%% ---------------------------------------------------------------------------
%% @doc mod_scene_object_create
%% @author ming_up@foxmail.com
%% @since  2017-02-06
%% @deprecated 场景对象生成
%% ---------------------------------------------------------------------------
-module(mod_scene_object_create).
-behaviour(gen_server).
-export([
         start_link/0,
         create_object/10,
         create_object_cast/10,
         insert_object/2,
         create_more_cast/5,
         get_new_id/0
        ]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-include("scene.hrl").
-include("battle.hrl").
-include("common.hrl").

%% @spec create_object(ObjectType, ConfigId, Scene, X, Y, Angle, CopyId, BroadCast, Arg) -> AutoId
%% 同步生成怪物
%% @param ObjectType: ?BATTLE_SIGN_MON | ?BATTLE_SIGN_PARTNER...
%% @param ConfigId 配置ID
%% @param Scene 场景ID
%% @param ScenePoolId 场景进程id
%% @param X 坐标
%% @param X 坐标
%% @param Angle 怪物出生时的站位角度
%% @param CopyId 房间号ID 为0时，普通房间，非0值切换房间。值相同，在同一个房间。
%% @param BroadCast:生成的时候是否广播(0:不广播; 1:广播)
%% @param Arg:可变参数列表[Tuple1, Tuple2...]
%%             Tuple1 = {auto_lv, V} | {group, V} | {cruise_info, V} |
%%                      {owner_id, OwnerId} | {mon_name, MonName} |  {color, MonColor} | {skip, V} |
%%                      {crack, V}
%%@return AutoId 怪物自增ID，每个怪物唯一
%% @end
create_object(ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, CopyId, BroadCast, Arg) ->
    gen_server:call(?MODULE, {create, [ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, CopyId, BroadCast, Arg]}).

%% @spec create_object_cast(ObjectType, ConfigId, Scene, X, Y, Angle, CopyId, BroadCast, Arg) -> ok.
%% 异步创建怪物
%% @end
create_object_cast(ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, CopyId, BroadCast, Arg) ->
    gen_server:cast(?MODULE, {create, [ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, CopyId, BroadCast, Arg]}),
    ok.

create_more_cast(Scene, ScenePoolId, CopyId, Broadcast, List) ->
    gen_server:cast(?MODULE, {create_more, [Scene, ScenePoolId, CopyId, Broadcast, List]}).

%% 插入一只怪
insert_object(State, Args) ->
    gen_server:cast(?MODULE, {insert_object, State, Args}).

%% 获取一个场景对象的唯一id
get_new_id() ->
    gen_server:call(?MODULE, get_new_id).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    process_flag(trap_exit, true),
    State = #object_create_state{auto_id = 1001},
    {ok, State}.

%% 同步创建
handle_call({create, Args} , _FROM, State) ->
    AutoId = State#object_create_state.auto_id,
    create_a_scene_object(AutoId, Args),
    NewState = State#object_create_state{auto_id = AutoId + 1, cnt = State#object_create_state.cnt + 1},
    {reply, AutoId, NewState};

%% 获取一个新的唯一id
handle_call(get_new_id, _FROM, State) ->
    {reply, State#object_create_state.auto_id, State#object_create_state{auto_id = State#object_create_state.auto_id + 1}};

handle_call(_R , _FROM, State) ->
    {reply, State, State}.

%% 异步创建
handle_cast({create, Args}, State) ->
    create_a_scene_object(State#object_create_state.auto_id, Args),
    NewState = State#object_create_state{auto_id = State#object_create_state.auto_id + 1, cnt = State#object_create_state.cnt + 1},
    {noreply, NewState};
handle_cast({create_more, [Scene, ScenePoolId, CopyId, BroadCast, List]}, #object_create_state{auto_id = OldAutoId} = State) ->
    ArgsList = [[ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, CopyId, BroadCast, Arg] || [ObjectType, ConfigId, X, Y, Angle, Arg] <- List],
    NewAutoId
    = try
        create_scene_objects(ArgsList, State#object_create_state.auto_id)
    catch
        _:_ ->
            State#object_create_state.auto_id + length(ArgsList)
    end,
    NewState = State#object_create_state{auto_id = NewAutoId, cnt = State#object_create_state.cnt + max(NewAutoId - OldAutoId, 0)},
    {noreply, NewState};
%% 插入一只怪
handle_cast({insert_object, MonState, Args}, State) ->
    SceneObject = MonState#ob_act.object,
    mon_mgr:insert_mon(MonState#ob_act{object = SceneObject#scene_object{id = State#object_create_state.auto_id}}, Args),
    NewState = State#object_create_state{auto_id = State#object_create_state.auto_id + 1, cnt = State#object_create_state.cnt + 1},
    {noreply, NewState};
handle_cast(_R , State) ->
    {noreply, State}.

handle_info({'EXIT', _From, normal}, State)->
    NewState = State#object_create_state{cnt = max(State#object_create_state.cnt-1, 0)},
    {noreply, NewState};
handle_info({'EXIT', From, Reason}, State)->
    %% PS: 改版后，实际上怪物进程是未链接到此进程的，所以可能是其他链接进程消息
    ?ERR("receive EXIT msg (pid=~p). reason: ~n~p~n", [From, Reason]),
    NewState = State#object_create_state{cnt = max(State#object_create_state.cnt - 1, 0)},
    {noreply, NewState};

handle_info(_Reason, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

create_a_scene_object(AutoId, [ObjectType, ConfigId, Scene, ScenePoolId, X, Y, Angle, Sid, BroadCast, Arg]) ->
    case ObjectType of
        ?BATTLE_SIGN_MON ->
            CreateMonInfo = [AutoId, ConfigId, Scene, ScenePoolId, X, Y, Angle, Sid, BroadCast, Arg],
            mon_mgr:create_mon(Scene, ScenePoolId, CreateMonInfo);
        ?BATTLE_SIGN_DUMMY ->
            CreateDummyInfo = [AutoId, ConfigId, Scene, ScenePoolId, X, Y, Angle, Sid, BroadCast, Arg],
            mon_mgr:create_dummy(Scene, ScenePoolId, CreateDummyInfo);
        _ -> skip
    end.

create_scene_objects([Args|T], AutoId) ->
    create_a_scene_object(AutoId, Args),
    create_scene_objects(T, AutoId + 1);

create_scene_objects([], AutoId) -> AutoId.

