%%%--------------------------------------
%%% @Module  : lib_fashion
%%% @Author  : huyihao
%%% @Created : 2017.10.26
%%% @Description:  时装
%%%--------------------------------------

-module (lib_fashion).

-export([
    fashion_login/2
    ,get_equip_fashion_list/1
    ,get_equip_fashion_list/2

    ,get_fashion_total_star/1
    ,get_fashion_active_num/1
    ,get_rand_fashion_model_list/1
    ,get_fashion_combat_power/1
    
    ,active_fashion_by_goods/2
    ,batch_active_fashion/2
    ,role_active_fashion_by_goods/2
    ,role_active_fashion_by_goods_do/6
    ,use_fashion_color_goods/3

    ,is_trial_fashion_goods/1
    ,is_trial_fashion/1
    ,check_fashion_goods/1
    
    ,handle_event/2
    ,calc_power/3
    ,count_fashion_attr/1
    ,count_fashion_suit_attr/1
    ,get_fashion_power/1
    
    ,fashion_time_out/2
    
    ,get_fashion_pos/2
    ,get_fashion_info/3

    ,pack_fashion_info/1
    ,fashion_color_star_up/3
    ,fashion_color_equip/2
    ,fashion_color_unequip/2

    ,get_role_fashion_pos_info/2
    ,db_update_fashion_suit/4
    ,calc_active_fashions/1

    %% 脱下时装需要导出的接口
    ,update_fashion_info/4
    ,db_update_fashion_info/2
    ,db_update_fashion_pos/2
    ,update_role_scene_fashion_info/4

    ,gm_active_all_fashion/1
    ]).

-include("fashion.hrl").
-include("server.hrl").
-include("def_event.hrl").
-include("def_goods.hrl").
-include("rec_event.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
-include("figure.hrl").
-include("predefine.hrl").
-include("goods.hrl").
-include("common.hrl").
-include("def_fun.hrl").

fashion_login(RoleId, Now) ->
    FashionPosIdList = data_fashion:get_pos_id_list(),
    ReSql = io_lib:format(?SELECT_FASHION_POS_SQL, [RoleId]),
    PosSqlList = db:get_all(ReSql),
    PosSqlTupleList = [list_to_tuple(Info)||Info <- PosSqlList],
    ReSql1 = io_lib:format(?SELECT_FASHION_INFO_SQL, [RoleId]),
    AllFashionSqlList = db:get_all(ReSql1),
    FashionPosList = get_fashion_pos_list(FashionPosIdList, PosSqlTupleList, AllFashionSqlList),
    SuitList = db:get_all(?SELECT_FAHION_SUIT, [RoleId]),
    NewSuitList = [{SuitId, util:bitstring_to_term(FashionSuitLBin), Acitve} || [SuitId, FashionSuitLBin, Acitve] <- SuitList],
    RoleFashion = #role_fashion{all_fashions = FashionPosList, suit_list = NewSuitList},
    %% 过滤过期时装
    #role_fashion{all_fashions = AllFashions, suit_list = AllSuitList} = RoleFashion1 = filter_expire_fashion(RoleId, Now, RoleFashion),
    %% 汇总时装属性
    FashionAttr = count_fashion_attr(AllFashions),
    SuitAttr    = count_fashion_suit_attr(AllSuitList),
    FashionAttrs1 = lists:append(FashionAttr, SuitAttr),
    AttrAfterPartial = lib_player_attr:partial_attr_convert(FashionAttrs1),
    RoleFashion1#role_fashion{fashion_attr = AttrAfterPartial}.

%% 获取玩家穿戴时装列表
get_equip_fashion_list(RoleId, _Career) ->
    ReSql = io_lib:format(?SELECT_FASHION_POS_SQL, [RoleId]),
    case db:get_all(ReSql) of
        [] ->
            {[], []};
        PosSqlList ->
            F = fun(Info, {FashionModelList1, WearFashion}) ->
                [_RoleId, PosId, WearFashionId, WearColorId] = Info,
                FashionModelCon = data_fashion:get_fashion_color_con(WearFashionId, WearColorId),
                case FashionModelCon of
                    [] ->
                        {FashionModelList1, WearFashion};
                    _ ->
                        #fashion_color_con{color_logo = ModelId} = FashionModelCon,
                        {
                            [{PosId, ModelId, WearColorId}|FashionModelList1],
                            [{PosId, WearFashionId, WearColorId}|WearFashion]
                        }
                end
            end,
            lists:foldl(F, {[], []}, PosSqlList)
    end.

get_fashion_pos_list([], _PosList, _InfoList) ->
    [];
get_fashion_pos_list(PosIdList, PosList, InfoList) ->
    % NowTime = utime:unixtime(),
    F1 = fun(PosId, TempList) ->
        case lists:keyfind(PosId, 2, PosList) of
            {_, PosId, WearFashionId, WearColorId} ->
                FashionPos = #fashion_pos{
                    pos_id = PosId, wear_fashion_id = WearFashionId,
                    wear_color_id = WearColorId, fashion_list = []
                },
                [FashionPos | TempList];
            _ ->
                [#fashion_pos{pos_id = PosId} | TempList]
        end
    end,
    TempFashionPosList = lists:foldl(F1, [], PosIdList),
    F2 = fun(Info, TempList) ->
        [_RoleId, PosId, FashionId, ColorId, SColorList|_] = Info,
        case lists:keyfind(PosId, #fashion_pos.pos_id, TempList) of
            #fashion_pos{fashion_list = OldFashionList} = ResPos ->
                ColorList = util:bitstring_to_term(SColorList),
                FashionInfo = #fashion_info{
                    pos_id = PosId, fashion_id = FashionId, color_id = ColorId, color_list = ColorList
                },
                NewPos = ResPos#fashion_pos{fashion_list = [FashionInfo|OldFashionList]},
                lists:keyreplace(PosId, #fashion_pos.pos_id, TempList, NewPos);
            _ ->
               TempList
        end
    end,
    FashionPosList = lists:foldl(F2, TempFashionPosList, InfoList),
    FashionPosList.

%% 检查限时时装
handle_event(Player, #event_callback{type_id = ?EVENT_LOGIN_CAST}) ->
    #player_status{id = RoleId, role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions, suit_list = SuitList} = NewRoleFasion = filter_expire_fashion(RoleId, utime:unixtime(), RoleFashion),
    FashionAttr = count_fashion_attr(AllFashions),
    SuitAttr    = count_fashion_suit_attr(SuitList),
    FashionAttrs1 = lists:append(FashionAttr, SuitAttr),
    AttrAfterPartial = lib_player_attr:partial_attr_convert(FashionAttrs1),
    NewRoleFasion1 = NewRoleFasion#role_fashion{fashion_attr = AttrAfterPartial},
    NewPlayer = Player#player_status{role_fashion = NewRoleFasion1},
    NewPlayer1 = lib_player:count_player_attribute(NewPlayer, ?MOD_FASHION),
    NewPlayer2 = update_role_scene_fashion_info(NewPlayer1, 0, 0, 0),
    lib_player:send_attribute_change_notify(NewPlayer2, ?NOTIFY_ATTR),
    {ok, NewPlayer2}.

filter_expire_fashion(RoleId, Now, RoleFashion) ->
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    NewAllFashions = filter_expire_fashion_do(RoleId, Now, AllFashions, []),
    NewRoleFashion = RoleFashion#role_fashion{all_fashions = NewAllFashions},
    NewRoleFashion.

filter_expire_fashion_do(_, _, [], Acc) -> Acc;
filter_expire_fashion_do(RoleId, Now, [FashionPos|Rest], Acc) ->
    #fashion_pos{fashion_list = FashionList} = FashionPos,
    NewFashionList = 
    lists:foldl(fun(FashionInfo = #fashion_info{pos_id = PosId, fashion_id = FashionId, color_id = WearColorId, color_list = ColorList}, TempFashionList) ->
        %% 过滤限时时装
        {NewColorList, ExpireColorList} =
         lists:splitwith(fun({_ColorId, _StarLv, ExpireTime}) -> 
            ExpireTime > Now orelse ExpireTime == 0
        end, ColorList),
         WearExpireRet = lists:keymember(WearColorId, 1, ExpireColorList),
         case WearExpireRet of
            true -> NewWearColorId = 0;
            _    -> NewWearColorId = WearColorId
        end,
         NewFashionInfo = FashionInfo#fashion_info{color_id = NewWearColorId, color_list = NewColorList},
         %% 更新限时时装到ets
         [lib_player_record:role_func_check_update(RoleId, ?FUNC_TYPE_FASHION, {{FashionId, ColorIdX}, ExpireTimeX}) || {ColorIdX, _LvX, ExpireTimeX} <- NewColorList, ExpireTimeX =/= 0],
         [lib_player_record:role_func_check_delete_sub_id(RoleId, ?FUNC_TYPE_FASHION, {FashionId, ColorIdX1}) || {ColorIdX1, _LvX1, _ExpireTimeX1} <- ExpireColorList],
         %% 更新数据库限时时装
         if ExpireColorList == [] ->
                skip;
            true ->
                db_update_fashion_info(RoleId, NewFashionInfo)
        end,
        if WearExpireRet == false ->
                skip;
            true ->
                Sql = io_lib:format(?REPLACE_FASHION_POS_SQL, [RoleId, PosId, 0, 0]),
                db:execute(Sql)                
        end,
        [NewFashionInfo|TempFashionList]
    end, [], FashionList),
    NewFashionPos = FashionPos#fashion_pos{fashion_list = NewFashionList},
    filter_expire_fashion_do(RoleId, Now, Rest, [NewFashionPos|Acc]).

%% 更新数据库
db_update_fashion_info(RoleId, FashionInfo) ->
    #fashion_info{
        pos_id      = PosId,
        fashion_id  = FashionId,
        color_id    = ColorId,
        color_list  = ColorList
    } = FashionInfo,
    ColorBin = util:term_to_bitstring(ColorList),
    db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, ColorId, ColorBin]),
    ok.

db_update_fashion_pos(RoleId, FashonPos) ->
    #fashion_pos{
        pos_id              = PosId,
        wear_fashion_id     = FashionId, 
        wear_color_id       = ColorId
    } = FashonPos,
    db:execute(?REPLACE_FASHION_POS_SQL, [RoleId, PosId,FashionId, ColorId]),
    ok.

