local addonName, ZLAUTO = ...

local ZL = ZLAUTO.mainFrame
ZL.GUI = LibStub('tdGUI-1.0')
local IsOnline = ZL.IsOnline
local GetClassColorName = ZL.GetClassColorName
local ParseClassColorName = ZL.ParseClassColorName
local ZLCreateFrame = ZL.ZLCreateFrame
local CreateButton = ZL.CreateButton
local CreateHeaderButton = ZL.CreateHeaderButton
local CreateDynamicTable = ZL.CreateDynamicTable
local GameTooltipShow = ZL.GameTooltipShow
local Prefix = ZL.Prefix


ZL.threadId = {}
ZL.RequestReceived = {}
ZL.addNewPlayer = {}




--创建并启动线程
function ZL.CreateThread(threadId, func, player)
    ZL.threadId[threadId] = coroutine.create(func)
    local success, msg = coroutine.resume(ZL.threadId[threadId], player)
    ZL.ThreadTimerStart()
    return success, msg
end

--启动检查线程是否已dead，如是，则ZL.threadId[threadId]=nil
function ZL.ThreadTimerStart()
    if (not ZL.ThreadTimer) then
        ZL.ThreadTimer = true
        C_Timer.NewTicker(0.1, function (self)
            if next(ZL.threadId, nil) then
                for key, thread in pairs(ZL.threadId) do
                    if coroutine.status(thread) == "dead" then
                        ZL.threadId[key] = nil
                    end
                end
            else
                for player in pairs(ZL.addNewPlayer) do
                    C_FriendList.RemoveFriend(player)
                end
                ZL.ThreadTimer = nil
                self:Cancel()
            end
        end)
    end
end
--保存同步的数据
function ZL.SaveRoles(data)
    local _, _, ownSyncKey = ZL.GetOwnRolesSyncKey()
    local otherSyncKey, otherUpdataTime, ownUpdataTime
    --保存sync roles，有绑定过的同步，自己的子账号数据不同步，对比更新日期，删除的角色不保存
    for battleTag, battleTagData in pairs(data.syncData) do
        for BNchildKey, BNchildData in pairs(battleTagData) do
            otherSyncKey = battleTag .. ":" .. BNchildKey
            otherUpdataTime = BNchildData.updataTime
            if otherSyncKey ~= ownSyncKey and ZL.IsRolesSyncKeyBind(otherSyncKey) then
                if not RolesOverView.sync[battleTag] then RolesOverView.sync[battleTag] = {} end
                if not RolesOverView.sync[battleTag][BNchildKey] then RolesOverView.sync[battleTag][BNchildKey] = {} end
                ownUpdataTime = RolesOverView.sync[battleTag][BNchildKey]["updataTime"] or 0
                if ownUpdataTime < otherUpdataTime then
                    RolesOverView.sync[battleTag][BNchildKey] = BNchildData
                    for realmNameKey, realmNameData in pairs(BNchildData) do
                        if type(realmNameData) == "table" then
                            for factionGroupKey, factionGroupData in pairs(realmNameData) do
                                for playerName in pairs(factionGroupData) do
                                    if (not ZL.glb.rolesDel) or (not ZL.glb.rolesDel[playerName["colorName"]]) then
                                        RolesOverView.syncKey[realmNameKey .. ":" .. factionGroupKey .. ":" .. playerName] = battleTag .. ":" .. BNchildKey
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end

    --保存ownroles
    for battleTag, battleTagData in pairs(data.rolesData) do
        for BNchildKey, BNchildData in pairs(battleTagData) do
            if not RolesOverView.sync[battleTag] then RolesOverView.sync[battleTag] = {} end
            RolesOverView.sync[battleTag][BNchildKey] = BNchildData
            for realmNameKey, realmNameData in pairs(BNchildData) do
                if type(realmNameData) == "table" then
                    for factionGroupKey, factionGroupData in pairs(realmNameData) do
                        for playerName in pairs(factionGroupData) do
                            if (not ZL.glb.rolesDel) or (not ZL.glb.rolesDel[playerName["colorName"]]) then
                                RolesOverView.syncKey[realmNameKey .. ":" .. factionGroupKey .. ":" .. playerName] = battleTag .. ":" .. BNchildKey
                            end
                        end
                    end
                end
            end
        end
    end

    --剔除掉已经删除角色的数据
    if ZL.glb.rolesDel and next(ZL.glb.rolesDel) then
        for playerFullName in pairs(ZL.glb.rolesDel) do
            local playerName, realmName, BNChild, battleTag = strsplit(":", playerFullName)
            local parsePlayerName = ParseClassColorName(playerName)
            if RolesOverView["owner"][battleTag] and RolesOverView["owner"][battleTag][BNChild] and RolesOverView["owner"][battleTag][BNChild][realmName] then
                for factionGroup in pairs(RolesOverView["owner"][battleTag][BNChild][realmName]) do
                    RolesOverView["owner"][battleTag][BNChild][realmName][factionGroup][parsePlayerName] = nil
                end
            end
            if RolesOverView["sync"][battleTag] and RolesOverView["sync"][battleTag][BNChild] and RolesOverView["sync"][battleTag][BNChild][realmName] then
                for factionGroup in pairs(RolesOverView["sync"][battleTag][BNChild][realmName]) do
                    RolesOverView["sync"][battleTag][BNChild][realmName][factionGroup][parsePlayerName] = nil
                end
            end
        end
    end

    if ZL.RolesOverViewFrame:IsShown() then
        ZL.RolesOverViewFrame:Update()
    end
end

--获取子账号下有记录的角色名
function ZL.GetSyncAccount()
    local tempTbl = {}
    local realmName = GetRealmName()
    local factionGroup = select(2, UnitFactionGroup("player"))
	for characterKey, syncValue in pairs(RolesOverView["syncKey"]) do
        --对方没有解除绑定的
        if (not RolesOverView["syncKeyUnBind"][syncValue]) then
            --本服务器、本阵营的
            local character = strmatch(characterKey, "^" .. realmName .. ":" .. factionGroup .. ":(.+)$")
            if character then
                if not tempTbl[syncValue] then tempTbl[syncValue] = {} end
                tinsert(tempTbl[syncValue], character)
            end
        end
    end
    return tempTbl
end
-- 获取自己的战网昵称、子账号名称、和SyncKey
function ZL.GetOwnRolesSyncKey()
    local BNChild
    local battleTag = select(2, BNGetInfo())
    if not RolesOverView.owner[battleTag] then RolesOverView.owner[battleTag] = {} end
    if not next(RolesOverView.owner[battleTag], nil) then
        BNChild = UnitGUID("player")
        RolesOverView.owner[battleTag][BNChild] = {}
    else
        for key in pairs(RolesOverView.owner[battleTag]) do
            BNChild = key
            break
        end
    end
    return battleTag, BNChild, battleTag .. ":" .. BNChild
end
--获取所有战网昵称和对应子账号
function ZL.GetAllBattleTagAndBNChild()
    local tempList = {}
    local battleTag, BNChild = ZL.GetOwnRolesSyncKey()
    if not tempList[battleTag] then tempList[battleTag] = {} end
    tempList[battleTag][BNChild] = true
    for _, value in pairs(RolesOverView.syncKey) do
        battleTag, BNChild = strsplit(":", value)
        if not tempList[battleTag] then tempList[battleTag] = {} end
        tempList[battleTag][BNChild] = true
    end
    return tempList
end

--获取战网昵称下拉框列表
function ZL.GetBattleTagDropdownList()
    local tempList = ZL.GetAllBattleTagAndBNChild()
    local battleTagDropdownList = {{text="全部", value=1}}
    local index = 2
    for key in pairs(tempList) do
        tinsert(battleTagDropdownList, {text=key, value=index})
        index = index + 1
    end
    return battleTagDropdownList
end
--获取子账号下拉框列表
function ZL.GetBNChildDropdownList2()
    local tempList = ZL.GetAllBattleTagAndBNChild()
    local BNChildDropdownList = {{text="全部", value=1}}
    local index = 2
    local battleTag = ZL.RolesOverViewFrame.battleTagDropdown:GetText()
    local BNChildText = ZL.RolesOverViewFrame.BNChildDropdown:GetText()
    local isTrue
    -- local _text, _value
    for key, value in pairs(tempList) do
        if battleTag == "全部" or key == battleTag then
            for BNChild in pairs(value) do
                if BNChildText == "全部" or BNChildText == BNChild then
                    isTrue = true
                end
                -- _text = BNChild
                -- _value = BNChild
                if RolesOverView["BNChildNewName"][BNChild] then
                    BNChild = RolesOverView["BNChildNewName"][BNChild] .. ":" .. BNChild--:gsub("Player", ""):gsub("-", "")
                    -- _value = RolesOverView["BNChildNewName"][BNChild] .. ":" .. BNChild
                    if BNChildText == "全部" or BNChildText == BNChild then
                        isTrue = true
                    end
                end
                tinsert(BNChildDropdownList, {text=BNChild, value=index}) --value=index
                index = index + 1
            end
        end
    end
    if not isTrue then
        ZL.RolesOverViewFrame.BNChildDropdown:SetText("全部")
    end
    return BNChildDropdownList
end
function ZL.GetBNChildDropdownList()
    local tempList = ZL.GetAllBattleTagAndBNChild()
    local BNChildDropdownList = {{text="全部", value="全部"}}
    local index = 2
    local battleTag = ZL.RolesOverViewFrame.battleTagDropdown:GetText()
    local BNChildText = ZL.RolesOverViewFrame.BNChildDropdown:GetValue() or ZL.RolesOverViewFrame.BNChildDropdown:GetText()
    local isTrue
    local newBNChild
    for key, value in pairs(tempList) do
        if battleTag == "全部" or key == battleTag then
            for BNChild in pairs(value) do
                if BNChildText == "全部" or BNChildText == BNChild then
                    isTrue = true
                end
                newBNChild = BNChild
                if RolesOverView["BNChildNewName"][BNChild] then
                    newBNChild = RolesOverView["BNChildNewName"][BNChild]
                end
                tinsert(BNChildDropdownList, {text=newBNChild, value=BNChild})
                index = index + 1
            end
        end
    end
    if not isTrue then
        ZL.RolesOverViewFrame.BNChildDropdown:SetDefaultText("全部")
        ZL.RolesOverViewFrame.BNChildDropdown:SetValue("全部")
    end
    return BNChildDropdownList
end

--获取服务器下拉框列表
function ZL.GetRealmDropdownList()
    local tempList = {}
    local realmDropdownList = {{text="全部", value=1}}
    for _, data1 in pairs(RolesOverView["owner"]) do
        for _, data2 in pairs(data1) do
            for key, data3 in pairs(data2) do
                if type(data3) == "table" then
                    tempList[key] = true
                end
            end
        end
    end
    for _, data1 in pairs(RolesOverView["sync"]) do
        for _, data2 in pairs(data1) do
            for key, data3 in pairs(data2) do
                if type(data3) == "table" then
                    tempList[key] = true
                end
            end
        end
    end
    local index = 2
    for realm in pairs(tempList) do
        tinsert(realmDropdownList, {text=realm, value=index})
        index = index + 1
    end
    wipe(tempList)
    tempList = nil
    return realmDropdownList
end
--判定指定SyncKey是否有绑定过
function ZL.IsRolesSyncKeyBind(synckey)
    local IsBind
    for _, _synckey in pairs(RolesOverView.syncKey) do
        if _synckey == synckey then
            IsBind = true
            break
        end
    end
    return IsBind
