--------------------------------------------------------------------------------
-- File: AoUMeterEvents.lua
-- Desc: All events managed by AoUMeter
-- Mod by: Resha
--------------------------------------------------------------------------------

--==============================================================================
--=========================== EVENTS - Addon manager ===========================
--==============================================================================

--------------------------------------------------------------------------------
onEvent["SCRIPT_ADDON_INFO_REQUEST"] = function(params)
    if params.target == common.GetAddonName() then
        userMods.SendEvent("SCRIPT_ADDON_INFO_RESPONSE", {
                sender = params.target,
                desc = userMods.FromWString(GetTextLocalized("Description")),
                showDNDButton = true,
                showHideButton = true,
                showSettingsButton = true,
            })
    end
end
--------------------------------------------------------------------------------
onEvent["SCRIPT_ADDON_MEM_REQUEST"] = function(params)
    if params.target == common.GetAddonName() then
        userMods.SendEvent("SCRIPT_ADDON_MEM_RESPONSE", { sender = params.target, memUsage = gcinfo() })
    end
end
--------------------------------------------------------------------------------
onEvent["SCRIPT_SHOW_SETTINGS"] = function(params)
    if not DPSMeterGUI.MainPanel:IsVisible() then
        onReaction["ShowHideBtnReaction"]()
    end
end
--------------------------------------------------------------------------------
onEvent["SCRIPT_TOGGLE_VISIBILITY"] = function(params)
    if params.target == common.GetAddonName() then
        if params.state then
            DPSMeterGUI.ShowHideBtn:Show()
        else
            DPSMeterGUI.ShowHideBtn:Hide()
        end
    end
end
--------------------------------------------------------------------------------
onEvent["SCRIPT_TOGGLE_DND"] = function(params)
    if params.target == common.GetAddonName() then
        DPSMeterGUI.ShowHideBtn:DragNDrop(params.state)
    end
end
--------------------------------------------------------------------------------
onEvent["SCRIPT_TOGGLE_UI"] = function(params)
    mainForm:Show(params.visible)
end

--==============================================================================
--=========================== REACTIONS ========================================
--==============================================================================

--------------------------------------------------------------------------------
-- Get the index of a spell in the spell panel
--------------------------------------------------------------------------------
function GetSpellPanelIndex(reaction)
    return tonumber(string.sub(reaction.sender, 11)) or -1
end
--------------------------------------------------------------------------------
-- Get the index of a spell in the spell panel
--------------------------------------------------------------------------------
function GetPlayerPanelIndex(reaction)
    local wtParent = reaction.widget:GetParent()
    return wtParent and tonumber(string.sub(wtParent:GetName(), 12)) or -1
end
--------------------------------------------------------------------------------
-- occurred when the player point a spell in the spell panel
--------------------------------------------------------------------------------
onReaction["SpellPanelOnPointing"] = function (reaction)
    DPSMeterGUI:HideAllSpellDetailsPanel()
    
    if reaction.active then
        DPSMeterGUI.DetailsPanel.SpellDetailsHeader:Show()
        DPSMeterGUI:UpdateSpellDetailsList(GetSpellPanelIndex(reaction))
    else
        DPSMeterGUI.DetailsPanel.SpellDetailsHeader:Hide()
    end
end
--------------------------------------------------------------------------------
-- occurred when the player press the reset button
--------------------------------------------------------------------------------
onReaction["ResetBtnReaction"] = function(reaction)
    onEvent["EVENT_GROUP_DISAPPEARED"]()
    onEvent["EVENT_GROUP_CHANGED"]()
end
--------------------------------------------------------------------------------
-- occurred when the player press the close button in the main panel
--------------------------------------------------------------------------------
onReaction["CloseMainPanelBtnReaction"] = function(reaction)
    DPSMeterGUI.MainPanel:Hide()
    DPSMeterGUI.DetailsPanel:Hide()
