%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     物品逻辑处理
%%% @end
%%%-------------------------------------------------------------------
-module(goods_logic).
-author("liushl").

-compile(export_all).
-include("common.hrl").
-include("def_goods.hrl").
-include("sql_goods.hrl").
-include("goods.hrl").
-include("server.hrl").
-include("drop.hrl").
-include("attr.hrl").
-include("figure.hrl").
-include("predefine.hrl").
-include("language.hrl").
-include("errcode.hrl").
-include("def_fun.hrl").

-export([

]).
%%-------------------------------------------------------------------------------------
%% @doc 【装备类】将某件物品穿到身上, 穿戴绑定， 如果身上对应位置已有物品 则替换
%% FromGoodsInfo::#goods{} 需要穿戴的物品
%% FromToLocation :: 需要穿戴的装备背包位置
%% ToToLocation :: 装备位置
%% ToCell :: 装备格子
%% OldExistGoods::#goods{}|none 穿戴位置已经存在的物品
%%----------------------------------------------------------
put_goods_on(FromGoodsInfo, FromToLocation, ToToLocation, ToCell, OldExistGoods) ->
    GoodsStatus = lib_goods_do:get_goods_status(),
    put_goods_on(GoodsStatus, FromGoodsInfo, FromToLocation, ToToLocation, ToCell, OldExistGoods).