db_update_fashion_suit(RoleId, SuitId, SuitFashionL, Acitve) ->
    db:execute(?REPLACE_INTO_FASHION_SUIT, [RoleId, SuitId, util:term_to_bitstring(SuitFashionL), Acitve]),
    ok.

%% 获取时装总属性加成
count_fashion_attr(Fashions) ->
    count_fashion_attr(Fashions, true).

%% Fashion 服装信息列表
%% CalcExpire 是否计算限时时装属性 true|false
count_fashion_attr(FashionPosList, CalcExpire) ->
    F = fun(#fashion_pos{fashion_list = FashionList}, TempList) ->
        F1 = fun(#fashion_info{fashion_id = FashionId, color_list = ColorList}, TempList1) ->
            ColorAttrs = calc_color_attr(FashionId, ColorList, CalcExpire),
            lib_player_attr:add_attr(list, [ColorAttrs, TempList1])                
        end,
        LastList = lists:foldl(F1, [], FashionList),
        lib_player_attr:add_attr(list, [LastList, TempList])
    end,
    TempAttrList = lists:foldl(F, [], FashionPosList),
    LastAttr = lib_player_attr:partial_attr_convert(TempAttrList),
    LastAttr.

count_fashion_suit_attr(SuitList) ->
    AttrList = lists:foldl(fun({SuitId, FashionL, Acitve}, AccList) ->
        Len = length(FashionL),
        case data_fashion:get_fashion_suit(SuitId) of
            #base_fashion_suit{fashion_id = NeedFashionL, attr = SuitAttr} ->
                NeedLen = length(NeedFashionL),
                if Len >= NeedLen andalso Acitve == 1 ->
                        lib_player_attr:add_attr(list, [SuitAttr, AccList]);
                    true ->
                        AccList
                end;
            _ ->
                AccList
        end 
    end, [], SuitList),
    NewAttrList = lib_player_attr:partial_attr_convert(AttrList),
    NewAttrList.

%% 单件时装的颜色列表属性
calc_color_attr(FashionId, ColorList, CalcExpire) ->
    lists:foldl(fun({ColorId, StarLv, ExpireTime}, TempAttrs) ->
        CheckResult = if CalcExpire -> true;
            true -> ExpireTime == 0
        end,
        if
            CheckResult ->
                case data_fashion:get_fashion_con(FashionId, ColorId, StarLv) of
                    #base_fashion_star_up{attr_list = ColorAttr} ->
                        lib_player_attr:add_attr(list, [ColorAttr, TempAttrs]);
                    _ ->
                        TempAttrs
                end;
            true ->
                TempAttrs 
        end
    end, [], ColorList).

%% 回调计算战力
calc_power(Player, AttrPower, BaseAttr) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = PositionList, fashion_attr = FashionAttrList, suit_list = SuitList} = RoleFashion,
    NewPositionList = lists:foldl(fun(TmpFashionPos = #fashion_pos{fashion_list = FashionList}, Acc) ->
        NewFashionList = calc_fashion_power(FashionList, AttrPower, BaseAttr),
        [TmpFashionPos#fashion_pos{fashion_list = NewFashionList}|Acc]
     end, [], PositionList),
    %% 不包括限时的属性
    FashionAttrList1    = count_fashion_attr(NewPositionList, false),
    SuitAttr            = count_fashion_suit_attr(SuitList),
    AttrAfterPartial    = lib_player_attr:partial_attr_convert(FashionAttrList1 ++ SuitAttr),
    FashionAttr1        = attr_conv:to_attr_record(AttrAfterPartial),
    %% 包括限时的战力
    FashionAttr         = attr_conv:to_attr_record(FashionAttrList),
    FashionCombatPower  = lib_player_attr:calc_attr_power_partial(AttrPower, BaseAttr, FashionAttr),
    %% 不包括限时的战力
    FashionCombatPower1 = lib_player_attr:calc_attr_power_partial(AttrPower, BaseAttr, FashionAttr1),
    NewRoleFashion = RoleFashion#role_fashion{
        all_fashions = NewPositionList, 
        power = FashionCombatPower, 
        power1 = FashionCombatPower1
    },
    NewPlayer = Player#player_status{role_fashion = NewRoleFashion},
    lib_common_rank_api:refresh_rank_by_fashion(NewPlayer),
    {NewPlayer, 0}.

%% 计算单件时装战力
calc_fashion_power(FashionList, AttrPower, BaseAttr) ->
    lists:foldl(fun(Fashion = #fashion_info{fashion_id = FashionId, color_list = ColorList}, Acc) ->
            ColorAttrList = calc_color_attr(FashionId, ColorList, true),
            ColorAttrs = attr_conv:to_attr_record(ColorAttrList),
            Power = lib_player_attr:calc_attr_power_partial(AttrPower, BaseAttr, ColorAttrs),
            [Fashion#fashion_info{power = Power}|Acc]
    end, [], FashionList).

%% 获得玩家的时装战力
get_fashion_power(Player) ->
    case Player#player_status.role_fashion of
        #role_fashion{power1 = Power} -> Power;
        _ -> 0
    end.

pack_fashion_info(PosList) ->
    F = fun(FashionPos, SendList1) ->
        #fashion_pos{
            pos_id = PosId, wear_color_id = WearColorId,
             wear_fashion_id = WearFashionId, fashion_list = FashionList
        } = FashionPos,
        F2 = fun(FashionInfo, TempList) ->
            #fashion_info{
                fashion_id = FashionId, color_list = ActiveColorList, power = Power
            } = FashionInfo,
            [{FashionId, ActiveColorList, Power} | TempList]
        end,
        FashionSendList = lists:foldl(F2, [], FashionList),
        SendInfo = {PosId, WearFashionId, WearColorId, FashionSendList},
        [SendInfo|SendList1]
    end,
    SendList = lists:foldl(F, [], PosList),
    SendList.

%% 时装颜色基础激活升星操作
fashion_color_star_up(OperateType, Player, [PosId, FashionId, ColorId, CostList]) ->
    #player_status{id = RoleId, sid = Sid, role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions, suit_list = SuitList, fashion_attr = OldAttrs} = RoleFashion,
    {NewAllFashions, NewSuitList}  = fashion_color_star_up_do(RoleId, OperateType, AllFashions, SuitList, [PosId, FashionId, ColorId, CostList]),
    FashionAttrs    = count_fashion_attr(NewAllFashions),
    SuitAttr        = count_fashion_suit_attr(NewSuitList),
    FashionAttrs1   = lists:append(FashionAttrs, SuitAttr),
    FashionAttrs2   = lib_player_attr:partial_attr_convert(FashionAttrs1),
    RoleId == 4294967524 andalso ?ERR("old ~p ~n new ~p", [OldAttrs, FashionAttrs2]),
    NewRoleFashion  = RoleFashion#role_fashion{all_fashions = NewAllFashions, suit_list = NewSuitList, fashion_attr = FashionAttrs2},
    NewPlayer   = Player#player_status{role_fashion = NewRoleFashion},
    NewPlayer1  = lib_player:count_player_attribute(NewPlayer, ?MOD_FASHION, fashion_color_star_up),
    NewPlayer2 = lib_workroom:calc_each_suit_own_num(NewPlayer1, NewAllFashions),
    NewPlayer3 = lib_workroom:calc_each_suit_sum_star(NewPlayer2, NewAllFashions),
    lib_player:send_attribute_change_notify(NewPlayer3, ?NOTIFY_ATTR),
    case OperateType of
        {_, OldStar} -> NewStar = OldStar+1;
        _  -> NewStar = 0, OldStar = 0
    end,
    {ok, BinData} = pt_413:write(41306, [?SUCCESS, PosId, FashionId, NewStar, 0]),
    lib_server_send:send_to_sid(Sid, BinData),
    case CostList of
        [{_, CostGoodId, CostNum}|_] -> ok;
        _ -> CostGoodId = 0, CostNum = 0
    end,
    %% 激活触发风采值统计
    case OperateType of
        {_, _OldStar} ->
            ta_agent_fire:fashion_up(NewPlayer3, [PosId, FashionId, ColorId, 2, CostGoodId, CostNum, OldStar, NewStar]),
            NewPlayer4 = NewPlayer3;
        _ ->
            {AllColorList, TempNum, NotOpenNum} = calc_active_fashions(NewAllFashions),
            handle_achievement(NewPlayer3, AllColorList, TempNum),
            ta_agent_fire:fashion_up(NewPlayer3, [PosId, FashionId, ColorId, 1, CostGoodId, CostNum, OldStar, NewStar]),
            {ok, NewPlayer4} = lib_wardrobe_active:active_fashion(NewPlayer3, AllColorList, NotOpenNum, CostGoodId)
    end,
    {ok, NewPlayer4}.

handle_achievement(Player, AllColorList, TempNum) ->
    F = fun({_, Num}, TSumNum) ->
        Num + TSumNum
    end,
    SumNum = lists:foldl(F, 0, AllColorList),
    lib_achievement_api:active_fashion_event(Player, SumNum + TempNum),
    ok.

%% 穿戴时装
fashion_color_equip(Player, [PosId, FashionId, ColorId]) ->
    #player_status{id = RoleId, sid = Sid, role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    NewFashionInfo = FashionInfo#fashion_info{color_id = ColorId},
    NewFashionPos = FashionPos#fashion_pos{wear_fashion_id = FashionId, wear_color_id = ColorId},
    db_update_fashion_info(RoleId, NewFashionInfo),
    db_update_fashion_pos(RoleId, NewFashionPos),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, NewFashionPos, AllFashions),
    NewRoleFashion = RoleFashion#role_fashion{all_fashions = NewAllFashions},
    NewPlayer = Player#player_status{role_fashion = NewRoleFashion},
    %% 更新场景玩家时装
    NewPlayer1 = update_role_scene_fashion_info(NewPlayer, PosId, FashionId, ColorId),
    lib_server_send:send_to_sid(Sid, pt_413, 41302, [?SUCCESS, PosId, FashionId, ColorId]),
    %% 卸下其他外观
    NewPlayer2 =
    case FashionId >= 0 andalso ColorId >= 0 of
        true -> lib_role_foster:put_off_other_appearance(NewPlayer1, PosId, 1, {FashionId, ColorId});
        _ -> NewPlayer1
    end,

    {ok, NewPlayer2}.

%% 卸下时装
fashion_color_unequip(Player, [PosId, FashionId]) ->
    #player_status{id = RoleId, sid = Sid, role_fashion = RoleFashion
    } = Player,
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    NewFashionInfo = FashionInfo#fashion_info{color_id = 0},
    NewFashionPos = FashionPos#fashion_pos{wear_fashion_id = 0, wear_color_id = 0},
    db_update_fashion_info(RoleId, NewFashionInfo),
    db_update_fashion_pos(RoleId, NewFashionPos),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, NewFashionPos, AllFashions),
    NewRoleFashion = RoleFashion#role_fashion{all_fashions = NewAllFashions},
    NewPlayer = Player#player_status{role_fashion = NewRoleFashion},
    %% 更新场景玩家时装
    NewPlayer1 = update_role_scene_fashion_info(NewPlayer, PosId, FashionId, 0),
    lib_server_send:send_to_sid(Sid, pt_413, 41303, [?SUCCESS, PosId, FashionId]),
    {ok, NewPlayer1}.