end
--------------------------------------------------------------------------------
-- occurred when the player click a player in the player list
--------------------------------------------------------------------------------
onReaction["PlayerInfoButtonDown"] = function(reaction) 
    local playerIndex = GetPlayerPanelIndex(reaction)
    if playerIndex then
        local activeFight = DPSMeterGUI:GetActiveFight()
        local playerName = activeFight:GetCombatantNameByIndex(playerIndex)
        if playerName then
            DPSMeterGUI:SetSelectedCombatantByName(playerName)
            DPSMeterGUI.DetailsPanel:Show()
            DPSMeterGUI:UpdateValues()
        end
    end
end
--------------------------------------------------------------------------------
-- occurred when the player press the close button of the spell panel
--------------------------------------------------------------------------------
onReaction["CloseSpellInfoPanelBtnReaction"] = function(reaction)
    DPSMeterGUI.DetailsPanel:Hide()
end
--------------------------------------------------------------------------------
-- occurred when the player click on the fight dropdown button in the main panel
--------------------------------------------------------------------------------
onReaction["GetFightBtnReaction"] = function(reaction)
    DPSMeterGUI:SwapFight()
end
--------------------------------------------------------------------------------
-- occurred when the player click on the mode dropdown button in the main panel
--------------------------------------------------------------------------------
onReaction["GetModeBtnReaction"] = function(reaction)
    DPSMeterGUI:SwapMode()
end
--------------------------------------------------------------------------------
-- occurred when the player click on the "D" button in order to show or hide the main panel
--------------------------------------------------------------------------------
onReaction["ShowHideBtnReaction"] = function(reaction)
    if DnD:IsDragging() then return end
    if DPSMeterGUI.MainPanel:IsVisible() then
        DPSMeterGUI.MainPanel:Hide()
        DPSMeterGUI.DetailsPanel:Hide()
    else
        DPSMeterGUI.MainPanel:Show()
        if avatar.IsExist() then
            DPSMeterGUI:UpdateValues()
        end
    end
end

--==============================================================================
--=========================== EVENTS ===========================================
--==============================================================================

--------------------------------------------------------------------------------
-- Event: EVENT_GROUP_CHANGED
--------------------------------------------------------------------------------
onEvent["EVENT_GROUP_CHANGED"] = function(params)
    if group.GetMembers() or raid.IsExist() then
        
        local partyMembersInfoList = DPSMeterGUI.DPSMeter:GetPartyMembers()
        
        for i, member in partyMembersInfoList do
            if not DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Current):GetCombatantByName(member.name) then
                DPSMeterGUI.DPSMeter:AddNewCombatantByName(member.name)
            end
            
            DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Current):GetCombatantByName(member.name):UpdateCombatantDataByID(member.id)
            DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Total):GetCombatantByName(member.name):UpdateCombatantDataByID(member.id)
        end
        
        if raid.IsExist() then
            for i, combatant in DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Current).CombatantsList do
                local bInvalid = true
                if IsThisStringValue (combatant.Name, object.GetName(avatar.GetId())) then
                    bInvalid = false
                else
                    for j, member in partyMembersInfoList do
                        if IsThisStringValue (combatant.Name, member.name) then
                            bInvalid = false
                            break
                        end
                    end
                end
                if bInvalid then
                    DPSMeterGUI.DPSMeter:RemoveCombatantByName(combatant.Name)
                end
            end
        end
    end
    
    DPSMeterGUI:UpdateValues()
end
--------------------------------------------------------------------------------
-- Event: EVENT_RAID_CHANGED = EVENT_GROUP_CHANGED
--------------------------------------------------------------------------------
onEvent["EVENT_RAID_CHANGED"] = onEvent["EVENT_GROUP_CHANGED"]
--------------------------------------------------------------------------------
-- Event: EVENT_RAID_MEMBER_STATUS_CHANGED
--------------------------------------------------------------------------------
onEvent["EVENT_RAID_MEMBER_STATUS_CHANGED"] = function(params)
    if group.GetLeaderIndex() ~= -1 then
        local partyMembersInfoList = DPSMeterGUI.DPSMeter:GetPartyMembers()
        for i, member in partyMembersInfoList do
            if member.id then
                local combatant
                combatant = DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Current):GetCombatantByName(member.name)
                if combatant then combatant:UpdateCombatantDataByID(member.id) end
                
                combatant = DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Total):GetCombatantByName(member.name)
                if combatant then combatant:UpdateCombatantDataByID(member.id) end
            end
        end	
    end