put_goods_on(GoodsStatus, FromGoodsInfo, FromToLocation, ToToLocation, ToCell, OldExistGoods)->
    F = fun() ->
        ok = lib_goods_dict:start_dict(),
        [_NewGoodsInfo, NewStatus] = goods_logic:change_goods_location_bind(FromGoodsInfo, ToToLocation, ToCell, ?BIND, GoodsStatus),
        case is_record(OldExistGoods, goods) of
            true  when OldExistGoods#goods.num =:= 0 ->
                {ok, NewStatus2} = goods_del:delete_goods_list(NewStatus, [{OldExistGoods#goods{num=1}, 1}]);
            true  ->
                [_, NewStatus2] = goods_logic:change_goods_location(OldExistGoods, FromToLocation, 0, NewStatus);
            false ->
                NewStatus2 = NewStatus
        end,
        {GoodsMaps, UpGoods} = lib_goods_dict:handle_dict_and_notify(NewStatus2#goods_status.dict),
        {ok, NewStatus2#goods_status{dict = GoodsMaps}, UpGoods}
        end,
    case goods_transaction:transaction(F) of
        {ok, NewGoodsStatus, ReturnGoods} ->
            lib_goods_do:set_goods_status(NewGoodsStatus),
            lib_goods_api:notify_client(GoodsStatus#goods_status.player_id, ReturnGoods, equipment),
            {ok, ReturnGoods};
        Error ->
            ?ERR("put_goods_on error:~p", [Error]),
            false
    end.

%%-------------------------------------------------------------------------------------
%% @doc 【装备吞噬强化类】 消耗指定物品强化物品
%% GoodsInfo :: #goods{}
%% CostGoods :: [{#goods{}, num}]
upgrade_goods(Player, GoodsInfo, CostGoods, Type) ->
    GoodsStatus = lib_goods_do:get_goods_status(),
    F = fun() ->
        ok = lib_goods_dict:start_dict(),
        [_NewGoodsInfo, GoodsStatus1] =
            case is_record(GoodsInfo, goods) of
                true  -> goods_logic:change_goods_extra(GoodsInfo, GoodsStatus);
                false -> [GoodsInfo, GoodsStatus]
            end,
        {ok, GoodsStatus2} = case CostGoods =/= [] of
                                 true -> goods_del:delete_goods_list(GoodsStatus1, CostGoods);
                                 false ->
                                     {ok, GoodsStatus1}
                             end,
        {Dict, GoodsL} =
            lib_goods_dict:handle_dict_and_notify(GoodsStatus2#goods_status.dict),
        GoodsStatus3 = GoodsStatus2#goods_status{dict = Dict},
        {ok, GoodsStatus3, GoodsL}
        end,
    case goods_transaction:transaction(F) of
        {ok, NewGoodsStatus, ReturnGoods} ->
            lib_goods_do:set_goods_status(NewGoodsStatus),
            lib_goods_api:notify_client(Player, ReturnGoods, equipment_star),
            NowTime = utime:unixtime(),
            ConsumeTypeId = data_goods:get_consume_type(Type),
            LogList = [[NowTime, ConsumeTypeId, Player#player_status.id, Id, GoodsTypeId, DeleteNum]
                || {#goods{id = Id, goods_id = GoodsTypeId}, DeleteNum} <- CostGoods],
            lib_log_api:log_throw(LogList),
            {ok, ReturnGoods};
        Error ->
            ?ERR("upgrade_goods error:~p", [{Player#player_status.id, Error}]),
            false
    end.
%%-------------------------------------------------------------------------------------
%% @doc 【装备类】将穿在身上物品卸到指定背包
%% GoodsInfo::#goods{} 需要卸的物品
%% ToLocation :: 目标背包
%%----------------------------------------------------------
take_goods_off(GoodsInfo, ToLocation)->
    GoodsStatus = lib_goods_do:get_goods_status(),
    take_goods_off(GoodsStatus, GoodsInfo, ToLocation).
take_goods_off(GoodsStatus, GoodsInfo, ToLocation)->
    F = fun() ->
        ok = lib_goods_dict:start_dict(),
        [_NewGoodsInfo, NewStatus] = goods_logic:change_goods_location(GoodsInfo, ToLocation, 0, GoodsStatus),
        {GoodsMaps, UpGoods} = lib_goods_dict:handle_dict_and_notify(NewStatus#goods_status.dict),
        {ok, NewStatus#goods_status{dict = GoodsMaps}, UpGoods}
        end,
    case goods_transaction:transaction(F) of
        {ok, NewGoodsStatus, ReturnGoods} ->
            lib_goods_do:set_goods_status(NewGoodsStatus),
            lib_goods_api:notify_client(GoodsStatus#goods_status.player_id, ReturnGoods, equipment),
            {ok, ReturnGoods};
        Error ->
            ?ERR("take_goods_off error:~p", [Error]),
            false
    end.

%%-------------------------------------------------------------------------------------
%% @doc 更新物品类型id，直接变成另外一个物品
%% GoodsInfoList :: [#goods{}]
%% CostGoods :: [{#goods{}, num}]
%%----------------------------------------------------------
update_goods_info(GoodsInfoList, CostGoods, Type)->
    GoodsStatus = lib_goods_do:get_goods_status(),
    F = fun() ->
        ok = lib_goods_dict:start_dict(),
        F0 = fun(GoodsInfo, GoodsStatusTemp) ->
            NewGoodsStatusTemp = goods_logic:change_goods_info(GoodsInfo, GoodsStatusTemp),
            {ok, NewGoodsStatusTemp}
             end,
        {ok, GoodsStatus1} = lib_goods_check:list_handle(F0, GoodsStatus, GoodsInfoList),
        {ok, GoodsStatus2} = case CostGoods =/= [] of
                                 true -> goods_del:delete_goods_list(GoodsStatus1, CostGoods);
                                 false ->
                                     {ok, GoodsStatus1}
                             end,
        {GoodsMaps, UpGoods} = lib_goods_dict:handle_dict_and_notify(GoodsStatus2#goods_status.dict),
        {ok, GoodsStatus2#goods_status{dict=GoodsMaps}, UpGoods}
        end,
    case goods_transaction:transaction(F) of
        {ok, NewGoodsStatus, ReturnGoods} ->
            lib_goods_do:set_goods_status(NewGoodsStatus),
            lib_goods_api:notify_client(GoodsStatus#goods_status.player_id, ReturnGoods, goods_compose),
            NowTime = utime:unixtime(),
            ConsumeTypeId = data_goods:get_consume_type(Type),
            LogList = [[NowTime, ConsumeTypeId, GoodsStatus#goods_status.player_id, Id, GoodsTypeId, DeleteNum]
                || {#goods{id = Id, goods_id = GoodsTypeId}, DeleteNum} <- CostGoods],
            lib_log_api:log_throw(LogList),
            {ok, ReturnGoods};
        Error ->
            ?ERR("update_goods_info error:~p", [Error]),
            false
    end.

%%-------------------------------------------------------------------------------------
%% @doc 更新物品的额外数据
%% GoodsInfoList :: [#goods{}]
%%----------------------------------------------------------
update_goods_info_extra(GoodsInfoList)->
    GoodsStatus = lib_goods_do:get_goods_status(),
    F = fun() ->
        ok = lib_goods_dict:start_dict(),
        F0 = fun(GoodsInfo, GoodsStatusTemp) ->
            [_NewGoodsInfo, GoodsStatusTemp] = goods_logic:change_goods_extra(GoodsInfo, GoodsStatusTemp),
            {ok, GoodsStatusTemp}
            end,
        {ok, NewStatus} = lib_goods_check:list_handle(F0, GoodsStatus, GoodsInfoList),
        {GoodsMaps, UpGoods} = lib_goods_dict:handle_dict_and_notify(NewStatus#goods_status.dict),
        {ok,NewStatus#goods_status{dict=GoodsMaps}, UpGoods}
        end,
    case goods_transaction:transaction(F) of
        {ok, NewGoodsStatus, ReturnGoods} ->
            lib_goods_do:set_goods_status(NewGoodsStatus),
            lib_goods_api:notify_client(GoodsStatus#goods_status.player_id, ReturnGoods, equipment_update),
            {ok, ReturnGoods};
        Error ->
            ?ERR("update_goods_info_extra error:~p", [Error]),
            false
    end.

%%-------------------------------------------------------------------------------------
%% @doc 新增物品
%% -spec add_goods(GoodsInfo, GoodsStatus) -> [NewGoodsInfo, NewGoodsStatus]
%% GoodsInfo | NewGoodsInfo     :: #goods{}         物品记录
%% GoodsStatus | NewGoodsStatus :: #goods_status{}  新的物品进程状态
%% @end
%% ------------------------------------------------------------------------------------
add_goods(GoodsInfo, GoodsStatus) ->
    NewGoodsInfo = lib_goods_util:add_goods(GoodsInfo),
    Dict = lib_goods_dict:append_dict({add, goods, NewGoodsInfo}, GoodsStatus#goods_status.dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict},
    [NewGoodsInfo, NewStatus].

%%-------------------------------------------------------------------------------------
%% @doc 更改物品数量
%% -spec change_goods_num(GoodsInfo, Num, GoodsStatus) -> [NewGoodsInfo, NewGoodsStatus]
%% GoodsInfo | NewGoodsInfo     :: #goods{}         物品记录
%% Num                          :: integer()        新数量
%% GoodsStatus | NewGoodsStatus :: #goods_status{}  新的物品进程状态
%% @end
%% ------------------------------------------------------------------------------------
change_goods_num(GoodsInfo, Num, GoodsStatus) ->
    NewGoodsInfo = lib_goods_util:change_goods_num(GoodsInfo, Num),
    Dict = lib_goods_dict:append_dict({add, goods, NewGoodsInfo}, GoodsStatus#goods_status.dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict},
    [NewGoodsInfo, NewStatus].

%%-------------------------------------------------------------------------------------
%% @doc 删除物品
-spec delete_goods(GoodsInfo, GoodsStatus) -> NewGoodsStatus when
        GoodsInfo      :: #goods{},         %%物品记录
      GoodsStatus  :: #goods_status{},
    NewGoodsStatus :: #goods_status{}.   %%新的物品进程状态
%% @end
%% ------------------------------------------------------------------------------------
delete_goods(GoodsInfo, GoodsStatus) ->
    lib_goods_util:delete_goods(GoodsInfo#goods.id, GoodsInfo#goods.player_id),
    Dict = lib_goods_dict:append_dict({del, goods, GoodsInfo#goods{num = 0}}, GoodsStatus#goods_status.dict),
    NewGoodsStatus = GoodsStatus#goods_status{dict = Dict},
    NewGoodsStatus.

%%-------------------------------------------------------------------------------------
%% @doc 更改物品背包位置
%%----------------------------------------------------------
change_goods_location(GoodsInfo, Location, Cell, GoodsStatus) ->
    NewGoodsInfo = lib_goods_util:change_goods_location_cell(GoodsInfo, Location, Cell),
    Dict = lib_goods_dict:append_dict({del, goods, GoodsInfo#goods{num = 0}}, GoodsStatus#goods_status.dict),
    Dict1 = lib_goods_dict:append_dict({add, goods, NewGoodsInfo}, Dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict1},
    [NewGoodsInfo, NewStatus].

%%-------------------------------------------------------------------------------------
%% @doc 更改物品背包位置和绑定属性
%%----------------------------------------------------------
change_goods_location_bind(GoodsInfo, Location, Cell, Bind, GoodsStatus) ->
    NewGoodsInfo = GoodsInfo#goods{location = Location, cell = Cell, bind = Bind},
    lib_goods_util:change_goods_location_cell_bind(NewGoodsInfo),
    Dict = lib_goods_dict:append_dict({del, goods, GoodsInfo#goods{num = 0}}, GoodsStatus#goods_status.dict),
    Dict1 = lib_goods_dict:append_dict({add, goods, NewGoodsInfo}, Dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict1},
    [NewGoodsInfo, NewStatus].

%%-------------------------------------------------------------------------------------
%% @doc 更改物品额外数据
%% ------------------------------------------------------------------------------------
change_goods_extra(GoodsInfo, GoodsStatus) ->
    lib_goods_util:change_goods_extra(GoodsInfo#goods.id, GoodsInfo#goods.player_id, GoodsInfo#goods.extra_data),
    Dict = lib_goods_dict:append_dict({add, goods, GoodsInfo}, GoodsStatus#goods_status.dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict},
    [GoodsInfo, NewStatus].

%%-------------------------------------------------------------------------------------
%% @doc 更改物品类型id
%% ------------------------------------------------------------------------------------
change_goods_info(GoodsInfo, GoodsStatus) ->
    lib_goods_util:update_goods_info(GoodsInfo),
    Dict = lib_goods_dict:append_dict({add, goods, GoodsInfo}, GoodsStatus#goods_status.dict),
    NewStatus = GoodsStatus#goods_status{dict = Dict},
    NewStatus.

%%-------------------------------------------------------------------------------------
%% @doc 刷新前端虚拟货币
%%----------------------------------------------
send_update_currency(PS, CurrencyId) ->
    Value = maps:get(CurrencyId, PS#player_status.currency_map, 0),
    {ok, BinData} = pt_150:write(15008, [CurrencyId, Value]),
    lib_server_send:send_to_sid(PS#player_status.sid, BinData).