update_role_scene_fashion_info(Player, PosId, FashionId, ColorId) ->
    #player_status{id = RoleId, figure = Figure, scene = SceneId, scene_pool_id = ScenePool, copy_id = CopyId, x = X, y = Y} = Player,
    {FigureModels, WearFashion} = get_equip_fashion_list(Player),
    NewFigure = Figure#figure{fashion_model = FigureModels, wear_fashion = WearFashion},
    NewPlayer = Player#player_status{figure = NewFigure},
    mod_scene_agent:update(NewPlayer, [{fashion_model, FigureModels},{wear_fashion, WearFashion}]),
    {ok, BinData} = pt_413:write(41311, [RoleId, FigureModels, PosId, FashionId, ColorId]),
    lib_server_send:send_to_area_scene(SceneId, ScenePool, CopyId,  X, Y, BinData),
    lib_role:update_role_show(RoleId, [{fashion_model, FigureModels},{wear_fashion, WearFashion}]),
    case NewFigure#figure.guild_id > 0 of
        true  -> mod_guild:update_guild_member_attr(RoleId, [{figure, NewFigure}]);
        false -> skip
    end,
    NewPlayer.

%% 永久激活
fashion_color_star_up_do(RoleId, ?COLOR_ACTIVE, AllFashions, SuitList, [PosId, FashionId, ColorId, CostList]) ->
    NewColor = {ColorId, 0, 0},
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    {SuitId, NewSuitFashionL, Acitve, NewSuitList} = update_suit_list(PosId, FashionId, SuitList),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    #fashion_info{color_list = ColorList} = FashionInfo,
    NewColorList = lists:keystore(ColorId, 1, ColorList, NewColor),
    NewFashionInfo  = FashionInfo#fashion_info{color_list = NewColorList},
    db_update_fashion_info(RoleId, NewFashionInfo),
    SuitList =/= NewSuitList andalso db_update_fashion_suit(RoleId, SuitId, NewSuitFashionL, Acitve),
    lib_log_api:log_fashion_activate(RoleId, PosId, FashionId, ColorId, 2, CostList, 0, 0),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, FashionPos, AllFashions),
    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_goods_api, after_send_reward, [CostList]),
    {NewAllFashions, NewSuitList};

