-- grab ftc from global
FTC = _G['FTC']

--[[
 * Handles Combat Events
 * --------------------------------
 * Called by EVENT_COMBAT_EVENT
 * --------------------------------
 *
 * Update for PanicModeCombatAnalyzer: Only added abilityId to function call
 *
 ]]--
function FTC.OnCombatEvent( eventCode , result , isError , abilityName , abilityGraphic , abilityActionSlotType , sourceName , sourceType , targetName , targetType , hitValue , powerType , damageType , log , sourceUnitId , targetUnitId , abilityId )

    -- Ignore errors
    if ( isError ) then return end

    -- Pass damage event to handler
    FTC.Damage:New( result , abilityName , abilityGraphic , abilityActionSlotType , sourceName , sourceType , targetName , targetType , hitValue , powerType , damageType, abilityId )
end



--[[
 * Validate and Process New Damages
 * --------------------------------
 * Called by FTC:OnCombatEvent()
 * --------------------------------
 *
 * Update for PanicModeCombatAnalyzer: Only added abilityId to damage object
 *
 ]]--
function FTC.Damage:New( result , abilityName , abilityGraphic , abilityActionSlotType , sourceName , sourceType , targetName , targetType , hitValue , powerType , damageType, abilityId )

    -- Determine context
    local target = zo_strformat("<<!aC:1>>",targetName)
    local player = zo_strformat("<<!aC:1>>",FTC.Player.name)
    local damageOut = false
    if ( sourceType == COMBAT_UNIT_TYPE_PLAYER or sourceType == COMBAT_UNIT_TYPE_PLAYER_PET ) then damageOut = true
    elseif ( target == player ) then damageOut = false
    else return end

    -- Debugging
    --d( result .. " || " .. sourceType .. " || " .. sourceName .. " || " .. targetName .. " || " .. abilityName .. " || " .. hitValue  )

    -- Reflag self-targetted as incoming
    if ( damageOut and ( target == player ) ) then damageOut = false end

    -- Ignore certain results
    if ( FTC.Damage:Filter( result , abilityName ) ) then return end

    -- Compute some flags
    local isCrit    = result == ACTION_RESULT_CRITICAL_DAMAGE or result == ACTION_RESULT_CRITICAL_HEAL or result == ACTION_RESULT_DOT_TICK_CRITICAL or result == ACTION_RESULT_HOT_TICK_CRITICAL
    local isHeal    = result == ACTION_RESULT_HEAL or result == ACTION_RESULT_CRITICAL_HEAL or result == ACTION_RESULT_HOT_TICK or result == ACTION_RESULT_HOT_TICK_CRITICAL

    -- Get the icon
    local icon = FTC.UI.Textures[abilityName] or '/esoui/art/icons/death_recap_ranged_basic.dds'
    if ( abilityName == "" and ( not damageOut ) and isHeal ) then icon = '/esoui/art/icons/ability_healer_017.dds'
    elseif ( abilityName == "" and not damageOut ) then icon = '/esoui/art/icons/death_recap_ranged_heavy.dds' end

    -- Setup the damage object
    local damage    = {
        ["out"]     = damageOut,
        ["result"]  = result,
        ["target"]  = targetName,
        ["source"]  = sourceName,
        ["ability"] = abilityName,
        ["type"]    = damageType,
        ["value"]   = hitValue,
        ["power"]   = powerType,
        ["ms"]      = GetGameTimeMilliseconds(),
        ["crit"]    = isCrit,
        ["heal"]    = isHeal,
        ["icon"]    = icon,
        ["mult"]    = 1,
        ["weapon"]  = FTC.Damage:IsWeaponAttack(abilityName),
        -- added by PanicModeCombatAnalyzer for better usage
        ["abilityId"] = abilityId
    }

    -- ACTION_RESULT_IMMUNE
    -- ACTION_RESULT_BLOCKED
    -- ACTION_RESULT_POWER_DRAIN
    -- ACTION_RESULT_POWER_ENERGIZE

    -- Damage Dealt
    if ( hitValue > 0 and ( result == ACTION_RESULT_DAMAGE or result == ACTION_RESULT_CRITICAL_DAMAGE or result == ACTION_RESULT_BLOCKED_DAMAGE or result == ACTION_RESULT_DOT_TICK or result == ACTION_RESULT_DOT_TICK_CRITICAL ) ) then

        -- Flag timestamps
        if ( damageOut ) then FTC.Damage.lastOut = GetGameTimeMilliseconds()
        else FTC.Damage.lastIn  = GetGameTimeMilliseconds() end

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end
        if ( FTC.init.SCT ) then FTC.SCT:Damage(damage) end

        -- Statistics
        if ( FTC.init.Stats and damageOut ) then FTC.Stats:RegisterDamage(damage) end

        -- Trigger Ulti Buff
        if ( FTC.init.Hotbar ) then FTC.Hotbar:UltimateBuff(damage) end

        -- Falling damage
    elseif ( result == ACTION_RESULT_FALL_DAMAGE ) then
        damage.ability  = GetString(FTC_Falling)
        damage.icon     = '/esoui/art/icons/death_recap_fall_damage.dds'

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end
        if ( FTC.init.SCT ) then FTC.SCT:Damage(damage) end

        -- Shielded Damage
    elseif ( result == ACTION_RESULT_DAMAGE_SHIELDED ) then

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end
        if ( FTC.init.SCT ) then FTC.SCT:Damage(damage) end

        -- Statistics
        if ( FTC.init.Stats and damageOut ) then FTC.Stats:RegisterDamage(damage) end

        -- Misses and  Dodges
    elseif ( result == ACTION_RESULT_DODGED or result == ACTION_RESULT_MISS ) then

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end
        if ( FTC.init.SCT ) then FTC.SCT:Damage(damage) end

        -- Crowd Controls
    elseif ( result == ACTION_RESULT_INTERRUPT or result == ACTION_RESULT_STUNNED or result == ACTION_RESULT_OFFBALANCE or result == ACTION_RESULT_DISORIENTED or result == ACTION_RESULT_STAGGERED or result == ACTION_RESULT_FEARED or result == ACTION_RESULT_SILENCED or result == ACTION_RESULT_ROOTED ) then

        -- Trigger Break Free buff
        if ( FTC.init.Buffs and damage.ability == GetAbilityName(16565) ) then
            local ability  = {
                ["owner"]  = FTC.Player.name,
                ["id"]     = 16565,
                ["name"]   = GetString(FTC_BreakFree),
                ["dur"]    = 8000,
                ["icon"]   = FTC.UI.Textures[GetAbilityName(16565)],
                ["ground"] = false,
                ["area"]   = false,
                ["debuff"] = false,
                ["toggle"] = nil,
            }
            FTC.Buffs:NewEffect( ability , "Player" )
        end

        -- Fire SCT Alert
        if ( FTC.init.SCT ) then FTC.SCT:NewCC( result , abilityName , damageOut ) end

        -- Healing Dealt
    elseif ( hitValue > 0 and ( result == ACTION_RESULT_HEAL or result == ACTION_RESULT_CRITICAL_HEAL or result == ACTION_RESULT_HOT_TICK or result == ACTION_RESULT_HOT_TICK_CRITICAL ) ) then

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end
        if ( FTC.init.SCT ) then FTC.SCT:Damage(damage) end

        -- Statistics
        if ( FTC.init.Stats and sourceType == COMBAT_UNIT_TYPE_PLAYER ) then FTC.Stats:RegisterDamage(damage) end

        -- Target Death
    elseif ( result == ACTION_RESULD_DIED or result == ACTION_RESULT_DIED_XP ) then

        -- Wipe Buffs
        if ( FTC.init.Buffs ) then FTC.Buffs:WipeBuffs(targetName) end

        -- Log and SCT
        if ( FTC.init.Log ) then FTC.Log:CombatEvent(damage) end

        -- DEBUG NEW EVENTS
    elseif ( hitValue > 0 ) then

        -- Prompt other unrecognized
        --local direction = damageIn and "Incoming" or "Outgoing"
        -- FTC.Log:Print( direction .. " result " .. result .. " not recognized! Target: " .. targetName .. " Value: " .. hitValue , {1,1,0} )
    end

    -- Fire a callback for extensions to use
    CALLBACK_MANAGER:FireCallbacks( "FTC_NewDamage" , damage )
end