PmCa = PmCa or {}
PmCa.Damage = {}

--Initialize Damage Management
function PmCa.Damage:Initialize()

    -- Set up initial timestamps
    PmCa.Damage.lastIn = 0
    PmCa.Damage.lastOut = 0
end

--Validate and Process New Damages
function PmCa.Damage:New(result, abilityName, sourceType, targetName, hitValue, abilityId)
    local self = PmCa

    -- if we have no target, then return
    local target = zo_strformat("<<!aC:1>>", targetName)
    if target == '' then return end

    local player = zo_strformat("<<!aC:1>>", GetUnitName('player'))
    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

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

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

    -- we only want outgoing stuff and values > 0
    if damageOut == false or hitValue <= 0 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
    local isDamage = result == ACTION_RESULT_DAMAGE or result == ACTION_RESULT_CRITICAL_DAMAGE or result == ACTION_RESULT_DOT_TICK or result == ACTION_RESULT_DOT_TICK_CRITICAL

    --only log outgoing stuff and greater than zero

    local data         = self.savedVariables.data or {}
    local lastSave     = self.tempVars.lastSave
    local lastSaveTS   = self.tempVars.lastSaveTimeStamp
    local currentTime  = GetGameTimeMilliseconds()
    local timeStamp    = GetTimeStamp() + self.tempVars.timeStampOffsetToLead
    local lastSaveDiff = currentTime - lastSave

    -- if the last saving data is 1 sek ago, make a new table
    if lastSaveDiff >= 1000 then
        lastSaveTS = timeStamp
        self.tempVars.lastSaveTimeStamp = timeStamp
        self.tempVars.lastSave          = currentTime
    end

    data[lastSaveTS]            = data[lastSaveTS] or {}

    local savingData = {
        abilityId = abilityId,
        value     = hitValue,
        crit      = isCrit,
--            ms        = GetGameTimeMilliseconds(),
    }

    local arrayString = 'damage'
    if isHeal then
        arrayString = 'healing'
    end
    data[lastSaveTS][arrayString]         = data[lastSaveTS][arrayString] or {}
    data[lastSaveTS][arrayString][target] = data[lastSaveTS][arrayString][target] or {}
    table.insert(data[lastSaveTS][arrayString][target], savingData)

    -- only store, when we have damage or healing
    if #data[lastSaveTS][arrayString][target] > 1 then
        if self.getTrial() > 0 then
            data[lastSaveTS]['trial'] = self.getTrial()
        end
        if GetGroupSize() > 0 then
            data[lastSaveTS]['group'] = self.getGroupEnc()
        end

        self.savedVariables.data[lastSaveTS] = data[lastSaveTS]
    end
end


--[[----------------------------------------------------------
    HELPER FUNCTIONS
 ]] -----------------------------------------------------------

--[[
 * Filter Out Unwanted Combat Events
 * --------------------------------
 * Called by PmCa.Damage:New()
 * --------------------------------
 ]] --
function PmCa.Damage:Filter(result, abilityName)

    -- Keep a list of ignored actions
    local results = {
        ACTION_RESULT_QUEUED,
    }

    -- Check actions
    for i = 1, #results do
        if (result == results[i]) then return true end
    end

    -- Keep a list of ignored abilities
    local abilities = {
        31221, -- Skyshard Collect
        36010, -- Mount Up
        41467, -- Regeneration Dummy
        57466, -- Rapid Regeneration Dummy
        57468, -- Mutagen Dummy
    }
    for i = 1, #abilities do
        if (abilityName == GetAbilityName(abilities[i])) then return true end
    end
end

--[[
 * Track Whether a Damage Source is a Weapon ATtack
 * --------------------------------
 * Called by PmCa.Damage:New()
 * --------------------------------
 ]] --
function PmCa.Damage:IsWeaponAttack(abilityName)

    local attacks = {
        4858, -- Bash
        7880, -- Light Attack
        7095, -- Heavy Attack
        16420, -- Heavy Attack (Dual Wield)
        16691, -- Heavy Attack (Bow)
        32480, -- Heavy Attack Werewolf
    }

    -- Compare each ability with the damage name
    for i = 1, #attacks do
        local name = GetAbilityName(attacks[i])
        if (abilityName == name) then return true end
    end
end