end
--获取已保存副本信息
function ZL.GetSavedInstanceInfo(playerRoles)
    RequestRaidInfo()
    for i = 1, GetNumSavedInstances() do
        local _, _, reset, _, locked, _, _, _, maxPlayers, _, _, _, _, instanceId = GetSavedInstanceInfo(i)
        if locked then
            local resetTime = reset + GetServerTime()
            playerRoles["instance:" .. instanceId .. ":" .. maxPlayers] = {resetTime=resetTime}
        end
    end
end
--获取周长日常信息
function ZL.GetWeekAndDayQuestInfo(playerRoles)
--[=[
    local entriesQuest = {}
    for i = 1, GetNumQuestLogEntries() do
        local _, _, _, isHeader, _, isComplete, _, questID = GetQuestLogTitle(i)
        if not isHeader and isComplete then
            entriesQuest[questID] = true
        end
    end
]=]
    local weeklyResetTime = ZL.GetWeeklyResetTime()
    --周长
    for i = 24579, 24590 do
        if C_QuestLog.IsQuestFlaggedCompleted(i) then
            playerRoles["weekQuest"] = {resetTime=weeklyResetTime} --已完成并且已交任务
            break
        else
            if IsQuestComplete(i) then
                playerRoles["weekQuest"] = -2 --已完成未提交
                break
            end
        end
    end

    local dailyResetTime = ZL.GetDailyResetTime()
    --日常
    --英雄副本日常
    do
        local questList = {78753, 83714, 84552, 87379}
        for _, questID in ipairs(questList) do
            if C_QuestLog.IsQuestFlaggedCompleted(questID) then
                playerRoles["heroDayQuest"] = -1 --已完成并且已交任务
                break
            else
                if IsQuestComplete(questID) then
                    playerRoles["heroDayQuest"] = -2 --已完成未提交
                    break
                end
            end
        end
    end
    --泰坦符文协议日常
    do
        local questList = {78752, 83713, 83717}
        for _, questID in ipairs(questList) do
            if C_QuestLog.IsQuestFlaggedCompleted(questID) then
                playerRoles["taiTanDayQuest"] = -1 --已完成并且已交任务
                break
            else
                if IsQuestComplete(questID) then
                    playerRoles["taiTanDayQuest"] = -2 --已完成未提交
                    break
                end
            end
        end
    end
    local learnSkillInfo = {}
    local skillName, header, skillRank
    local numSkills = GetNumSkillLines()
    for i = 1, numSkills do
        skillName, header, _, skillRank = GetSkillLineInfo(i)
        if header ~= 1 then
            learnSkillInfo[skillName] = skillRank
        end
    end
    --珠宝加工日常
    do
        if learnSkillInfo["珠宝加工"] and learnSkillInfo["珠宝加工"] >= 350 then
            for i = 12958, 12963 do
                if C_QuestLog.IsQuestFlaggedCompleted(i) then
                    playerRoles["zhuBaoDayQuest"] = {resetTime=dailyResetTime} --已完成并且已交任务
                    break
                else
                    if IsQuestComplete(i) then
                        playerRoles["zhuBaoDayQuest"] = -2 --已完成未提交
                        break
                    end
                end
            end
        else
            playerRoles["zhuBaoDayQuest"] = -3 --未学习或技能点数不够
        end
    end
    --钓鱼日常
    do
        if learnSkillInfo["钓鱼"] and learnSkillInfo["钓鱼"] >= 350 then
            local questList = {13830, 13832, 13833, 13834, 13836}
            for _, questID in ipairs(questList) do
                if C_QuestLog.IsQuestFlaggedCompleted(questID) then
                    playerRoles["fishingDayQuest"] = {resetTime=dailyResetTime} --已完成并且已交任务
                    break
                else
                    if IsQuestComplete(questID) then
                        playerRoles["fishingDayQuest"] = -2 --已完成未提交
                        break
                    end
                end
            end
        else
            playerRoles["fishingDayQuest"] = -3
        end
    end
    --烹饪日常
    do
        if learnSkillInfo["烹饪"] and learnSkillInfo["烹饪"] >= 1 then
            local questList = {13100, 13101, 13102, 13103, 13107, 13112, 13113, 13114, 13115, 13116}
            for _, questID in ipairs(questList) do
                if C_QuestLog.IsQuestFlaggedCompleted(questID) then
                    playerRoles["cookingDayQuest"] = {resetTime=dailyResetTime} --已完成并且已交任务
                    break
                else
                    if IsQuestComplete(questID) then
                        playerRoles["cookingDayQuest"] = -2 --已完成未提交
                        break
                    end
                end
            end
        else
            playerRoles["cookingDayQuest"] = -3
        end
    end
end

--获取货币信息
function ZL.GetCurrencyInfo(playerRoles)
    playerRoles["jinBiCurrency"] = GetMoney()
    local GetCurrencyInfo = C_CurrencyInfo and C_CurrencyInfo.GetCurrencyInfo or GetCurrencyInfo
    local currencyList = {
        42, --公正徽章
        61, --达拉然珠宝匠硬币
        81, --美食家奖章
        101, --英雄纹章
        102, --勇气纹章
        121, --奥特兰克山谷荣誉奖章
        122, --阿拉希盆地荣誉奖章
        125, --战歌峡谷荣誉奖章
        161, --岩石守卫者的碎片
        221, --征服纹章
        241, --冠军的微记
        301, --凯旋纹章
        341, --寒冰纹章
        1900, --竞技场点数
        1901, --荣誉点数
        2589, --赛德里尔精华
        2711, --亵读者的天灾石
    }
    for _, currencyID in ipairs(currencyList) do
        playerRoles["currency:" .. currencyID] = C_CurrencyInfo.GetCurrencyInfo(currencyID).quantity
    end
end

--获取专业技能CD
function ZL.GetProfessionCoolDownInfo(playerRoles)
    local function tempfuc(spellID, keyString)
        local resetTime
        if IsPlayerSpell(spellID) then
            resetTime = ZL.GetCooldownTime(spellID)
        end
        if resetTime == nil then
            --未学习转化技能
            playerRoles[keyString] = -3
        elseif resetTime == 0 then
            playerRoles[keyString] = {coolDownTime=0}
        else
            playerRoles[keyString] = {coolDownTime=resetTime}
        end
    end
    --炼金
    do
        --炼金转化，共CD
        --先判断是否有学，再判断是否有冷却时间，最后判断是否CD中
        local alchemyTransmuteList = {
            17187, 11479, 11480, 17559, 17560, 17561, 17562, 17563, 17564, 17565, 17566,  --17187为转化奥金，初期有CD，后面没有
            28566, 28567, 28568, 28569, 28580, 28581, 28582, 28583, 28584, 28585,
            53771, 53773, 53774, 53775, 53776, 53777, 53779, 53780, 53781, 53782, 53783, 53784,
            54020, 66658, 66659, 66660, 66662, 66664, 46714,
        }
        local resetTime
        for _, spellID in ipairs(alchemyTransmuteList) do
            if IsPlayerSpell(spellID) and GetSpellBaseCooldown(spellID) > 0 then
                resetTime = ZL.GetCooldownTime(spellID)
                break
            end
        end
        if resetTime == nil then
            --未学习转化技能
            playerRoles["alchemyTransmute"] = -3
        elseif resetTime == 0 then
            playerRoles["alchemyTransmute"] = {coolDownTime=0}
        else
            playerRoles["alchemyTransmute"] = {coolDownTime=resetTime}
        end
        --炼金诺森德炼金研究
        tempfuc(60893, "profession:60893")
    end
    --裁缝
    --月布
    tempfuc(18560, "profession:18560")
    --法纹布
    tempfuc(56003, "profession:56003")
    --乌纹布
    tempfuc(56002, "profession:56002")
    --月影布
    tempfuc(56001, "profession:56001")
    --冰川背包
    tempfuc(56005, "profession:56005")
    --雕文
    --大雕文
    tempfuc(61177, "profession:61177")
    --小雕文
    tempfuc(61288, "profession:61288")
    --珠宝
    --冰冻棱柱
    tempfuc(62242, "profession:62242")
    --采矿
    --熔炼泰坦精钢
    tempfuc(55208, "profession:55208")
end
--获取自己的roles数据
function ZL.GetOwnRolesData()
    local battleTag, BNChild = ZL.GetOwnRolesSyncKey()
    local realmName = GetRealmName()
    local factionGroup = select(2, UnitFactionGroup("player"))
    local playerName = UnitName("player")
    local colorName = ZL.GetClassColorName(UnitName("player")) .. ":" .. realmName .. ":" .. BNChild .. ":".. battleTag
    if (not ZL.glb.rolesDel) or (not ZL.glb.rolesDel[colorName]) then
        if not RolesOverView.owner[battleTag][BNChild][realmName] then RolesOverView.owner[battleTag][BNChild][realmName] = {} end
        if not RolesOverView.owner[battleTag][BNChild][realmName][factionGroup] then RolesOverView.owner[battleTag][BNChild][realmName][factionGroup] = {} end
        RolesOverView.owner[battleTag][BNChild]["updataTime"] = date("%Y-%m-%d %H:%M:%S", GetServerTime())
        local playerRoles = {
            ["colorName"] = colorName,
            ["UnitLevel"] = UnitLevel("player"),
            ["itemLevel"] = floor(select(2, GetAverageItemLevel()) or 0),
            ["realmName"] = realmName,
        }
        --副本信息
        ZL.GetSavedInstanceInfo(playerRoles)
        --周长、日常
        ZL.GetWeekAndDayQuestInfo(playerRoles)
        --货币
        ZL.GetCurrencyInfo(playerRoles)
        --专业
        ZL.GetProfessionCoolDownInfo(playerRoles)
        RolesOverView.owner[battleTag][BNChild][realmName][factionGroup][playerName] = playerRoles
    end
end
--判断子账号下是否有在线角色
function ZL.GetTargetCharacter(accountData)
    local realmName = GetRealmName()
    local factionGroup = select(2, UnitFactionGroup("player"))
    local battleTag, BNChild = ZL.GetOwnRolesSyncKey()
    --判断是否为好友，并且在线，不是好友的先不添加，如果在线则直接返回角色名：一个子账号只可能同时存在一个角色在线
    --目的防止频繁添加好友
	for _, player in ipairs(accountData) do
		if IsOnline(player, nil, nil, true) then
			ZL.SendOrAckRoles(player)
            return
		end
	end
    local function temp(player)
        if IsOnline(player, nil, true) then
			ZL.SendOrAckRoles(player)
            return true
        else
            local _info = C_FriendList.GetFriendInfo(player)
            --是好友但不在线则删除，防止好友数量超过100
            if _info then
                C_Timer.After(1, function ()
                    C_FriendList.RemoveFriend(player)
                    ZL.addNewPlayer[player] = nil
                end)
            else
                --名字不存在(比如已经改名了)，删除syncKey，并删除对应的数据
                RolesOverView.syncKey[realmName .. ":" .. factionGroup .. ":" .. player] = nil
                if RolesOverView.sync[battleTag] and RolesOverView.sync[battleTag][BNChild] and RolesOverView.sync[battleTag][BNChild][realmName]
                and RolesOverView.sync[battleTag][BNChild][realmName][factionGroup] then
                    RolesOverView.sync[battleTag][BNChild][realmName][factionGroup][player] = nil
                end
                if ZL.glb["rolesLgnore"] then
                    ZL.glb["rolesLgnore"][player .. ":" .. realmName .. ":" .. BNChild .. ":" .. battleTag] = nil
                end
                if ZL.glb["rolesDel"] then
                    ZL.glb["rolesDel"][player .. ":" .. realmName .. ":" .. BNChild .. ":" .. battleTag] = nil
                end
            end
            return false
		end
    end
	--如果没有在线的，则添加好友，新添加的好友反馈有延迟，需利用协程检查添加好友
    local index = 1
    local function linshi()
        if ZL.IsOnlinePlayer ~= nil then
            C_Timer.After(0.2, linshi)
        else
            if index <= #accountData and (ZL.PlayerIsOnline == false or ZL.PlayerIsOnline == nil) then
                local player = accountData[index]
                local info = C_FriendList.GetFriendInfo(player)
                if not info then
                    ZL.CreateSyncRolesThread(temp, player)
                    C_Timer.After(0.5, linshi)
                end
                index = index + 1
            else
                ChatFrame_RemoveMessageEventFilter("CHAT_MSG_SYSTEM", ZL.AddFriendFilterFunc)
            end
            ZL.PlayerIsOnline = nil
        end
    end
    ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", ZL.AddFriendFilterFunc)
    linshi()