end
--------------------------------------------------------------------------------
-- Event: EVENT_GROUP_MEMBER_STATUS_CHANGED = EVENT_RAID_MEMBER_STATUS_CHANGED
--------------------------------------------------------------------------------
onEvent["EVENT_GROUP_MEMBER_STATUS_CHANGED"] = onEvent["EVENT_RAID_MEMBER_STATUS_CHANGED"]
--------------------------------------------------------------------------------
-- Event: EVENT_GROUP_DISAPPEARED
--------------------------------------------------------------------------------
onEvent["EVENT_GROUP_DISAPPEARED"] = function()
    -- Keep track of previous fights
    local prevTotalFight = DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Total)
    local prevPrevFight = DPSMeterGUI.DPSMeter:GetFight(DPSMeterGUI.DPSMeter.Fight.Previous)
    
    -- Reset
    DPSMeterGUI.DPSMeter:ResetAllFights()
    DPSMeterGUI.ActiveFight = DPSMeterGUI.DPSMeter.Fight.Current
    
    -- Restore previous fights
    if prevTotalFight.Data[enumMode.Dps].Amount > 0 then
        DPSMeterGUI.DPSMeter.FightsList[DPSMeterGUI.DPSMeter.Fight.Previous] = prevTotalFight
    else
        DPSMeterGUI.DPSMeter.FightsList[DPSMeterGUI.DPSMeter.Fight.Previous] = prevPrevFight
    end
    
    DPSMeterGUI.DPSMeter:AddNewCombatantByID(avatar.GetId())
    DPSMeterGUI:SetSelectedCombatantByName(object.GetName(avatar.GetId()))
    DPSMeterGUI:UpdateValues()
end
--------------------------------------------------------------------------------
-- Event: EVENT_RAID_DISAPPEARED = EVENT_GROUP_DISAPPEARED
--------------------------------------------------------------------------------
onEvent["EVENT_RAID_DISAPPEARED"] = onEvent["EVENT_GROUP_DISAPPEARED"]
--------------------------------------------------------------------------------
-- Event: EVENT_GROUP_MEMBER_REMOVED
--------------------------------------------------------------------------------
onEvent["EVENT_GROUP_MEMBER_REMOVED"] = function(params)
    DPSMeterGUI.DPSMeter:RemoveCombatantByName(params.name)
    if DPSMeterGUI.SelectedCombatantName == params.name then
        DPSMeterGUI:SetSelectedCombatantByName(object.GetName(avatar.GetId()))
    end
    DPSMeterGUI:UpdateValues()
end
--------------------------------------------------------------------------------
-- Event: EVENT_SECOND_TIMER
--------------------------------------------------------------------------------
onEvent["EVENT_SECOND_TIMER"] = function(params)
    if not avatar.IsExist() then return end
    
    if DPSMeterGUI.DPSMeter.bCollectData then
        if object.IsInCombat(avatar.GetId()) then
            DPSMeterGUI.DPSMeter:UpdateFightsTime()
        elseif DPSMeterGUI.DPSMeter:UpdateOffBattleTime() > Settings["MaxOffBattleTime"] then
            DPSMeterGUI.DPSMeter:Stop()
        end

        DPSMeterGUI:UpdateValues()
    end