%% 升星
fashion_color_star_up_do(RoleId, {?COLOR_STAR_UP, _}, AllFashions, SuitList, [PosId, FashionId, ColorId, CostList]) ->
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    #fashion_info{color_list = ColorList} = FashionInfo,
    {ColorId, OldStar, Time} = lists:keyfind(ColorId, 1, ColorList),
    NewColorList = lists:keystore(ColorId, 1, ColorList, {ColorId, OldStar+1, Time}),
    NewFashionInfo  = FashionInfo#fashion_info{color_list = NewColorList},
    db_update_fashion_info(RoleId, NewFashionInfo),
    lib_log_api:log_fashion_star(RoleId, PosId, FashionId, ColorId, 2, OldStar, OldStar+1, CostList),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, FashionPos, AllFashions),
    {NewAllFashions, SuitList};

%% 限时激活永久
fashion_color_star_up_do(RoleId, ?COLOR_SHORT_ACTIVE_EVER, AllFashions, SuitList, [PosId, FashionId, ColorId, CostList]) ->
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    {SuitId, NewSuitFashionL, Acitve, NewSuitList} = update_suit_list(PosId, FashionId, SuitList),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    #fashion_info{color_list = ColorList} = FashionInfo,
    {ColorId, _OldStar, Time} = lists:keyfind(ColorId, 1, ColorList),
    NewColorList = lists:keystore(ColorId, 1, ColorList, {ColorId, 0, 0}),
    NewFashionInfo  = FashionInfo#fashion_info{color_list = NewColorList},
    db_update_fashion_info(RoleId, NewFashionInfo),
    SuitList =/= NewSuitList andalso db_update_fashion_suit(RoleId, SuitId, NewSuitFashionL, Acitve),
    %% 更新ets
    lib_player_record:role_func_check_delete_sub_id(RoleId, ?FUNC_TYPE_FASHION, {FashionId, ColorId}),
    lib_log_api:log_fashion_activate(RoleId, PosId, FashionId, ColorId, 2, CostList, Time, 0),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, FashionPos, AllFashions),
    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_goods_api, after_send_reward, [CostList]),
    {NewAllFashions, SuitList};

%% 限时激活|限时叠加
fashion_color_star_up_do(RoleId, ?COLOR_SHORT_ACTIVE, AllFashions, SuitList, [PosId, FashionId, ColorId, ExpireTime, CostList]) ->
    #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, AllFashions),
    FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
    #fashion_info{color_list = ColorList} = FashionInfo,
    Now = utime:unixtime(),
    NewColorList =
    case lists:keyfind(ColorId, 1, ColorList) of
        {_, _OldStar, OldTime} when OldTime > Now ->
            NewEndTime = calc_expire_time(Now, ExpireTime),
            lists:keystore(ColorId, 1, ColorList, {ColorId, _OldStar, NewEndTime});
        _ ->
            OldTime = 0,
            NewEndTime = calc_expire_time(Now, ExpireTime),
            lists:keystore(ColorId, 1, ColorList, {ColorId, 0, NewEndTime})
    end,
    NewFashionInfo = FashionInfo#fashion_info{color_list = NewColorList},
    db_update_fashion_info(RoleId, NewFashionInfo),
    lib_player_record:role_func_check_update(RoleId, ?FUNC_TYPE_FASHION, {{FashionId, ColorId}, NewEndTime}),
    lib_log_api:log_fashion_activate(RoleId, PosId, FashionId, ColorId, 1, CostList, OldTime, NewEndTime),
    NewAllFashions = update_fashion_info(NewFashionInfo, FashionList, FashionPos, AllFashions),
    {NewAllFashions, SuitList};