end
--开始发送或者回应roles
function ZL.SendOrAckRoles(targetCharacter, type)
	local _, _, ownSyncKey = ZL.GetOwnRolesSyncKey()
    --发送数据之前先获取一遍自己的roles
    type = type or "sendRoles"
    ZL.GetOwnRolesData()
    local data = {
        type = type,
        playerName = GetClassColorName(UnitName("player")),
        rolesData = RolesOverView.owner,
        syncData = RolesOverView.sync,
        accountSyncKey = ownSyncKey,
    }
    MyAddon:TransmitAddonInfo2("AUTOAUC ROLES", data, "WHISPER", targetCharacter)
end

--同步数据
function ZL.SyncRoles()
    ZL.GetOwnRolesData()
    if (not ZL.syncRolesLastTime) or (GetTime() - ZL.syncRolesLastTime > 5) then
        ZL.syncRolesLastTime = GetTime()
        ZL.isAddNewPlayer = nil
        local SyncAccountTal = ZL.GetSyncAccount()
        for _, accountData in pairs(SyncAccountTal) do
            ZL.GetTargetCharacter(accountData)
        end
        wipe(SyncAccountTal)
        SyncAccountTal = nil
    end
end

--创建同步roles线程
function ZL.CreateSyncRolesThread(func, player)
    if type(func) ~= "function" then return end
    if ZL.threadId["coroutineIsOnline"] then
        C_Timer.NewTicker(0.5, function(self)
            if not ZL.threadId["coroutineIsOnline"] then
                ZL.CreateThread("coroutineIsOnline", func, player)
                self:Cancel()
            end
        end)
    else
        ZL.CreateThread("coroutineIsOnline", func, player)
    end
end

function ZL.CreateActivityMenu(self)
    local row = self.row
    local btn = ZL.RolesOverViewFrame.entries[row][1]
    local playerName, realmName = strsplit(":", btn.playerFullName)
    return {
        {text = playerName .. "-" .. realmName, isTitle = true,},
        {isSeparator = true},
        {
            text = "隐藏该角色",
            func = function ()
                if not ZL.glb.rolesLgnore then ZL.glb.rolesLgnore = {} end
                ZL.glb.rolesLgnore[btn.playerFullName] = true
                ZL.RolesOverViewFrame:Update()
                if ZL.LgnoreRolesFrame:IsShown() then
                    ZL.LgnoreRolesFrame:Update()
                end
            end,
        },
        {
            text = "删除该角色数据",
            func = function ()
                StaticPopup_Show("ZL_DELETEROLES", "确定删除[" .. playerName .. "|cffffff00-" .. realmName .. "|r]所有数据么？删除后不可恢复并且不再保存和同步！").data = btn.playerFullName
            end,
        },
        {
            text = "修改子账号",
            func = function ()
                StaticPopup_Show("ZL_MODIFYBNCHILD", "请输入新的子账号名字(|cffff0000不可包含:|r)").data = btn.playerFullName
            end,
        },
        {isSeparator = true},
        {text = CANCEL},
    }
end

function ZL.CreateActivityMenu2(self)
    local row = self.row
    local btn = ZL.RolesOverViewFrame.currencyEntries[row][1]
    local playerName, realmName = strsplit(":", btn.playerFullName)
    return {
        {text = playerName .. "-" .. realmName, isTitle = true,},
        {isSeparator = true},
        {
            text = "删除该角色数据",
            func = function ()
                StaticPopup_Show("ZL_DELETEROLES", "确定删除[" .. playerName .. "|cffffff00-" .. realmName .. "|r]所有数据么？删除后不可恢复并且不再保存和同步！").data = btn.playerFullName
            end,
        },
        {
            text = "修改子账号",
            func = function ()
                StaticPopup_Show("ZL_MODIFYBNCHILD", "请输入新的子账号名字(|cffff0000不可包含:|r)").data = btn.playerFullName
            end,
        },
        {isSeparator = true},
        {text = CANCEL},
    }