end
--------------------------------------------------------------------------------
-- Event: EVENT_UNIT_DAMAGE_RECEIVED
--------------------------------------------------------------------------------
onEvent["EVENT_UNIT_DAMAGE_RECEIVED"] = function(params)
    if not params then return end
    
    DPSMeterGUI.DPSMeter:CollectDamageData(params)
    
    if DPSMeterGUI:GetActiveFight():GetCombatantCount() <= Settings["HeavyMode_MaxCombatant"] then
        DPSMeterGUI:UpdateValues()
    end
end
--------------------------------------------------------------------------------
-- Event: EVENT_HEALING_RECEIVED
onEvent["EVENT_HEALING_RECEIVED"] = function(params)
    if not params then return end
    
    DPSMeterGUI.DPSMeter:CollectHealData(params)
end 
--------------------------------------------------------------------------------
-- Event: EVENT_AVATAR_CREATED
--------------------------------------------------------------------------------
onEvent["EVENT_AVATAR_CREATED"] = function(params)
    -- Since AO 2.0.03, localization must be applied here
    localization = GetGameLocalization()
    if not common.GetAddonRelatedTextGroup(localization) then
        localization = "eng"
    end
    
    onEvent["SCRIPT_ADDON_INFO_REQUEST"]({ target = common.GetAddonName() })
    
    -- Initialize localizations
    StrPet = userMods.FromWString(GetTextLocalized("Pet"))
    
    TitleMode[enumMode.Dps] = GetTextLocalized("DPS")
    TitleMode[enumMode.Hps] = GetTextLocalized("HPS")
    TitleMode[enumMode.Def] = GetTextLocalized("DEF")
    
    TitleFight[enumFight.Previous] = GetTextLocalized("Previous")
    TitleFight[enumFight.Current] = GetTextLocalized("Current")
    TitleFight[enumFight.Total] = GetTextLocalized("Overall")
    
    TitleDmgType[enumHit.Normal] = GetTextLocalized("Normal")
    TitleDmgType[enumHit.Critical] = GetTextLocalized("Critical")
    TitleDmgType[enumHit.Glancing] = GetTextLocalized("Glancing")
    
    TitleMissType[enumMiss.Dodge] = GetTextLocalized("Dodge")
    TitleMissType[enumMiss.Miss] = GetTextLocalized("Miss")
    
    TitleHitBlockType[enumHitBlock.Block] = GetTextLocalized("Blocked")
    TitleHitBlockType[enumHitBlock.Parry] = GetTextLocalized("Parry")
    TitleHitBlockType[enumHitBlock.Barrier] = GetTextLocalized("Barrier")
    TitleHitBlockType[enumHitBlock.Resist] = GetTextLocalized("Resisted")
    TitleHitBlockType[enumHitBlock.Absorb] = GetTextLocalized("Absorbed")
    TitleHitBlockType[enumHitBlock.RunesAbsorb] = GetTextLocalized("Rune")
    TitleHitBlockType[enumHitBlock.MultAbsorb] = GetTextLocalized("Multiplier")
    TitleHitBlockType[enumHitBlock.Mount] = GetTextLocalized("Mount")
    
    TitleHealResistType[enumHealResist.Resisted] = GetTextLocalized("Resisted")
    TitleHealResistType[enumHealResist.RuneResisted] = GetTextLocalized("Rune")
    TitleHealResistType[enumHealResist.Absorbed] = GetTextLocalized("Absorbed")
    TitleHealResistType[enumHealResist.Overload] = GetTextLocalized("Overload")
    
    TitleExtraInfoType[enumExtraInfo.Lethality] = GetTextLocalized("Lethality")
    
    DPSMeterGUI.DetailsPanel.SpellHeaderNameText:SetVal("Name", GetTextLocalized("Ability"))
    DPSMeterGUI.DetailsPanel.SpellHeaderStatsText:SetVal("DamageDone", GetTextLocalized("Dmg"))
    DPSMeterGUI.DetailsPanel.SpellHeaderStatsText:SetVal("Absorbed", GetTextLocalized("Abs"))
    DPSMeterGUI.DetailsPanel.SpellDetailsHeaderNameText:SetVal("Name", GetTextLocalized("Type"))
    DPSMeterGUI.DetailsPanel.SpellDetailsHeaderStatsText:SetVal("Min", GetTextLocalized("Min"))
    DPSMeterGUI.DetailsPanel.SpellDetailsHeaderStatsText:SetVal("Avg", GetTextLocalized("Avg"))
    DPSMeterGUI.DetailsPanel.SpellDetailsHeaderStatsText:SetVal("Max", GetTextLocalized("Max"))
    
    -- If wider main panel, then extend the width...
    if Settings["MainPanelWidth"] == enumWidth.Auto and localization == "rus" or Settings["MainPanelWidth"] == enumWidth.Wide then
        local newWidth = Settings["MainPanelWideSize"]
        
        if newWidth > DPSMeterGUI.MainPanelWidth then
            local deltaWidth = newWidth - DPSMeterGUI.MainPanelWidth
            DPSMeterGUI.BarWidth = DPSMeterGUI.BarWidth + deltaWidth
            local delta13 = math.floor(deltaWidth * 1/3)
            local delta23 = math.floor(deltaWidth * 2/3)
            
            DPSMeterGUI.MainPanel:SetWidth(DPSMeterGUI.InitialSize["MainPanelWidth"] + deltaWidth)
            DPSMeterGUI.MainPanel.FightBtn:SetWidth(DPSMeterGUI.InitialSize["FightBtnWidth"] + delta23)
            DPSMeterGUI.MainPanel.ModeBtn:SetWidth(DPSMeterGUI.InitialSize["ModeBtnWidth"] + delta13)
            DPSMeterGUI.MainPanel.FightBtn:SetPosition(DPSMeterGUI.InitialSize["FightBtnPosX"] + delta13, nil)
            DPSMeterGUI.MainPanel.TotalPanel:SetWidth(DPSMeterGUI.InitialSize["TotalPanelWidth"] + deltaWidth)
            
            for playerIndex = 1, Settings["MaxCombatants"] do
                DPSMeterGUI.MainPanel.PlayerList[playerIndex]:SetWidth(DPSMeterGUI.InitialSize["TotalPanelWidth"] + deltaWidth)
            end
        end
        
    end
    
    -- Update the mode in the fight panel (at the top of the player list)
    DPSMeterGUI.MainPanel.ModeText:SetVal("Name", TitleMode[DPSMeterGUI.ActiveMode])
    
    -- Update the mode in the title of the spell panel
    DPSMeterGUI.DetailsPanel.PlayerNameText:SetVal("Mode", TitleMode[DPSMeterGUI.ActiveMode])
    
    -- Update the mode in the header of the spell panel
    DPSMeterGUI.DetailsPanel.SpellHeaderStatsText:SetVal("DPS", TitleMode[DPSMeterGUI.ActiveMode])
    
    -- DPSMeterGUI.DPSMeter.Fight.x indices can change during the execution
    local title = {
        [DPSMeterGUI.DPSMeter.Fight.Previous] = TitleFight[enumFight.Previous],
        [DPSMeterGUI.DPSMeter.Fight.Current] = TitleFight[enumFight.Current],
        [DPSMeterGUI.DPSMeter.Fight.Total] = TitleFight[enumFight.Total]
    }
    
    -- Update the fight in the fight panel (at the top of the player list)
    DPSMeterGUI.MainPanel.FightText:SetVal("Name", title[DPSMeterGUI.ActiveFight])
    
    -- Update the fight in the title of the spell panel
    DPSMeterGUI.DetailsPanel.PlayerNameText:SetVal("Fight", title[DPSMeterGUI.ActiveFight])
    
    DPSMeterGUI.DPSMeter:AddNewCombatantByID(avatar.GetId())
    DPSMeterGUI:SetSelectedCombatantByName(object.GetName(avatar.GetId()))
    
    DPSMeterGUI:UpdateValues()
end