fashion_color_star_up_do(_, _, AllFashions, SuitList, _) ->
    {AllFashions, SuitList}.

get_fashion_pos(PosId, AllFashions) ->
    case lists:keyfind(PosId, #fashion_pos.pos_id, AllFashions) of
        FashionPos = #fashion_pos{} -> FashionPos;
        _  -> #fashion_pos{pos_id = PosId}
    end.

get_fashion_suit(Pos, FashionId) ->
    SuitIds = data_fashion:get_all_suit(),
    case lists:foldl(fun(SuitIdX, Acc) -> 
        case data_fashion:get_fashion_suit(SuitIdX) of
            #base_fashion_suit{fashion_id = Fashions} ->
                case lists:member({Pos, FashionId}, Fashions) of
                    true ->
                        [SuitIdX|Acc];
                    _ ->
                        Acc
                end;
            _ ->
                Acc
        end
    end, [], SuitIds) of
        [SuitId|_] ->
            SuitId;
        _ ->
            0
    end.

update_suit_list(PosId, FashionId, SuitList) ->
    case get_fashion_suit(PosId, FashionId) of
        SuitId when is_integer(SuitId) andalso SuitId =/= 0 ->
            update_fashion_suit(PosId, FashionId, SuitId, SuitList);
        _ ->
            {0, [], 0, SuitList}
    end.

update_fashion_suit(PosId, FashionId, SuitId, SuitList) ->
    case lists:keyfind(SuitId, 1, SuitList) of
        {_, FashionL, Acitve} ->
            case lists:member({PosId, FashionId}, FashionL) of
                false ->
                    NewFashionL = [{PosId, FashionId}|FashionL],
                    NewSuitList = lists:keystore(SuitId, 1, SuitList, {SuitId, NewFashionL, Acitve}),
                    {SuitId, NewFashionL, Acitve, NewSuitList};
                _ ->
                    {0, FashionL, 0, SuitList}
            end;
        _ ->
            NewFashionL = [{PosId, FashionId}],
            NewSuitList = lists:keystore(SuitId, 1, SuitList, {SuitId, NewFashionL, 0}),
            {SuitId, NewFashionL, 0, NewSuitList}
    end.

get_fashion_info(PosId, FashionId, FashionList) ->
    case lists:keyfind(FashionId, #fashion_info.fashion_id, FashionList) of
        FashionInfo = #fashion_info{} -> FashionInfo;
        _  -> #fashion_info{pos_id = PosId, fashion_id = FashionId}
    end.

update_fashion_info(FashionInfo, FashionList, FashionPos, AllFashions) ->
    #fashion_info{fashion_id = FashionId} = FashionInfo,
    NewFashionList  = lists:keystore(FashionId, #fashion_info.fashion_id, FashionList, FashionInfo),
    NewFashionPos   = FashionPos#fashion_pos{fashion_list = NewFashionList},
    lists:keystore(NewFashionPos#fashion_pos.pos_id, #fashion_pos.pos_id, AllFashions, NewFashionPos).

%% 获取穿戴时装列表
get_equip_fashion_list(Player) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    F = fun(FashionPos, {FashionModelList1, WearFashion}) ->
        #fashion_pos{
            pos_id = PosId, wear_fashion_id = WearFashionId, wear_color_id = WearColorId
        } = FashionPos,
        FashionModelCon = data_fashion:get_fashion_color_con(WearFashionId, WearColorId),
        case FashionModelCon of
            [] ->
                {FashionModelList1, WearFashion};
            _ ->
                #fashion_color_con{color_logo = ModelId} = FashionModelCon,
                {
                    [{PosId, ModelId, WearColorId}|FashionModelList1],
                    [{PosId, WearFashionId, WearColorId}|WearFashion]
                }
        end
    end,
    lists:foldl(F, {[], []}, AllFashions).

%% 根据部位id获取穿着的时装颜色
-spec get_role_fashion_pos_info(Player, Pos) -> ReturnList when
    Player :: #player_status{},
    Pos :: ?CLOTH | ?HEAD_WEAR | ?BACK_DECOR | ?WEAPON | ?HAIR,
    ReturnList :: list(). %% [{ModelId, ColorId}]
get_role_fashion_pos_info(Player, Pos) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    case lists:keyfind(Pos, #fashion_pos.pos_id, AllFashions) of
        #fashion_pos{wear_fashion_id = FashionId, wear_color_id = ColorId} ->
            case data_fashion:get_fashion_color_con(FashionId, ColorId) of
                #fashion_color_con{color_logo = ModelId} ->
                    [{ModelId, ColorId}];
                _ ->
                    []
            end;
        _ ->
            []
    end.

%% 时装过期
fashion_time_out(Player, ExpireFashionIds) -> %?ERR("~p", [ExpireFashionIds]),
    #player_status{
        id = RoleId, role_fashion = RoleFashion
    } = Player,
    #role_fashion{all_fashions = PositionList, suit_list = SuitList} = RoleFashion,
    F = fun({FashionId, ColorId}, TempPosList) ->
        lib_player_record:role_func_check_delete_sub_id(RoleId, ?FUNC_TYPE_FASHION, {FashionId, ColorId}),
        [PosId|_] = data_fashion:get_fashion_pos_id(FashionId),
        case lists:keyfind(PosId, #fashion_pos.pos_id, TempPosList) of
            #fashion_pos{wear_fashion_id = WearFashionId, wear_color_id = WearColorId, fashion_list = FashionList} = FashionPos ->
                case lists:keyfind(FashionId, #fashion_info.fashion_id, FashionList) of
                    FashionInfo = #fashion_info{color_list = ColorList} ->
                        NewColorList = lists:keydelete(ColorId, 1, ColorList),
                        ColorBin = util:term_to_bitstring(NewColorList),
                        db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, ColorId, ColorBin]),
                        NewFashionInfo = FashionInfo#fashion_info{color_list = NewColorList},
                        NewFashionList = lists:keystore(FashionId, #fashion_info.fashion_id, FashionList, NewFashionInfo),
                        if
                            WearFashionId == FashionId andalso WearColorId == ColorId ->
                                ReSql1 = io_lib:format(?REPLACE_FASHION_POS_SQL, [RoleId, PosId, 0, 0]),
                                db:execute(ReSql1),
                                NewFashionPos = FashionPos#fashion_pos{wear_fashion_id = 0, wear_color_id = 0, fashion_list = NewFashionList};
                            true ->
                                NewFashionPos = FashionPos#fashion_pos{fashion_list = NewFashionList}
                        end,
                        lists:keystore(PosId, #fashion_pos.pos_id, TempPosList, NewFashionPos);
                    _ ->
                        TempPosList     
                end;
            _ ->
                TempPosList
        end
    end,
    %% 新的部位列表
    NewPositionList = lists:foldl(F, PositionList, ExpireFashionIds),
    %% 新的时装汇总属性
    FashionAttr     = count_fashion_attr(NewPositionList),
    SuitAttr        = count_fashion_suit_attr(SuitList),
    NewFashionAttr  = lib_player_attr:partial_attr_convert(lists:append(FashionAttr, SuitAttr)),
    NewRoleFashion  = RoleFashion#role_fashion{all_fashions = NewPositionList, fashion_attr = NewFashionAttr},
    NewPlayer0 = Player#player_status{role_fashion = NewRoleFashion},
    NewPlayer1 = lib_player:count_player_attribute(NewPlayer0, ?MOD_FASHION, fashion_timeout),
    lib_player:send_attribute_change_notify(NewPlayer1, ?NOTIFY_ATTR),
    pp_fashion:handle(41300, NewPlayer1, []),
    update_role_scene_fashion_info(NewPlayer1, 0, 0, 0),
    %beauty_contest_api:when_fashion_overdue(NewPlayer1, ExpireFashionIds),
    NewPlayer1.

%% 获取总星数
get_fashion_total_star(Player) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = FashionPosList} = RoleFashion,
    lists:foldl(fun(#fashion_pos{fashion_list = FashionList}, Acc) -> 
        lists:foldl(fun(#fashion_info{color_list = ColorList}, Acc1) -> 
            FashionStar = lists:sum([Star || {_ColorId, Star, Time} <- ColorList, Time == 0]),
            FashionStar + Acc1
        end, Acc, FashionList)
    end, 0, FashionPosList).

%% 获取总激活时装颜色数量
get_fashion_active_num(Player) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = FashionPosList} = RoleFashion,
    lists:foldl(fun(#fashion_pos{fashion_list = FashionList}, Acc) -> 
        lists:foldl(fun(#fashion_info{color_list = ColorList}, Acc1) -> 
            FashionColorNum = length(ColorList),
            FashionColorNum + Acc1
        end, Acc, FashionList)
    end, 0, FashionPosList).

%% 获取时装总站力
get_fashion_combat_power(Player) ->
    #player_status{role_fashion = RoleFashion} = Player,
    case RoleFashion of
        #role_fashion{power = FashionPower} ->
            FashionPower;
        _ ->
            0
    end.

%%根据职业随机获取时装
get_rand_fashion_model_list(Career) ->
    PosIdList = data_fashion:get_pos_id_list(),
    PosNum = urand:rand(0, length(PosIdList)),
    UsePosIdList = urand:get_rand_list(PosNum, PosIdList),
    get_rand_fashion_model_list_helper(UsePosIdList, Career, []).

get_rand_fashion_model_list_helper([Pos|G], Career, FashionModelList) ->
    FashionId = get_rand_fashion_by_pos(Pos),
    if FashionId == 0 ->
            get_rand_fashion_model_list_helper(G, Career, FashionModelList);
        true ->
            AllColors = data_fashion:get_fashion_all_colors(FashionId),
            ColorId = urand:list_rand(AllColors),
            #fashion_color_con{color_logo = ModelId} = data_fashion:get_fashion_color_con(FashionId, ColorId),
            NewFashionModelList = [{Pos, ModelId, ColorId}|FashionModelList],
            get_rand_fashion_model_list_helper(G, Career, NewFashionModelList)
    end;
get_rand_fashion_model_list_helper([], _Career, FashionModelList) ->
    FashionModelList.

get_rand_fashion_by_pos(Pos) ->
    AllFashionIds = ulists:list_shuffle(data_fashion:get_all_fashion()),
    get_rand_fashion_by_pos(Pos, AllFashionIds).

get_rand_fashion_by_pos(_Pos, []) -> 0;
get_rand_fashion_by_pos(Pos, [FashionId|Rest]) ->
    case data_fashion:get_fashion_pos_id(FashionId) of
        [Pos|_] -> FashionId;
        _ -> 
            get_rand_fashion_by_pos(Pos, Rest)
    end.

%% 使用物品激活限时道具通用接口
active_fashion_by_goods(RoleId, GoodsId) ->
    case is_trial_fashion_goods(GoodsId) of
        true ->
            case data_fashion:get_fashion_trial(GoodsId) of
                #base_fashion_trial{fashion_id = FashionId, color_id = ColorId, expire_time = ExpireTime, is_overlay = IsOverLay} ->
                    role_active_fashion_by_goods(RoleId, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay);
                _ ->
                    skip
            end;
        _ -> %% 忽略永久激活
            skip
    end.

role_active_fashion_by_goods(RoleId, #base_fashion_trial{goods_id = GoodsId, fashion_id = FashionId, 
    color_id = ColorId, expire_time = ExpireTime, is_overlay = IsOverLay}) ->
        role_active_fashion_by_goods(RoleId, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay).

role_active_fashion_by_goods(RoleId, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay) ->
    Pid = misc:get_player_process(RoleId),
    case is_pid(Pid) andalso misc:is_process_alive(Pid) of
        true ->
            lib_player:apply_cast(RoleId, ?APPLY_CAST_SAVE, ?NOT_HAND_OFFLINE, ?MODULE, role_active_fashion_by_goods_do, [FashionId, ColorId, GoodsId, ExpireTime, IsOverLay]);
        _ ->
            active_fashion_offline(RoleId, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay)
    end.

role_active_fashion_by_goods_do(Player, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay) ->
    case lib_fashion_check:active_fashion_use_goods_check(Player, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay) of
        {false, Errcode} -> %?ERR("~p ~p ~p", [FashionId, ExpireTime, _Errcode]),
            ReturnCode  = ?ERRCODE(err413_fashion_cannot_overlay),
            ReturnCode1 = ?ERRCODE(err413_fashion_color_active),
            if Errcode == ReturnCode orelse Errcode == ReturnCode1 ->
                    check_return_goods(Player#player_status.id, GoodsId);
                true ->
                    skip
            end,
            {ok, Player};
        {true, PosId} ->
            #player_status{id = RoleId, role_fashion = RoleFashion} = Player,
            #role_fashion{all_fashions = AllFashions, suit_list = SuitList} = RoleFashion,
            {NewAllFashions, _}  = fashion_color_star_up_do(RoleId, ?COLOR_SHORT_ACTIVE, AllFashions, SuitList, [PosId, FashionId, ColorId, ExpireTime, [{?TYPE_GOODS, GoodsId, 1}]]),
            FashionAttrs    = count_fashion_attr(NewAllFashions),
            SuitAttr        = count_fashion_suit_attr(SuitList),
            FashionAttrs1   = lib_player_attr:partial_attr_convert(SuitAttr ++ FashionAttrs),
            NewRoleFashion  = RoleFashion#role_fashion{all_fashions = NewAllFashions, fashion_attr = FashionAttrs1},
            NewPlayer       = Player#player_status{role_fashion = NewRoleFashion},
            {AllColorList, TempNum, NotOpenNum} = calc_active_fashions(NewAllFashions),
            handle_achievement(NewPlayer, AllColorList, TempNum),
            {ok, NewPlayer1} = lib_wardrobe_active:active_fashion(NewPlayer, AllColorList, NotOpenNum, GoodsId),
            NewPlayer2 = lib_workroom:calc_each_suit_own_num(NewPlayer1, NewAllFashions),
            {ok, NewPlayer2}
    end.

%% 玩家离线激活
active_fashion_offline(RoleId, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay) ->
    FashionCon = data_fashion:get_fashion_con(FashionId, ColorId, 0),
    if 
        not is_record(FashionCon, base_fashion_star_up) ->
            skip;
        true ->
            #base_fashion_star_up{pos_id = PosId} = FashionCon,
            Now = utime:unixtime(),
            case db:get_row(?SELECT_ONE_FASHION_INFO_SQL, [RoleId, PosId, FashionId]) of
                [] -> %% 新激活
                    NewExpireTime = calc_expire_time(Now, ExpireTime),
                    NewColorList = [{ColorId, 0, NewExpireTime}],
                    db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, 0, util:term_to_bitstring(NewColorList)]);
                    % db:execute(?REPLACE_FASHION_POS_SQL, [RoleId, PosId, 0, 0]);
                [_ColorId1, ColorListBin|_] ->
                    ColorList = util:bitstring_to_term(ColorListBin),
                    case lists:keyfind(ColorId, 1, ColorList) of
                        {_, _OldStar, OldExpireTime} when OldExpireTime == 0 ->
                            check_return_goods(RoleId, GoodsId);
                        {_, _OldStar, OldExpireTime} when OldExpireTime > Now andalso IsOverLay == 0 ->
                            check_return_goods(RoleId, GoodsId);
                        {_, _OldStar, OldExpireTime} when OldExpireTime =< Now andalso IsOverLay == 0 ->
                            NewExpireTime = calc_expire_time(Now, ExpireTime),
                            NewColorList = lists:keystore(ColorId, 1, ColorList, {ColorId, _OldStar, NewExpireTime}),
                            db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, 0, util:term_to_bitstring(NewColorList)]);
                        {_, _OldStar, OldExpireTime} when IsOverLay == 1 ->
                            if
                                OldExpireTime > Now ->
                                    NewExpireTime = calc_expire_time(OldExpireTime, ExpireTime);
                                true ->
                                    NewExpireTime = calc_expire_time(Now, ExpireTime)
                            end,
                            NewColorList = lists:keystore(ColorId, 1, ColorList, {ColorId, _OldStar, NewExpireTime}),
                            db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, 0, util:term_to_bitstring(NewColorList)]);                            
                        _ ->
                            NewExpireTime = calc_expire_time(Now, ExpireTime),
                            NewColorList = lists:keystore(ColorId, 1, ColorList, {ColorId, 0, NewExpireTime}),
                            db:execute(?REPLACE_FASHION_INFO_SQL, [RoleId, PosId, FashionId, 0, util:term_to_bitstring(NewColorList)])
                    end
            end
    end.    

is_trial_fashion_goods(GoodsId) ->
    Goods = data_fashion:get_all_trial_fashion_goods(),
    lists:member(GoodsId, Goods).

is_trial_fashion(FashionId) ->
    TrialFashionIds = data_fashion:get_all_trial_fashion(),
    lists:keymember(FashionId, 1, TrialFashionIds).

check_fashion_goods(_GoodsInfo) ->
    true.

check_return_goods(RoleId, GoodsId) ->
    check_return_goods(RoleId, GoodsId, 1).

check_return_goods(RoleId, GoodsId,GoodsNum) ->
    case get_return_goods(GoodsId, GoodsNum) of
        ReturnGoods = [_|_] ->
            Title = utext:get(4130001), Content = utext:get(4130002),
            lib_mail_api:send_sys_mail([RoleId], ?MOD_FASHION, Title, Content, ReturnGoods),
            ok;
        _ ->
            skip
    end.

get_return_goods(GoodsId, Num) ->
    case data_goods_price:get_goods_price(GoodsId) of
        #goods_price{price_type = PriceType, price = Price} when Price =/= 0 ->
            [{PriceType, 0, round(Price*Num)}];
        _ ->
            []
    end.

%% 批量自动激活时装
batch_active_fashion(_RoleId, []) ->
    skip;
batch_active_fashion(RoleId, [{?TYPE_FASHION, GoodsId, _}|Rest]) ->
    active_fashion_by_goods(RoleId, GoodsId),
    batch_active_fashion(RoleId, Rest);
batch_active_fashion(RoleId, [{?TYPE_FASHION, GoodsId}|Rest]) ->
    active_fashion_by_goods(RoleId, GoodsId),
    batch_active_fashion(RoleId, Rest);
batch_active_fashion(RoleId, [_|Rest]) ->
    batch_active_fashion(RoleId, Rest).

%% return - AllColorList:非限时的颜色对应数量 TempNum:限时总数量 NotOpenNum:未开放的
calc_active_fashions(AllFashion) ->
    F = fun(#fashion_pos{fashion_list = FashionList}, {CalcList, CalcTempNum, CalcNotOpenNum}) ->
        F1 = fun(#fashion_info{fashion_id = FashionId, color_list = ColorList}, {TList, TTempNum, TNotOpenNum}) ->
            %% 是否满足开放条件
            IsOpen = is_satisfy_open(FashionId),
            F2 = fun({ColorId, _, Time}, {TList1, TNum0, TNum1}) when Time =< 0 ->
                    case data_fashion:get_fashion_con(FashionId, ColorId, 0) of
                        #base_fashion_star_up{star_cost = [{_, GoodsId, _}|_], pos_id = PosId} ->
                            case data_goods_type:get(GoodsId) of
                                #ets_goods_type{color = Color} ->
                                    case lists:keyfind({PosId, Color}, 1, TList1) of
                                        {_, Num} ->
                                            {
                                                lists:keystore({PosId, Color}, 1, TList1, {{PosId, Color}, Num+1}),
                                                TNum0,
                                                case IsOpen of false -> TNum1 + 1; _ -> TNum1 end
                                            };
                                        _ ->
                                            {
                                                lists:keystore({PosId, Color}, 1, TList1, {{PosId, Color}, 1}),
                                                TNum0,
                                                case IsOpen of false -> TNum1 + 1; _ -> TNum1 end
                                            }
                                    end;
                                _ -> {TList1, TNum0, TNum1}
                            end;
                        _ -> {TList1, TNum0, TNum1}
                    end;
                (_, {TList1, TNum0, TNum1}) -> {TList1, TNum0 + 1, TNum1}
            end,
            lists:foldl(F2, {TList, TTempNum, TNotOpenNum}, ColorList)
        end,
        lists:foldl(F1, {CalcList, CalcTempNum, CalcNotOpenNum}, FashionList)
    end,
    {AllColorList, TempNum, NotOpenNum} = lists:foldl(F, {[], 0, 0}, AllFashion),
    {AllColorList, TempNum, NotOpenNum}.

is_satisfy_open(FashionId) ->
    OpenDay = util:get_open_day(),
    NowTime = utime:unixtime(),
    case data_fashion:get_fashion_model(FashionId) of
        #fashion_model_con{open_day = CfgOpenDay, open_time = CfgOpenTime}
            when is_integer(CfgOpenDay), is_integer(CfgOpenTime),
            OpenDay >= CfgOpenDay, NowTime >= CfgOpenTime ->
            true;
        _ -> false
    end.

%%get_active_cost(FashionId, ColorId) ->
%%    case data_fashion:get_fashion_con(FashionId, ColorId, 0) of
%%        #base_fashion_star_up{star_cost = [{_, GoodsId, _}|_]} -> ok;
%%        _ -> GoodsId = 0
%%    end,
%%    GoodsId.

use_fashion_color_goods(Player, GoodsInfo, GoodsNum) ->
    #goods{player_id = RoleId, goods_id = GoodsId} = GoodsInfo,
    IsTrialGoods = is_trial_fashion_goods(GoodsId),
    FashionTrialCfg = data_fashion:get_fashion_trial(GoodsId),
    if
        not IsTrialGoods ->
            {fail, ?ERRCODE(err413_trial_fashion_cost_error)};
        not is_record(FashionTrialCfg, base_fashion_trial) ->
            {fail, ?ERRCODE(missing_config)};
        FashionTrialCfg#base_fashion_trial.is_overlay == 0 andalso
         GoodsNum > 1 orelse GoodsNum =< 0 ->
            {fail, ?ERRCODE(err413_color_goods_cannot_overlay)};
        true ->
            #base_fashion_trial{fashion_id = FashionId, color_id = ColorId, expire_time = ExpireTime, is_overlay = IsOverLay} = FashionTrialCfg,
            NewExpireTime = round(ExpireTime*GoodsNum),
            case lib_fashion_check:active_fashion_use_goods_check(Player, FashionId, ColorId, GoodsId, NewExpireTime, IsOverLay) of
                {false, Errcode} ->
                    ReturnCode  = ?ERRCODE(err413_fashion_cannot_overlay),
                    ReturnCode1 = ?ERRCODE(err413_fashion_color_active),
                    if Errcode == ReturnCode orelse Errcode == ReturnCode1 ->
                            case check_return_goods(RoleId, GoodsId, GoodsNum) of
                                ok ->
                                    lib_goods_api:cost_object_list(Player, [{0, GoodsInfo#goods.goods_id, GoodsNum}], goods_use, ""),
                                    {use_fashion_color_goods, Player, GoodsNum, Errcode};
                                _ ->
                                    {fail, Errcode}
                            end;
                        true ->
                            {fail, Errcode}
                    end;
                {true, PosId} ->
                    #player_status{id = RoleId, role_fashion = RoleFashion} = Player,
                    #role_fashion{all_fashions = AllFashions, suit_list = SuitList} = RoleFashion,
                    lib_goods_api:cost_object_list(Player, [{0, GoodsInfo#goods.goods_id, GoodsNum}], goods_use, ""),
                    {NewAllFashions, _}  = fashion_color_star_up_do(RoleId, ?COLOR_SHORT_ACTIVE, AllFashions, SuitList, [PosId, FashionId, ColorId, NewExpireTime, [{?TYPE_GOODS, GoodsId, GoodsNum}]]),
                    FashionAttrs    = count_fashion_attr(NewAllFashions),
                    FashionAttrs1   = lib_player_attr:partial_attr_convert(FashionAttrs),
                    NewRoleFashion  = RoleFashion#role_fashion{all_fashions = NewAllFashions, fashion_attr = FashionAttrs1},
                    NewPlayer       = Player#player_status{role_fashion = NewRoleFashion},
                    {AllColorList, TempNum, _NotOpenNum} = calc_active_fashions(NewAllFashions),
                    handle_achievement(NewPlayer, AllColorList, TempNum),
                    {ok, NewPlayer, GoodsNum};
                _ ->
                    {fail, ?FAIL}
            end
    end.

calc_expire_time(StartTime, ExpireTime) ->
    EndTime = StartTime + ExpireTime,
    Rest = EndTime rem 60,
    if Rest == 0 ->
            EndTime;
        true ->
            EndTime + (60 - Rest)
    end.


gm_active_all_fashion(Player) ->
    #player_status{id = RoleId, sid = Sid, role_fashion = RoleFashion} = Player,
    FashionListCfg = data_fashion:get_all_fashion_with_color(),
    F = fun({FashionId, ColorId}, TRoleFashion) ->
        NewColor = {ColorId, 0, 0},
        #role_fashion{all_fashions = TAllFashions, suit_list = TSuitList} = TRoleFashion,
        [PosId|_] = data_fashion:get_fashion_pos_id(FashionId),
        #fashion_pos{fashion_list = FashionList} = FashionPos = get_fashion_pos(PosId, TAllFashions),
        {SuitId, NewSuitFashionL, Acitve, TSuitList1} = update_suit_list(PosId, FashionId, TSuitList),
        FashionInfo = get_fashion_info(PosId, FashionId, FashionList),
        #fashion_info{color_list = ColorList} = FashionInfo,
        NewColorList = lists:keystore(ColorId, 1, ColorList, NewColor),
        NewFashionInfo  = FashionInfo#fashion_info{color_list = NewColorList},
        db_update_fashion_info(RoleId, NewFashionInfo),
        TSuitList =/= TSuitList1 andalso db_update_fashion_suit(RoleId, SuitId, NewSuitFashionL, Acitve),
        TAllFashions1 = update_fashion_info(NewFashionInfo, FashionList, FashionPos, TAllFashions),
        RoleFashion1  = TRoleFashion#role_fashion{all_fashions = TAllFashions1, suit_list = TSuitList1},
        {ok, BinData} = pt_413:write(41306, [?SUCCESS, PosId, FashionId, 0, 0]),
        lib_server_send:send_to_sid(Sid, BinData),
        RoleFashion1
    end,
    NewRoleFashion = lists:foldl(F, RoleFashion, FashionListCfg),
    #role_fashion{all_fashions = NewAllFashions, suit_list = NewSuitList} = NewRoleFashion,
    FashionAttrs    = count_fashion_attr(NewAllFashions),
    SuitAttr        = count_fashion_suit_attr(NewSuitList),
    FashionAttrs1   = lists:append(FashionAttrs, SuitAttr),
    FashionAttrs2   = lib_player_attr:partial_attr_convert(FashionAttrs1),
    NewRoleFashion1 = NewRoleFashion#role_fashion{fashion_attr = FashionAttrs2},
    NewPlayer   = Player#player_status{role_fashion = NewRoleFashion1},
    NewPlayer1  = lib_player:count_player_attribute(NewPlayer, ?MOD_FASHION, fashion_color_star_up),
    lib_player:send_attribute_change_notify(NewPlayer1, ?NOTIFY_ATTR),
    NewPlayer1.