end
--创建rolesUI
function ZL:CreateRolesOverViewFrame()
    ZL.RolesOverViewFrame = ZLCreateFrame("ZLRolesOverViewFrame", ZL, nil, nil, nil, true, true, "角色信息总览")
    local RolesOverViewFrame = ZL.RolesOverViewFrame
    tinsert(UISpecialFrames, RolesOverViewFrame:GetName())
    ZL.RolesOverViewFrame:SetScale(ZL.glb.ZLRolesOverViewFrameScale)
    RolesOverViewFrame:SetScript("OnMouseUp", function (self)
        self:StopMovingOrSizing()
        if not ZL.glb.ZLRolesOverViewFrame then ZL.db.global.ZLRolesOverViewFrame = {} end
        ZL.glb.ZLRolesOverViewFrame.point, _, ZL.glb.ZLRolesOverViewFrame.relative, ZL.glb.ZLRolesOverViewFrame.x, ZL.glb.ZLRolesOverViewFrame.y = self:GetPoint()
    end)
    RolesOverViewFrame:SetScript("OnMouseDown", function (self)
        self:StartMoving()
    end)
    RolesOverViewFrame:SetScript("OnShow", function (self)
        RolesOverViewFrame:Update()
    end)
    RolesOverViewFrame:ClearAllPoints()
    if ZL.glb.ZLRolesOverViewFrame and ZL.glb.ZLRolesOverViewFrame.point then
        RolesOverViewFrame:SetPoint(ZL.glb.ZLRolesOverViewFrame.point, UIParent, ZL.glb.ZLRolesOverViewFrame.relative, ZL.glb.ZLRolesOverViewFrame.x, ZL.glb.ZLRolesOverViewFrame.y)
    else
        RolesOverViewFrame:SetPoint("CENTER")
    end
    RolesOverViewFrame.resizeButton:Hide()
    RolesOverViewFrame.closeButton:SetScript("OnClick", function (self)
        ZL.RolesOverViewFrame.locked = nil
        ZL.opt.ZLRolesOverViewFrameIsShown = nil
        RolesOverViewFrame:Hide()
    end)
    RolesOverViewFrame.lgnoreBtn = CreateFrame("Button", nil, RolesOverViewFrame)
    local lgnoreBtn = RolesOverViewFrame.lgnoreBtn
    lgnoreBtn:SetPoint("TOPLEFT", 3, -5)
    lgnoreBtn:SetSize(20, 20)
    local lgnoreBtnTexture = [[Interface\MONEYFRAME\Arrow-Left-Up.blp]]
    lgnoreBtn:SetNormalTexture(lgnoreBtnTexture)
    lgnoreBtn:SetHighlightTexture(lgnoreBtnTexture)
    lgnoreBtn:SetScript("OnClick", function ()
        if ZL.LgnoreRolesFrame:IsShown() then
            ZL.LgnoreRolesFrame:Hide()
            lgnoreBtnTexture = [[Interface\MONEYFRAME\Arrow-Left-Up.blp]]
            lgnoreBtn:SetNormalTexture(lgnoreBtnTexture)
            lgnoreBtn:SetHighlightTexture(lgnoreBtnTexture)
        else
            ZL.LgnoreRolesFrame:Show()
            lgnoreBtnTexture = [[Interface\MONEYFRAME\Arrow-Right-Up.blp]]
            lgnoreBtn:SetNormalTexture(lgnoreBtnTexture)
            lgnoreBtn:SetHighlightTexture(lgnoreBtnTexture)
        end
    end)
    lgnoreBtn:SetScript("OnEnter", function (self)
        GameTooltipShow(self, "BOTTOM", "TOP", 0, 4)
        GameTooltip:AddLine("角色名单")
        GameTooltip:Show()
    end)
    lgnoreBtn:SetScript("OnLeave", function ()
        GameTooltip:Hide()
    end)

    --刷新按钮
    RolesOverViewFrame.refreshBtn = CreateFrame("Button", nil, RolesOverViewFrame)
    local refreshBtn = RolesOverViewFrame.refreshBtn
    refreshBtn:SetPoint("RIGHT", RolesOverViewFrame.closeButton, "LEFT")
    refreshBtn:SetSize(15, 15)
    refreshBtn:SetNormalTexture(851904)
    refreshBtn:SetHighlightTexture(851904)
    refreshBtn:SetScript("OnClick", function (self)
        ZL.SyncRoles()
        RolesOverViewFrame:Update()
        self:Disable()
        C_Timer.After(2, function ()
            self:Enable()
        end)
    end)
    refreshBtn:SetScript("OnEnter", function (self)
        GameTooltipShow(self, "BOTTOM", "TOP", 0, 5)
        GameTooltip:AddLine("刷新")
        GameTooltip:Show()
    end)
    refreshBtn:SetScript("OnLeave", function ()
        GameTooltip:Hide()
    end)

    --设置按钮
    RolesOverViewFrame.rolesSettingBtn = CreateFrame("Button", nil, RolesOverViewFrame)
    local rolesSettingBtn = RolesOverViewFrame.rolesSettingBtn
    rolesSettingBtn:SetPoint("RIGHT", refreshBtn, "LEFT", -5, 0)
    rolesSettingBtn:SetSize(15, 15)
    rolesSettingBtn:SetNormalTexture("Interface\\Buttons\\UI-OptionsButton.blp")
    rolesSettingBtn:SetHighlightTexture("Interface\\Buttons\\UI-OptionsButton.blp")
    rolesSettingBtn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    rolesSettingBtn:SetScript("OnClick", function (self, button)
        if button == "LeftButton" then
            ZL.OpenAceConfigDialog("金团拍卖助手", "rolesOverView", "bindNewRoles")
        else
            ZL.OpenAceConfigDialog("金团拍卖助手", "windowsSetting", "guiScale")
        end
    end)
    rolesSettingBtn:SetScript("OnEnter", function (self)
        GameTooltipShow(self, "BOTTOM", "TOP", 0, 5)
        GameTooltip:AddLine("设置")
        GameTooltip:AddLine("左键：|cffffffff角色总览设置|r")
        GameTooltip:AddLine("右键：|cffffffff窗口缩放设置|r")
        GameTooltip:Show()
    end)
    rolesSettingBtn:SetScript("OnLeave", function ()
        GameTooltip:Hide()
    end)

    --创建滚动条
    RolesOverViewFrame.scrollFrame = CreateFrame("ScrollFrame", nil, RolesOverViewFrame, "UIPanelScrollFrameTemplate")
    RolesOverViewFrame.scrollFrame:SetFrameLevel(RolesOverViewFrame:GetFrameLevel() + 1) -- 设置为比父框架高1级
    RolesOverViewFrame.scrollFrame:SetPoint("TOPLEFT", RolesOverViewFrame.TitleBottom, "BOTTOMLEFT", 0, 0)
    RolesOverViewFrame.scrollFrame:SetPoint("BOTTOMRIGHT", RolesOverViewFrame, "BOTTOMRIGHT", 0, 3)
    RolesOverViewFrame.scrollFrame:SetClipsChildren(true) --必须设置为true，scrollFrame所有的子元素才会被剪切
    RolesOverViewFrame.scrollFrame:SetScript("OnMouseWheel", ZL.ScrollFrame_OnMouseWheel) --重设滑动条鼠标滚轮事件
    --重设ScrollBar位置，放置到scrollFrame内，防止被剪切掉
    RolesOverViewFrame.scrollFrame.ScrollBar:ClearAllPoints()
    RolesOverViewFrame.scrollFrame.ScrollBar:SetPoint("TOPLEFT", RolesOverViewFrame.scrollFrame, "TOPRIGHT", -20, -17)
    RolesOverViewFrame.scrollFrame.ScrollBar:SetPoint("BOTTOMRIGHT", RolesOverViewFrame.scrollFrame, "BOTTOMRIGHT", 0, 16)
    RolesOverViewFrame.scrollFrame.content = CreateFrame("Frame", nil, RolesOverViewFrame.scrollFrame)
    local content = RolesOverViewFrame.scrollFrame.content
    content:SetPoint("TOPLEFT", RolesOverViewFrame.scrollFrame, "TOPLEFT", 0, 0)
    content:SetSize(RolesOverViewFrame.scrollFrame:GetWidth()-20, 100)
    RolesOverViewFrame.scrollFrame:SetScrollChild(content)
    RolesOverViewFrame.scrollFrame.ScrollBar:SetFrameLevel(content:GetFrameLevel()+100)
    
    RolesOverViewFrame.scrollFrame.ScrollBar.colTexture = RolesOverViewFrame.scrollFrame.ScrollBar:CreateTexture(nil, "OVERLAY")
    local colTexture = RolesOverViewFrame.scrollFrame.ScrollBar.colTexture
    colTexture:SetColorTexture(0.56, 0.93, 0.56, 0.2)
    colTexture:SetBlendMode("ADD")

    RolesOverViewFrame.scrollFrame.ScrollBar.rowTexture = RolesOverViewFrame.scrollFrame.ScrollBar:CreateTexture(nil, "OVERLAY")
    local rowTexture = RolesOverViewFrame.scrollFrame.ScrollBar.rowTexture
    rowTexture:SetColorTexture(0.56, 0.93, 0.56, 0.2)
    rowTexture:SetBlendMode("ADD")

    local battleTagFontString = content:CreateFontString(nil, "OVERLAY")
    battleTagFontString:SetPoint("TOPLEFT", content, "TOPLEFT", 3, -8)
    battleTagFontString:SetHeight(24)
    battleTagFontString:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    battleTagFontString:SetWordWrap(false)
    battleTagFontString:SetJustifyH("LEFT")
    battleTagFontString:SetTextColor(1, 0.82, 0, 1)
    battleTagFontString:SetText("战网昵称：")

    RolesOverViewFrame.battleTagDropdown = CreateFrame("Button", nil, content)
    local battleTagDropdown = RolesOverViewFrame.battleTagDropdown
    battleTagDropdown:SetPoint("LEFT", battleTagFontString, "RIGHT", 5, 0)
    battleTagDropdown:SetSize(190, 24)
    ZL.GUI:GetClass('Dropdown'):Bind(battleTagDropdown)
    battleTagDropdown:SetDefaultText("全部")
    battleTagDropdown:SetMenuTable(ZL.GetBattleTagDropdownList())
    battleTagDropdown:SetCallback('OnSelectChanged', function ()
        RolesOverViewFrame.BNChildDropdown:SetMenuTable(ZL.GetBNChildDropdownList())
        RolesOverViewFrame:Update()
    end)

    local BNChildFontString = content:CreateFontString(nil, "OVERLAY")
    BNChildFontString:SetPoint("LEFT", battleTagDropdown, "RIGHT", 5, 0)
    BNChildFontString:SetHeight(24)
    BNChildFontString:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    BNChildFontString:SetWordWrap(false)
    BNChildFontString:SetJustifyH("LEFT")
    BNChildFontString:SetTextColor(1, 0.82, 0, 1)
    BNChildFontString:SetText("子账号：")

    RolesOverViewFrame.BNChildDropdown = CreateFrame("Button", nil, content)
    local BNChildDropdown = RolesOverViewFrame.BNChildDropdown
    BNChildDropdown:SetPoint("LEFT", BNChildFontString, "RIGHT", 5, 0)
    BNChildDropdown:SetSize(220, 24)
    ZL.GUI:GetClass('Dropdown'):Bind(BNChildDropdown)
    BNChildDropdown:SetDefaultText("全部")
    BNChildDropdown:SetMenuTable(ZL.GetBNChildDropdownList())
    BNChildDropdown:SetCallback('OnSelectChanged', function (self)
        RolesOverViewFrame:Update()
    end)

    local tooltipFontString2 = content:CreateFontString(nil, "OVERLAY")
    tooltipFontString2:SetPoint("LEFT", BNChildDropdown, "RIGHT", 5, 0)
    tooltipFontString2:SetHeight(24)
    tooltipFontString2:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    tooltipFontString2:SetWordWrap(false)
    tooltipFontString2:SetJustifyH("LEFT")
    tooltipFontString2:SetTextColor(1, 0.82, 0, 1)
    tooltipFontString2:SetText("右键点击小地图按钮可固定窗口")

    local width1 = 3 + battleTagFontString:GetWidth() + 5 + battleTagDropdown:GetWidth() + 5 + BNChildFontString:GetWidth() + 5 + BNChildDropdown:GetWidth() + 5 + tooltipFontString2:GetWidth() + 25

    local realmName = GetRealmName()
    local factionGroup = select(2, UnitFactionGroup("player"))

    local realmFontString = content:CreateFontString(nil, "OVERLAY")
    realmFontString:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    realmFontString:SetHeight(24)
    realmFontString:SetWordWrap(false)
    realmFontString:SetJustifyH("LEFT")
    realmFontString:SetTextColor(1, 0.82, 0, 1)
    realmFontString:SetText("服务器：")
    
    RolesOverViewFrame.realmDropdown = CreateFrame("Button", nil, content)
    local realmDropdown = RolesOverViewFrame.realmDropdown
    realmDropdown:SetPoint("LEFT", realmFontString, "RIGHT", 5, 0)
    realmDropdown:SetSize(150, 24)
    ZL.GUI:GetClass('Dropdown'):Bind(realmDropdown)
    realmDropdown:SetMenuTable(ZL.GetRealmDropdownList())
    realmDropdown:SetDefaultText(realmName)
    realmDropdown:SetCallback('OnSelectChanged', function ()
        
        RolesOverViewFrame:Update()
    end)

    local factionGroupFontString = content:CreateFontString(nil, "OVERLAY")
    factionGroupFontString:SetPoint("LEFT", realmDropdown, "RIGHT", 5, 0)
    factionGroupFontString:SetHeight(24)
    factionGroupFontString:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    factionGroupFontString:SetWordWrap(false)
    factionGroupFontString:SetJustifyH("LEFT")
    factionGroupFontString:SetTextColor(1, 0.82, 0, 1)
    factionGroupFontString:SetText("阵营：")
    
    RolesOverViewFrame.factionGroupDropdown = CreateFrame("Button", nil, content)
    local factionGroupDropdown = RolesOverViewFrame.factionGroupDropdown
    factionGroupDropdown:SetPoint("LEFT", factionGroupFontString, "RIGHT", 5, 0)
    factionGroupDropdown:SetSize(90, 24)
    ZL.GUI:GetClass('Dropdown'):Bind(factionGroupDropdown)
    factionGroupDropdown:SetMenuTable({{text = "全部", value = 1}, {text = "联盟", value = 2}, {text = "部落", value = 3}})
    factionGroupDropdown:SetDefaultText(factionGroup)
    factionGroupDropdown:SetCallback('OnSelectChanged', function ()
        
        RolesOverViewFrame:Update()
    end)

    local tooltipFontString = content:CreateFontString(nil, "OVERLAY")
    tooltipFontString:SetPoint("LEFT", factionGroupDropdown, "RIGHT", 5, 0)
    tooltipFontString:SetHeight(24)
    tooltipFontString:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
    tooltipFontString:SetWordWrap(false)
    tooltipFontString:SetJustifyH("LEFT")
    tooltipFontString:SetTextColor(1, 0.82, 0, 1)
    tooltipFontString:SetText("|T136814:0:0:2:0|t:已完成  |T136813:0:0:2:0|t:未学习  |T136815:0:0:2:0|t:已完成未交任务")

    RolesOverViewFrame.FixedSortingCheckBtn = CreateFrame("CheckButton", nil, content, "ChatConfigCheckButtonTemplate")
    local FixedSortingCheckBtn = RolesOverViewFrame.FixedSortingCheckBtn
    FixedSortingCheckBtn:SetSize(20, 20)
    FixedSortingCheckBtn:SetHitRectInsets(0, -FixedSortingCheckBtn.Text:GetWidth(), 0, 0)
    FixedSortingCheckBtn:SetScript("OnEnter", function (self)
        GameTooltipShow(self, "BOTTOM", "TOP", 0 , 5)
        GameTooltip:AddLine("固定排序")
        GameTooltip:AddLine("1、按照玩家名字固定排序", 1, 1, 1)
        GameTooltip:AddLine("2、固定排序模式下可以通过拖动\n玩家名字调整排序", 1, 1, 1)
        GameTooltip:AddLine("3、也可以点击相应标题栏进行排序", 1, 1, 1)
        GameTooltip:Show()
    end)
    FixedSortingCheckBtn:SetScript("OnLeave", function ()
        GameTooltip:Hide()
    end)
    FixedSortingCheckBtn:SetScript("OnClick", function (self)
        if FixedSortingCheckBtn:GetChecked() then
            if RolesOverViewFrame.entries[1][1] then
                RolesOverViewFrame.entries[1][1].sortTexture:Hide()
            end
            if not ZL.glb.rolesSort then ZL.glb.rolesSort = {} end
            ZL.glb.rolesSort.index = 0
            if not ZL.glb.rolesSort["0"] then
                ZL.glb.rolesSort["0"] = {}
                for ir in ipairs(RolesOverViewFrame.entries) do
                    if ir > 1 then
                        if RolesOverViewFrame.entries[ir][1].playerFullName then
                            tinsert(ZL.glb.rolesSort["0"], RolesOverViewFrame.entries[ir][1].playerFullName)
                        end
                    end
                end
            end
            RolesOverViewFrame:Update()
        end
    end)

    RolesOverViewFrame.FixedSortingCheckBtn2 = CreateFrame("CheckButton", nil, content, "ChatConfigCheckButtonTemplate")
    local FixedSortingCheckBtn2 = RolesOverViewFrame.FixedSortingCheckBtn2
    FixedSortingCheckBtn2:SetSize(20, 20)
    FixedSortingCheckBtn2:SetHitRectInsets(0, -FixedSortingCheckBtn2.Text:GetWidth(), 0, 0)
    FixedSortingCheckBtn2:SetScript("OnEnter", function (self)
        GameTooltipShow(self, "BOTTOM", "TOP", 0 , 5)
        GameTooltip:AddLine("固定排序")
        GameTooltip:AddLine("1、按照玩家名字固定排序", 1, 1, 1)
        GameTooltip:AddLine("2、固定排序模式下可以通过拖动\n玩家名字调整排序", 1, 1, 1)
        GameTooltip:AddLine("3、也可以点击相应标题栏进行排序", 1, 1, 1)
        GameTooltip:Show()
    end)
    FixedSortingCheckBtn2:SetScript("OnLeave", function ()
        GameTooltip:Hide()
    end)
    FixedSortingCheckBtn2:SetScript("OnClick", function (self)
        if FixedSortingCheckBtn2:GetChecked() then
            if RolesOverViewFrame.currencyEntries[1][1] then
                RolesOverViewFrame.currencyEntries[1][1].sortTexture:Hide()
            end
            if not ZL.glb.currencyRolesSort then ZL.glb.currencyRolesSort = {} end
            ZL.glb.currencyRolesSort.index = 0
            if not ZL.glb.currencyRolesSort["0"] then
                ZL.glb.currencyRolesSort["0"] = {}
                for ir in ipairs(RolesOverViewFrame.currencyEntries) do
                    if ir > 1 then
                        if RolesOverViewFrame.currencyEntries[ir][1].playerFullName then
                            tinsert(ZL.glb.currencyRolesSort["0"], RolesOverViewFrame.currencyEntries[ir][1].playerFullName)
                        end
                    end
                end
            end
            RolesOverViewFrame:Update()
        end
    end)

    RolesOverViewFrame.entries = CreateDynamicTable()
    RolesOverViewFrame.currencyEntries = CreateDynamicTable()
    RolesOverViewFrame:Hide()
    function RolesSort(tableName)
        if not ZL.glb.rolesSort then ZL.glb.rolesSort = {["1"]="up", ["index"]=1} end
        local index = ZL.glb.rolesSort.index
        local direction = ZL.glb.rolesSort[tostring(index)]
        if index > #tableName[1] then
            index = #tableName[1]
        end
        local priority = {}
        if type(direction) == "table" then
            for i, name in ipairs(direction) do
                priority[name] = i
            end
        end
        table.sort(tableName, function (a, b)
            if index > 0 then
                local a_new = (index == 1 and ParseClassColorName(a[index]) or a[index])
                local b_new = (index == 1 and ParseClassColorName(b[index]) or b[index])
                a_new = type(a_new) == "table" and -1 or a_new
                b_new = type(b_new) == "table" and -1 or b_new
                if direction == "up" then
                    if a_new < b_new then
                        return true
                    end
                else
                    if a_new > b_new then
                        return true
                    end
                end
                return false
            else
                local a_priority = priority[a[1]] or math.huge  -- 如果名字不在 list 中，优先级为无穷大
                local b_priority = priority[b[1]] or math.huge  -- 如果名字不在 list 中，优先级为无穷大
                -- 如果优先级相同（比如都不在 list 中），则按字母顺序排序
                if a_priority == b_priority then
                    return ParseClassColorName(a[1]) < ParseClassColorName(b[1])
                else
                    -- 否则按优先级排序
                    return a_priority < b_priority
                end
            end
        end)
    end
    function RolesSort2(tableName)
        if not ZL.glb.currencyRolesSort then ZL.glb.currencyRolesSort = {["1"]="up", ["index"]=1} end
        local index = ZL.glb.currencyRolesSort.index
        local direction = ZL.glb.currencyRolesSort[tostring(index)]
        if index > #tableName[1] then
            index = #tableName[1]
        end
        local priority = {}
        if type(direction) == "table" then
            for i, name in ipairs(direction) do
                priority[name] = i
            end
        end
        table.sort(tableName, function (a, b)
            if index > 0 then
                local a_new = index == 1 and ParseClassColorName(a[index]) or a[index]
                local b_new = index == 1 and ParseClassColorName(b[index]) or b[index]
                if direction == "up" then
                    if a_new < b_new then
                        return true
                    end
                else
                    if a_new > b_new then
                        return true
                    end
                end
                return false
            else
                local a_priority = priority[a[1]] or math.huge  -- 如果名字不在 list 中，优先级为无穷大
                local b_priority = priority[b[1]] or math.huge  -- 如果名字不在 list 中，优先级为无穷大
                -- 如果优先级相同（比如都不在 list 中），则按字母顺序排序
                if a_priority == b_priority then
                    return ParseClassColorName(a[1]) < ParseClassColorName(b[1])
                else
                    -- 否则按优先级排序
                    return a_priority < b_priority
                end
            end
        end)
        wipe(priority)
        priority = nil
    end

    function RolesOverViewFrame:Update()
        local ownplayerName = GetClassColorName(UnitName("player"))
        local ownrealmName = GetRealmName()
        local ownbattleTag, ownBNChild = ZL.GetOwnRolesSyncKey()
        local ownplayerFullName = ownplayerName .. ":" .. ownrealmName .. ":" .. ownBNChild .. ":" .. ownbattleTag
        for i in ipairs(RolesOverViewFrame.entries) do
            for j in ipairs(RolesOverViewFrame.entries[i]) do
                RolesOverViewFrame.entries[i][j]:Hide()
            end
        end
        for i in ipairs(RolesOverViewFrame.currencyEntries) do
            for j in ipairs(RolesOverViewFrame.currencyEntries[i]) do
                RolesOverViewFrame.currencyEntries[i][j]:Hide()
            end
        end
        local showData = {}
        local rolesData = {}
        local title = {}
        local totalWidth = 0
        local totalHeight = battleTagFontString:GetHeight() + 8
        do
            for _, data in ipairs(ZL.RolesTypes) do
                if data.isShow() then
                    tinsert(showData, data)
                    tinsert(title, data.name)
                end
            end
            local battleTagText = ZL.RolesOverViewFrame.battleTagDropdown:GetText()
            local BNChildText = ZL.RolesOverViewFrame.BNChildDropdown:GetValue() or ZL.RolesOverViewFrame.BNChildDropdown:GetText()
            -- local _, txt2 = strsplit(":", BNChildText)
            -- if txt2 then
            --     BNChildText = txt2
            -- end
            for battleTag, battleData in pairs(RolesOverView.owner) do
                if battleTagText == "全部" or battleTagText == battleTag then
                    for BNChild, BNChildData in pairs(battleData) do
                        if BNChildText == "全部" or BNChildText == BNChild then
                            for realName, realNameData in pairs(BNChildData) do
                                if type(realNameData) == "table" then
                                    for _factionGroup, factionGroupData in pairs(realNameData) do
                                        for player, playerData in pairs(factionGroupData) do
                                            if (not ZL.glb.rolesLgnore) or (not ZL.glb.rolesLgnore[playerData["colorName"]]) then
                                                local contentData = {}
                                                for _, data in ipairs(showData) do
                                                    tinsert(contentData, playerData[data.isShow()] or 0)
                                                end
                                                tinsert(rolesData, contentData)
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            for battleTag, battleData in pairs(RolesOverView.sync) do
                if battleTagText == "全部" or battleTagText == battleTag then
                    for BNChild, BNChildData in pairs(battleData) do
                        if ownBNChild ~= BNChild and (BNChildText == "全部" or BNChildText == BNChild) then
                            for realName, realNameData in pairs(BNChildData) do
                                if type(realNameData) == "table" then
                                    for factionGroup, factionGroupData in pairs(realNameData) do
                                        for player, playerData in pairs(factionGroupData) do
                                            if (not ZL.glb.rolesLgnore) or (not ZL.glb.rolesLgnore[playerData["colorName"]]) then
                                                local contentData = {}
                                                for _, data in ipairs(showData) do
                                                    tinsert(contentData, playerData[data.isShow()] or 0)
                                                end
                                                tinsert(rolesData, contentData)
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if rolesData[1] then
                RolesSort(rolesData)
            end
            tinsert(rolesData, 1, title)
            local w, h = 65, 20
            local colTextureHeight = (#rolesData -1) * h
            local rowTextureWidth = #rolesData[1] * w + 60
            totalWidth = rowTextureWidth + 26
            --8:间隙， 25：第一行高度
            totalHeight = totalHeight + 8 + 25 + colTextureHeight
            for i, data in ipairs(rolesData) do
                for j, value in ipairs(data) do
                    if i == 1 then
                        if not RolesOverViewFrame.entries[i][j] then
                            local button = CreateHeaderButton(content, w, h+5)
                            if j == 1 then
                                button:SetWidth(w+60)
                                button:SetPoint("TOPLEFT", battleTagFontString, "BOTTOMLEFT", (j-1)*w, -(i-1)*h-8)
                                button.sortTexture = button:CreateTexture(nil, "OVERLAY")
                                button.sortTexture:SetSize(12, 12)
                                button.sortTexture:Hide()
                                FixedSortingCheckBtn:SetPoint("LEFT", button, "LEFT")
                                FixedSortingCheckBtn:SetFrameLevel(button:GetFrameLevel()+1)
                            else
                                button:SetPoint("LEFT", RolesOverViewFrame.entries[i][j-1], "RIGHT", 0, 0)
                            end
                            local myFont = CreateFont("MyCustomFont")
                            myFont:CopyFontObject(GameFontNormal)
                            myFont:SetFont(GameFontNormal:GetFont(), 13, "OUTLINE")
                            myFont:SetTextColor(1, 1, 1)
                            button:SetNormalFontObject(myFont)
                            button:SetNormalTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Parchment-Horizontal]])
                            button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
                            button:SetID(j)
                            button:SetScript("OnEnter", function (self)
                                GameTooltipShow(self, "BOTTOM", "TOP")
                                GameTooltip:AddLine("点击可排序")
                                GameTooltip:Show()
                            end)
                            button:SetScript("OnLeave", function ()
                                GameTooltip:Hide()
                            end)
                            RolesOverViewFrame.entries[i][j] = button
                        end
                    else
                        if not RolesOverViewFrame.entries[i][j] then
                            local button = CreateButton(nil, content, "", "TOPLEFT", RolesOverViewFrame.entries[1][1], "BOTTOMLEFT", (j-1)*w+3, -(i-1)*h-3, w, h, 13)
                            button:ClearAllPoints()
                            if j == 1 then
                                button:SetWidth(w+60)
                                button:SetPoint("TOPLEFT", RolesOverViewFrame.entries[1][1], "BOTTOMLEFT", 0, -(i-2)*h)

                                button:SetMovable(true)
                                button:RegisterForDrag("LeftButton")
                                button:SetScript("OnDragStart", button.StartMoving)
                                button:SetScript("OnDragStop", function (self)
                                    self:StopMovingOrSizing()
                                    local isTrue
                                    if FixedSortingCheckBtn:GetChecked() then
                                        local temp
                                        local btn2
                                        for ir in ipairs(RolesOverViewFrame.entries) do
                                            for ic in ipairs(RolesOverViewFrame.entries[ir]) do
                                                btn2 = RolesOverViewFrame.entries[ir][ic]
                                                if btn2:IsMouseOver() and btn2 ~= self and btn2.row then
                                                    isTrue = true
                                                    temp = RolesOverViewFrame.entries[btn2.row][1].playerFullName
                                                    RolesOverViewFrame.entries[btn2.row][1].playerFullName = self.playerFullName
                                                    self.playerFullName = temp
                                                    break
                                                end
                                            end
                                        end
                                        temp = nil
                                        btn2 = nil
                                    else
                                        local msgStr = "固定排序模式下才可以调整玩家名字排序！"
                                        print(Prefix(msgStr))
                                        ZL.ScrollingMessageFrame:AddMessage(msgStr)
                                    end
                                    self:ClearAllPoints()
                                    self:SetPoint("TOPLEFT", RolesOverViewFrame.entries[1][1], "BOTTOMLEFT", 0, -(self.row-2)*h)
                                    if isTrue then
                                        if not ZL.glb.rolesSort then ZL.glb.rolesSort = {} end
                                        ZL.glb.rolesSort["0"] = {}
                                        for ir in ipairs(RolesOverViewFrame.entries) do
                                            if ir > 1 then
                                                local btn = RolesOverViewFrame.entries[ir][1]
                                                if btn.playerFullName then
                                                    tinsert(ZL.glb.rolesSort["0"], btn.playerFullName)
                                                end
                                            end
                                        end
                                        C_Timer.After(0.25, function ()
                                            RolesOverViewFrame:Update()
                                        end)
                                    end
                                end)
                            else
                                button:SetPoint("TOPLEFT", RolesOverViewFrame.entries[1][1], "BOTTOMLEFT", (j-1)*w+60, -(i-2)*h)
                            end
                            button:RegisterForClicks("RightButtonUp")
                            button:SetScript("OnClick", function (self, btn)
                                ZL.GUI:ToggleMenu(self, ZL.CreateActivityMenu(self), 'cursor')
                            end)

                            local myFont = CreateFont("MyCustomFont2")
                            myFont:CopyFontObject(GameFontNormal)
                            myFont:SetFont(GameFontNormal:GetFont(), 12, "OUTLINE")
                            myFont:SetTextColor(1, 1, 1)
                            button:SetNormalFontObject(myFont)
                            button:SetScript("OnLeave", function (self)
                                colTexture:Hide()
                                rowTexture:Hide()
                                GameTooltip:Hide()
                            end)
                            button.texture = button:CreateTexture(nil, "OVERLAY")
                            button.texture:SetPoint("CENTER")
                            button.texture:SetSize(h-3, h-3)
                            button.row = i
                            RolesOverViewFrame.entries[i][j] = button
                        end
                    end
                    local f = RolesOverViewFrame.entries[i][j]
                    f:SetText("")
                    if i == 1 then
                        f:SetScript("OnClick", function (self, button)
                            if button == "LeftButton" then
                                FixedSortingCheckBtn:SetChecked()
                                if not ZL.glb.rolesSort then ZL.glb.rolesSort = {} end
                                local index = self:GetID()
                                ZL.glb.rolesSort.index = index
                                local sortTexture = RolesOverViewFrame.entries[1][1].sortTexture
                                sortTexture:ClearAllPoints()
                                sortTexture:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
                                if not ZL.glb.rolesSort[tostring(index)] or ZL.glb.rolesSort[tostring(index)] == "down" then
                                    ZL.glb.rolesSort[tostring(index)] = "up"
                                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortup.png")
                                elseif ZL.glb.rolesSort[tostring(index)] == "up" then
                                    ZL.glb.rolesSort[tostring(index)] = "down"
                                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortdown.png")
                                end
                                sortTexture:Show()
                                RolesOverViewFrame:Update()
                            end
                        end)
                    else
                        if j == 1 then
                            f.playerFullName = value
                        end
                        local btn = RolesOverViewFrame.entries[i][1]
                        if btn.playerFullName == ownplayerFullName then
                            f:SetNormalTexture([[Interface\CHARACTERFRAME\BarFill]])
                        else
                            f:ClearNormalTexture()
                        end
                        f.BorderBottom:Show()
                        f.BorderRight:Show()
                        if i < #rolesData then
                            f.BorderBottom:Hide()
                        end
                        if j < #data then
                            f.BorderRight:Hide()
                        end
                        f.texture:SetTexture()
                        f:SetScript("OnEnter", function (self)
                            colTexture:SetPoint("TOPLEFT", self, "TOPLEFT", 0, (i-2)*h)
                            colTexture:SetSize(self:GetWidth(), colTextureHeight)
                            colTexture:Show()
                            local offsetX = 0
                            if j > 1 then
                                offsetX = (j-1)*w + 60
                            end
                            rowTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -offsetX, 0)
                            rowTexture:SetSize(rowTextureWidth, self:GetHeight())
                            rowTexture:Show()
                            local playerName, _realmName, BNChild, battleTag = strsplit(":", data[1])
                            local BNChildNewName = RolesOverView["BNChildNewName"][BNChild] or BNChild
                            GameTooltipShow(self, "LEFT", "LEFT", totalWidth-offsetX, 0)
                            GameTooltip:AddLine(playerName .. "(子账号可修改)")
                            GameTooltip:AddLine("战网昵称：|cffffffff" .. battleTag .. "|r")
                            GameTooltip:AddLine("子账号：|cffffffff" .. BNChildNewName .. "|r")
                            GameTooltip:AddLine("服务器：|cffffffff" .. _realmName .. "|r")
                            GameTooltip:AddLine(" ")
                            GameTooltip:AddLine("<右键>  打开功能菜单", 1, 1, 1)
                            GameTooltip:Show()
                        end)
                    end
                    --  0:未完成 -1:已完成  -2:已完成未提交  -3:未学习专业技能或技能点数不够  >0：装等、角色等级
                    if type(value) == "string" then
                        if i > 1 and j == 1 then
                            local playerName = strsplit(":", value)
                            f:SetText(playerName)
                        else
                            f:SetText(value)
                        end
                    elseif type(value) == "number" then
                        if value > 0 then
                            f:SetText(value)
                        elseif value == -2 then
                            f.texture:SetTexture([[interface/raidframe/ReadyCheck-Waiting]])
                        elseif value == -3 then
                            f.texture:SetTexture([[interface/raidframe/ReadyCheck-NotReady]])
                        end
                    elseif type(value) == "table" then
                        --已完成任务但还未到重置时间
                        if value.resetTime and value.resetTime > GetServerTime() then
                            f.texture:SetTexture([[interface/raidframe/readycheck-ready]])
                        elseif value.coolDownTime then
                            local remainTime = value.coolDownTime - GetServerTime()
                            if remainTime > 0 then
                                f:SetText("|cffff0000" .. ZL.ConvertSecondsToTimeString(remainTime) .. "|r")
                            else
                                f:SetText("|cff00ff00就绪|r")
                            end
                        end
                    end
                    f:Show()
                end
            end
            local sortTexture = RolesOverViewFrame.entries[1][1].sortTexture
            if ZL.glb.rolesSort and ZL.glb.rolesSort.index and ZL.glb.rolesSort.index > 0 then
                local index = ZL.glb.rolesSort.index
                local newindex = index
                if index > #rolesData[1] then
                    newindex = #rolesData[1]
                end
                local btn = RolesOverViewFrame.entries[1][newindex]
                sortTexture:ClearAllPoints()
                sortTexture:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT")
                if ZL.glb.rolesSort[tostring(index)] == "down" then
                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortdown.png")
                elseif ZL.glb.rolesSort[tostring(index)] == "up" then
                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortup.png")
                end
                sortTexture:Show()
            end
            local f = RolesOverViewFrame.entries[1][1]
            realmFontString:ClearAllPoints()
            realmFontString:SetPoint("TOPLEFT", f, "BOTTOMLEFT", 0, -15-colTextureHeight)

            totalHeight = totalHeight + 15 + realmFontString:GetHeight()
            totalWidth = max(width1, totalWidth)

            wipe(showData)
            wipe(rolesData)
            wipe(title)
        end
        do
            local totalList = {}
            for _, data in ipairs(ZL.CurrencyRoles) do
                if data.isShow() then
                    tinsert(showData, data)
                    tinsert(title, data.name)
                    tinsert(totalList, 0) --初始化合计
                end
            end
            local realmText = ZL.RolesOverViewFrame.realmDropdown:GetText()
            local factionGroupText = ZL.RolesOverViewFrame.factionGroupDropdown:GetText()
            for battleTag, battleData in pairs(RolesOverView.owner) do
                for BNChild, BNChildData in pairs(battleData) do
                    for realName, realNameData in pairs(BNChildData) do
                        if type(realNameData) == "table" and (realmText == "全部" or realmText == realName) then
                            for _factionGroup, factionGroupData in pairs(realNameData) do
                                if factionGroupText == "全部" or factionGroupText == _factionGroup then
                                    for player, playerData in pairs(factionGroupData) do
                                        local contentData = {}
                                        for index, data in ipairs(showData) do
                                            tinsert(contentData, playerData[data.isShow()] or 0)
                                            totalList[index] = totalList[index] + (type(playerData[data.isShow()]) == "number" and playerData[data.isShow()] or 0)
                                        end
                                        tinsert(rolesData, contentData)
                                    end
                                end
                            end
                        end
                    end
                end
            end
            for battleTag, battleData in pairs(RolesOverView.sync) do
                for BNChild, BNChildData in pairs(battleData) do
                    for realName, realNameData in pairs(BNChildData) do
                        if type(realNameData) == "table" and (realmText == "全部" or realmText == realName) then
                            for _factionGroup, factionGroupData in pairs(realNameData) do
                                if factionGroupText == "全部" or factionGroupText == _factionGroup then
                                    for player, playerData in pairs(factionGroupData) do
                                        local contentData = {}
                                        for index, data in ipairs(showData) do
                                            tinsert(contentData, playerData[data.isShow()] or 0)
                                            totalList[index] = totalList[index] + (type(playerData[data.isShow()]) == "number" and playerData[data.isShow()] or 0)
                                        end
                                        tinsert(rolesData, contentData)
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if rolesData[1] then
                RolesSort2(rolesData)
            end
            tinsert(rolesData, 1, title)
            totalList[1] = "合计"
            tinsert(rolesData, totalList)
            local w, h = 90, 20
            local colTextureHeight = (#rolesData -1) * h
            local rowTextureWidth = #rolesData[1] * w
            local offsetX
            for i, data in ipairs(rolesData) do
                offsetX = 0
                for j, value in ipairs(data) do
                    local colWidth = w
                    if j == 1 then
                        colWidth = 120
                        if i == 1 then
                            rowTextureWidth = rowTextureWidth + colWidth - w
                        end
                    elseif rolesData[1][j] == "|cfffa8da5服务器|r" or rolesData[1][j] == "|cfffa8da5等级|r" or rolesData[1][j] == "|cfffa8da5装等|r" then
                        colWidth = 60
                        if i == 1 then
                            rowTextureWidth = rowTextureWidth + colWidth - w
                        end
                    elseif rolesData[1][j] == "|cff40c7eb金币|r" then
                        colWidth = 160
                        if i == 1 then
                            rowTextureWidth = rowTextureWidth + colWidth - w
                        end
                    end

                    if j > 1 then
                        offsetX = offsetX + RolesOverViewFrame.currencyEntries[1][j-1]:GetWidth()
                    end
                    if i == 1 then
                        if not RolesOverViewFrame.currencyEntries[i][j] then
                            local button = CreateHeaderButton(content, colWidth, h+5)
                            if j == 1 then
                                button:SetPoint("TOPLEFT", realmFontString, "BOTTOMLEFT", (j-1)*colWidth, -(i-1)*h-8)
                                button.sortTexture = button:CreateTexture(nil, "OVERLAY")
                                button.sortTexture:SetSize(12, 12)
                                button.sortTexture:Hide()
                                FixedSortingCheckBtn2:SetPoint("LEFT", button, "LEFT")
                                FixedSortingCheckBtn2:SetFrameLevel(button:GetFrameLevel()+1)
                            else
                                button:SetPoint("LEFT", RolesOverViewFrame.currencyEntries[i][j-1], "RIGHT", 0, 0)
                            end
                            button:SetNormalFontObject("MyCustomFont")
                            button:SetNormalTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Parchment-Horizontal]])
                            button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
                            button:SetID(j)
                            button:SetScript("OnEnter", function (self)
                                GameTooltipShow(self, "BOTTOM", "TOP")
                                GameTooltip:AddLine("点击可排序")
                                GameTooltip:Show()
                            end)
                            button:SetScript("OnLeave", function ()
                                GameTooltip:Hide()
                            end)
                            RolesOverViewFrame.currencyEntries[i][j] = button
                        end
                    else
                        if not RolesOverViewFrame.currencyEntries[i][j] then
                            local button = CreateButton(nil, content, " ", "TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", 0, 0, colWidth, h, 13)
                            button:ClearAllPoints()
                            if j == 1 then
                                button:SetPoint("TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", 0, -(i-2)*h)
                                button:SetMovable(true)
                                button:RegisterForDrag("LeftButton")
                                button:SetScript("OnDragStart", button.StartMoving)
                                button:SetScript("OnDragStop", function (self)
                                    self:StopMovingOrSizing()
                                    local isTrue
                                    if FixedSortingCheckBtn2:GetChecked() then
                                        local temp
                                        local btn2
                                        for ir in ipairs(RolesOverViewFrame.currencyEntries) do
                                            for ic in ipairs(RolesOverViewFrame.currencyEntries[ir]) do
                                                btn2 = RolesOverViewFrame.currencyEntries[ir][ic]
                                                if btn2:IsMouseOver() and btn2 ~= self and btn2.row then
                                                    isTrue = true
                                                    temp = RolesOverViewFrame.currencyEntries[btn2.row][1].playerFullName
                                                    RolesOverViewFrame.currencyEntries[btn2.row][1].playerFullName = self.playerFullName
                                                    self.playerFullName = temp
                                                    break
                                                end
                                            end
                                        end
                                        temp = nil
                                        btn2 = nil
                                    else
                                        local msgStr = "固定排序模式下才可以调整玩家名字排序！"
                                        print(Prefix(msgStr))
                                        ZL.ScrollingMessageFrame:AddMessage(msgStr)
                                    end
                                    self:ClearAllPoints()
                                    self:SetPoint("TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", 0, -(i-2)*h)
                                    if isTrue then
                                        if not ZL.glb.currencyRolesSort then ZL.glb.currencyRolesSort = {} end
                                        ZL.glb.currencyRolesSort["0"] = {}
                                        for ir in ipairs(RolesOverViewFrame.currencyEntries) do
                                            if ir > 1 then
                                                local btn = RolesOverViewFrame.currencyEntries[ir][1]
                                                if btn.playerFullName then
                                                    tinsert(ZL.glb.currencyRolesSort["0"], btn.playerFullName)
                                                end
                                            end
                                        end
                                        C_Timer.After(0.25, function ()
                                            RolesOverViewFrame:Update()
                                        end)
                                    end
                                end)
                            else
                                button:SetPoint("TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", offsetX, -(i-2)*h)
                            end
                            button:RegisterForClicks("RightButtonUp")
                            button:SetScript("OnClick", function (self, btn)
                                ZL.GUI:ToggleMenu(self, ZL.CreateActivityMenu2(self), 'cursor')
                            end)
                            button:SetNormalFontObject("MyCustomFont2")
                            button:SetScript("OnLeave", function (self)
                                colTexture:Hide()
                                rowTexture:Hide()
                                GameTooltip:Hide()
                            end)
                            button.texture = button:CreateTexture(nil, "OVERLAY")
                            button.texture:SetPoint("CENTER")
                            button.texture:SetSize(h-3, h-3)
                            button.row = i
                            RolesOverViewFrame.currencyEntries[i][j] = button
                        end
                    end
                    local f = RolesOverViewFrame.currencyEntries[i][j]
                    f:SetText("")
                    f:SetWidth(colWidth)
                    if i == 1 then
                        f:SetScript("OnClick", function (self, button)
                            if button == "LeftButton" then
                                FixedSortingCheckBtn2:SetChecked()
                                if not ZL.glb.currencyRolesSort then ZL.glb.currencyRolesSort = {} end
                                local index = self:GetID()
                                ZL.glb.currencyRolesSort.index = index
                                local sortTexture = RolesOverViewFrame.currencyEntries[1][1].sortTexture
                                sortTexture:ClearAllPoints()
                                sortTexture:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
                                if not ZL.glb.currencyRolesSort[tostring(index)] or ZL.glb.currencyRolesSort[tostring(index)] == "down" then
                                    ZL.glb.currencyRolesSort[tostring(index)] = "up"
                                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortup.png")
                                elseif ZL.glb.currencyRolesSort[tostring(index)] == "up" then
                                    ZL.glb.currencyRolesSort[tostring(index)] = "down"
                                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortdown.png")
                                end
                                sortTexture:Show()
                                RolesOverViewFrame:Update()
                            end
                        end)
                    else
                        if j > 1 then
                            f:ClearAllPoints()
                            f:SetPoint("TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", offsetX, -(i-2)*h)
                        end
                        local fontString = f:GetFontString()
                        fontString:ClearAllPoints()
                        if rolesData[1][j] == "|cfffa8da5玩家名字|r" or rolesData[1][j] == "|cfffa8da5服务器|r" or rolesData[1][j] == "|cfffa8da5等级|r" or rolesData[1][j] == "|cfffa8da5装等|r" then
                            fontString:SetPoint("CENTER")
                        else
                            fontString:SetPoint("RIGHT", f, "RIGHT", -3, 0)
                        end
                        if j == 1 then
                            f.playerFullName = value
                        end
                        local btn = RolesOverViewFrame.currencyEntries[i][1]
                        if btn.playerFullName == ownplayerFullName then
                            f:SetNormalTexture([[Interface\CHARACTERFRAME\BarFill]])
                        elseif i == #rolesData then --最后合计行
                            f:SetNormalTexture([[Interface\ACHIEVEMENTFRAME\UI-Achievement-Parchment-Horizontal-Desaturated]])
                        else
                            f:ClearNormalTexture()
                        end
                        f.BorderBottom:Show()
                        f.BorderRight:Show()
                        if i < #rolesData then
                            f.BorderBottom:Hide()
                        end
                        if j < #data then
                            f.BorderRight:Hide()
                        end
                        f.texture:SetTexture()
                        f:SetScript("OnEnter", function (self)
                            colTexture:SetPoint("TOPLEFT", self, "TOPLEFT", 0, (i-2)*h)
                            colTexture:SetSize(self:GetWidth(), colTextureHeight)
                            colTexture:Show()
                            rowTexture:SetPoint("TOPLEFT", RolesOverViewFrame.currencyEntries[1][1], "BOTTOMLEFT", 0, -(i-2)*h)
                            rowTexture:SetSize(rowTextureWidth, self:GetHeight())
                            rowTexture:Show()
                            if data[1] then
                                local playerName, _realmName, BNChild, battleTag = strsplit(":", data[1])
                                local BNChildNewName = RolesOverView["BNChildNewName"][BNChild] or BNChild
                                GameTooltipShow(RolesOverViewFrame.currencyEntries[1][1], "LEFT", "LEFT", totalWidth, -(i-1)*h)
                                GameTooltip:AddLine(playerName .. "(子账号可修改)")
                                GameTooltip:AddLine("战网昵称：|cffffffff" .. battleTag .. "|r")
                                GameTooltip:AddLine("子账号：|cffffffff" .. BNChildNewName .. "|r")
                                GameTooltip:AddLine("服务器：|cffffffff" .. _realmName .. "|r")
                                GameTooltip:AddLine(" ")
                                GameTooltip:AddLine("<右键>  打开功能菜单", 1, 1, 1)
                                GameTooltip:Show()
                            end
                        end)
                    end
                    if type(value) == "string" then
                        if i > 1 and j == 1 then
                            local playerName = strsplit(":", value)
                            f:SetText(playerName)
                        else
                            f:SetText(value)
                        end
                    elseif type(value) == "number" then
                        if i == #rolesData then
                            if rolesData[1][j] == "|cff40c7eb金币|r" then
                                f:SetText(GetMoneyString(value))
                            elseif rolesData[1][j] == "|cfffa8da5服务器|r" or rolesData[1][j] == "|cfffa8da5等级|r" or rolesData[1][j] == "|cfffa8da5装等|r" then
                                f:SetText(" ")
                            else
                                f:SetText(value)
                            end
                        else
                            if rolesData[1][j] == "|cff40c7eb金币|r" then
                                f:SetText(GetMoneyString(value))
                            else
                                f:SetText(value)
                            end
                        end
                    end
                    f:Show()
                end
            end
            local sortTexture = RolesOverViewFrame.currencyEntries[1][1].sortTexture
            if ZL.glb.currencyRolesSort and ZL.glb.currencyRolesSort.index and ZL.glb.currencyRolesSort.index > 0 then
                local index = ZL.glb.currencyRolesSort.index
                local newindex = index
                if index > #rolesData[1] then
                    newindex = #rolesData[1]
                end
                local btn = RolesOverViewFrame.currencyEntries[1][newindex]
                sortTexture:ClearAllPoints()
                sortTexture:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT")
                if ZL.glb.currencyRolesSort[tostring(index)] == "down" then
                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortdown.png")
                elseif ZL.glb.currencyRolesSort[tostring(index)] == "up" then
                    sortTexture:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Images\\sortup.png")
                end
                sortTexture:Show()
            end

            --8：间隙， 25：第一行高度
            totalHeight = totalHeight + 8 + 25 + colTextureHeight + 3
            totalWidth = max(totalWidth, rowTextureWidth + 26)

            wipe(showData)
            wipe(rolesData)
            wipe(title)
            wipe(totalList)
            totalList = nil
        end

        content:SetSize(totalWidth-20, totalHeight)
        RolesOverViewFrame:SetSize(totalWidth, min(max(totalHeight+43, 200), GetScreenHeight()-50))
        if ZL.LgnoreRolesFrame then
            ZL.LgnoreRolesFrame:Update()
        end
        showData = nil
        rolesData = nil
        title = nil
    end

    if ZL.glb.rolesSort and ZL.glb.rolesSort.index == 0 then
        FixedSortingCheckBtn:Click()
    end
    if ZL.glb.currencyRolesSort and ZL.glb.currencyRolesSort.index == 0 then
        FixedSortingCheckBtn2:Click()
    end
end
--创建不显示角色名单窗口
function ZL:CreateLgnoreRolesFrame()
    ZL.LgnoreRolesFrame = CreateFrame("Frame", nil, ZL.RolesOverViewFrame, "BackdropTemplate")
    local LgnoreRolesFrame = ZL.LgnoreRolesFrame
    LgnoreRolesFrame:SetPoint("TOPRIGHT", ZL.RolesOverViewFrame, "TOPLEFT", 0, 2)
    LgnoreRolesFrame:SetSize(200, 300)
    LgnoreRolesFrame:SetBackdrop({
        bgFile = "Interface/ChatFrame/ChatFrameBackground",
        edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
        edgeSize = 16,
        insets = { left = 3, right = 3, top = 3, bottom = 3 }
    })
    LgnoreRolesFrame:SetBackdropColor(0, 0, 0, 0.9)
    LgnoreRolesFrame:SetBackdropBorderColor(0.9, 0.9, 0.9)
    LgnoreRolesFrame:SetScript("OnShow", function (self)
        self:Update()
    end)
    -- LgnoreRolesFrame.TitleFont = LgnoreRolesFrame:CreateFontString()
    -- LgnoreRolesFrame.TitleFont:SetPoint("TOP", LgnoreRolesFrame, "TOP", 0, -10)
    -- LgnoreRolesFrame.TitleFont:SetFont(GameFontNormal:GetFont(), 16, "OUTLINE")
    -- LgnoreRolesFrame.TitleFont:SetWordWrap(false)
    -- LgnoreRolesFrame.TitleFont:SetTextColor(1, 0.82, 0, 1)
    -- LgnoreRolesFrame.TitleFont:SetText("隐藏和删除角色名单")
    LgnoreRolesFrame:Hide()
    --创建滚动条
    LgnoreRolesFrame.scrollFrame = CreateFrame("ScrollFrame", nil, LgnoreRolesFrame, "UIPanelScrollFrameTemplate")
    LgnoreRolesFrame.scrollFrame:SetFrameLevel(LgnoreRolesFrame:GetFrameLevel() + 1) -- 设置为比父框架高1级
    LgnoreRolesFrame.scrollFrame:SetPoint("TOPLEFT", LgnoreRolesFrame, "TOPLEFT", 5, -5)
    LgnoreRolesFrame.scrollFrame:SetPoint("BOTTOMRIGHT", LgnoreRolesFrame, "BOTTOMRIGHT", 0, 3)
    LgnoreRolesFrame.scrollFrame:SetClipsChildren(true) --必须设置为true，scrollFrame所有的子元素才会被剪切
    LgnoreRolesFrame.scrollFrame:SetScript("OnMouseWheel", ZL.ScrollFrame_OnMouseWheel) --重设滑动条鼠标滚轮事件
    
    --重设ScrollBar位置，放置到scrollFrame内，防止被剪切掉
    LgnoreRolesFrame.scrollFrame.ScrollBar:ClearAllPoints()
    LgnoreRolesFrame.scrollFrame.ScrollBar:SetPoint("TOPLEFT", LgnoreRolesFrame.scrollFrame, "TOPRIGHT", -22, -17)
    LgnoreRolesFrame.scrollFrame.ScrollBar:SetPoint("BOTTOMRIGHT", LgnoreRolesFrame.scrollFrame, "BOTTOMRIGHT", -2, 17)
    LgnoreRolesFrame.scrollFrame.content = CreateFrame("Frame", nil, LgnoreRolesFrame.scrollFrame)
    local content = LgnoreRolesFrame.scrollFrame.content
    content:SetPoint("TOPRIGHT", LgnoreRolesFrame.scrollFrame, "TOPRIGHT", 0, 0)
    content:SetSize(LgnoreRolesFrame.scrollFrame:GetWidth()-20, 100)
    -- ZL.background(content)
    LgnoreRolesFrame.scrollFrame:SetScrollChild(content)
    LgnoreRolesFrame.scrollFrame.ScrollBar:SetFrameLevel(content:GetFrameLevel()+100)
    local contentWidth = content:GetWidth()
    LgnoreRolesFrame.entries = setmetatable({}, {
        __index = function (t, v)
            local f = CreateFrame("Button", nil, content)
            f:SetSize(contentWidth, 20)
            if v == 1 then
                f:SetPoint("TOPLEFT", content, "TOPLEFT", 0, 0)
            else
                f:SetPoint("TOPLEFT", t[v-1], "BOTTOMLEFT", 0, 0)
            end
            f:SetNormalFontObject("GameFontNormal")
            f:SetHighlightFontObject("GameFontHighlight")
            f:SetText(" ")
            local font = f:GetFontString()
            if font then
                font:SetPoint("LEFT")
                font:SetTextColor(1, 0.82, 0)
            end
            f:SetHighlightTexture([[Interface\QuestFrame\UI-QuestLogTitleHighlight]])
            f:SetScript("OnLeave", function ()
                GameTooltip:Hide()
            end)
            f:RegisterForClicks("RightButtonUp")
            t[v] = f
            return f
        end
    })

    function LgnoreRolesFrame:Update()
        for _, f in ipairs(LgnoreRolesFrame.entries) do
            f:Hide()
        end
        local lgnoreList = {}
        local num = 1
        local f, font
        local playerName, realmName
        if ZL.glb["rolesLgnore"] and next(ZL.glb["rolesLgnore"]) then
            for playerFullName in pairs(ZL.glb["rolesLgnore"]) do
                playerName, realmName = strsplit(":", playerFullName)
                if not lgnoreList[realmName] then lgnoreList[realmName] = {} end
                lgnoreList[realmName][playerName] = playerFullName
            end
            f = LgnoreRolesFrame.entries[num]
            f:SetText("|cffff8000已隐藏名单|r")
            font = f:GetFontString()
            font:ClearAllPoints()
            font:SetPoint("CENTER")
            f.playerFullName = nil
            f:Disable()
            f:Show()
            num = num + 1
            for realName, realNameData in pairs(lgnoreList) do
                f = LgnoreRolesFrame.entries[num]
                f:SetText(realName)
                font = f:GetFontString()
                font:ClearAllPoints()
                font:SetPoint("LEFT")
                f.playerFullName = nil
                f:Disable()
                f:Show()
                num = num + 1
                for _playerName, playerNameData in pairs(realNameData) do
                    f = LgnoreRolesFrame.entries[num]
                    f:SetText("　" .. _playerName)
                    font = f:GetFontString()
                    font:ClearAllPoints()
                    font:SetPoint("LEFT")
                    f.playerFullName = playerNameData
                    f:Enable()
                    f:SetScript("OnClick", function (self)
                        ZL.glb["rolesLgnore"][self.playerFullName] = nil
                        ZL.RolesOverViewFrame:Update()
                        LgnoreRolesFrame:Update()
                    end)
                    f:SetScript("OnEnter", function (self)
                        if self.playerFullName then
                            local __playerName, __realmName, BNChild, battleTag = strsplit(":", self.playerFullName)
                            local BNChildNewName = RolesOverView["BNChildNewName"][BNChild] or BNChild
                            GameTooltipShow(self, "Right", "LEFT", -3, 0)
                            GameTooltip:AddLine(__playerName)
                            GameTooltip:AddLine("战网昵称：|cffffffff" .. battleTag .. "|r")
                            GameTooltip:AddLine("子账号：|cffffffff" .. BNChildNewName .. "|r")
                            GameTooltip:AddLine("服务器：|cffffffff" .. __realmName .. "|r")
                            GameTooltip:AddLine(" ")
                            GameTooltip:AddLine("右键：|cffffffff恢复|r")
                            GameTooltip:Show()
                        end
                    end)
                    f:Show()
                    num = num + 1
                end
            end
            wipe(lgnoreList)
        end
        if ZL.glb["rolesDel"] and next(ZL.glb["rolesDel"]) then
            for playerFullName in pairs(ZL.glb["rolesDel"]) do
                playerName, realmName = strsplit(":", playerFullName)
                if not lgnoreList[realmName] then lgnoreList[realmName] = {} end
                lgnoreList[realmName][playerName] = playerFullName
            end
            f = LgnoreRolesFrame.entries[num]
            f:SetText(" ")
            f.playerFullName = nil
            f:Disable()
            f:Show()
            num = num + 1
            f = LgnoreRolesFrame.entries[num]
            f:SetText("|cffff8000已删除名单|r")
            font = f:GetFontString()
            font:ClearAllPoints()
            font:SetPoint("CENTER")
            f.playerFullName = nil
            f:Disable()
            f:Show()
            num = num + 1
            for realName, realNameData in pairs(lgnoreList) do
                f = LgnoreRolesFrame.entries[num]
                f:SetText(realName)
                font = f:GetFontString()
                font:ClearAllPoints()
                font:SetPoint("LEFT")
                f.playerFullName = nil
                f:Disable()
                f:Show()
                num = num + 1
                for _playerName, playerNameData in pairs(realNameData) do
                    f = LgnoreRolesFrame.entries[num]
                    f:SetText("　" .. _playerName)
                    font = f:GetFontString()
                    font:ClearAllPoints()
                    font:SetPoint("LEFT")
                    f.playerFullName = playerNameData
                    f:Enable()
                    f:SetScript("OnClick", function (self)
                        ZL.glb["rolesDel"][self.playerFullName] = nil
                        local msgStr = "已恢复" .. _playerName .. "数据传输和保存\n重新登录该角色或下次同步成功后显示"
                        print(Prefix(msgStr))
                        ZL.ScrollingMessageFrame:AddMessage(msgStr)
                        ZL.RolesOverViewFrame:Update()
                        LgnoreRolesFrame:Update()
                        ZL.SyncRoles()
                    end)
                    f:SetScript("OnEnter", function (self)
                        if self.playerFullName then
                            local __playerName, __realmName, BNChild, battleTag = strsplit(":", self.playerFullName)
                            local BNChildNewName = RolesOverView["BNChildNewName"][BNChild] or BNChild
                            GameTooltipShow(self, "Right", "LEFT", -3, 0)
                            GameTooltip:AddLine(__playerName)
                            GameTooltip:AddLine("战网昵称：|cffffffff" .. battleTag .. "|r")
                            GameTooltip:AddLine("子账号：|cffffffff" .. BNChildNewName .. "|r")
                            GameTooltip:AddLine("服务器：|cffffffff" .. __realmName .. "|r")
                            GameTooltip:AddLine(" ")
                            GameTooltip:AddLine("右键：|cffffffff恢复|r")
                            GameTooltip:Show()
                        end
                    end)
                    f:Show()
                    num = num + 1
                end
            end
            wipe(lgnoreList)
        end
        if RolesOverView["syncKey"] and next(RolesOverView["syncKey"]) then
            local battleTag, BNChild
            for _, syncAccount in pairs(RolesOverView["syncKey"]) do
                battleTag, BNChild = strsplit(":", syncAccount)
                BNChild = RolesOverView["BNChildNewName"][BNChild] or BNChild
                if not lgnoreList[battleTag] then lgnoreList[battleTag] = {} end
                lgnoreList[battleTag][BNChild] = syncAccount
            end
            f = LgnoreRolesFrame.entries[num]
            f:SetText(" ")
            f.playerFullName = nil
            f:Disable()
            f:Show()
            num = num + 1
            f = LgnoreRolesFrame.entries[num]
            f:SetText("|cffff8000已绑定子账号|r")
            font = f:GetFontString()
            font:ClearAllPoints()
            font:SetPoint("CENTER")
            f.playerFullName = nil
            f:Disable()
            f:Show()
            num = num + 1
            for _battleTag, _battleTagData in pairs(lgnoreList) do
                f = LgnoreRolesFrame.entries[num]
                f:SetText(_battleTag)
                font = f:GetFontString()
                font:ClearAllPoints()
                font:SetPoint("LEFT")
                f.playerFullName = nil
                f:Disable()
                f:Show()
                num = num + 1
                for _BNChild, BNChildData in pairs(_battleTagData) do
                    f = LgnoreRolesFrame.entries[num]
                    f:SetText("　|cffffffff" .. _BNChild .. "|r")
                    font = f:GetFontString()
                    font:ClearAllPoints()
                    font:SetPoint("LEFT")
                    f.playerFullName = BNChildData
                    f:Enable()
                    f:SetScript("OnClick", function (self)
                        StaticPopup_Show("ZL_DELETEBNCHILD", "确定解除[|cffffff00" .. _battleTag .. ":" .. _BNChild .. "|r]绑定么？解除后将删除所有数据并不再同步数据！").data = BNChildData
                    end)
                    f:SetScript("OnEnter", function (self)
                        GameTooltipShow(self, "Right", "LEFT", -3, 0)
                        GameTooltip:AddLine("<右键>  解除绑定")
                        GameTooltip:Show()
                    end)
                    f:Show()
                    num = num + 1
                end
            end
            wipe(lgnoreList)
        end
        content:SetHeight(num*20)
        LgnoreRolesFrame:SetHeight(ZL.RolesOverViewFrame:GetHeight()+5)

        lgnoreList = nil
    end
end