--[[
  * CyrHUD.Battle class
  * Author: Sasky
  * Contains all information about a conflict
]]--

if CyrHUD == nil then
    --noinspection GlobalCreationOutsideO
    CyrHUD = {}
end

-- Setup class
CyrHUD.Battle = {}
CyrHUD.Battle.__index = CyrHUD.Battle
setmetatable(CyrHUD.Battle, {
    __call = function (cls, ...)
        return cls.new(...)
    end,
})

----------------------------------------------
-- Creation
----------------------------------------------
CyrHUD.Battle.new = function(keepID)
    local self = setmetatable({}, CyrHUD.Battle)
    self.startBattle = GetTimeStamp()
    self.endBattle = nil
    self.keepID = keepID
    self.keepName = GetKeepName(keepID)
    self.keepType = GetKeepType(keepID)
    if self.keepType == KEEPTYPE_RESOURCE then
        self.keepType = 10 + GetKeepResourceType(keepID)
        local name = self.keepName:gsub("Castle ","")
        name = name:gsub("Fort ","")
        name = name:gsub("Keep ","")
        name = name:gsub("Lumber ","")
        self.keepName = name
    end
    self.siege = {}
    self:update()
    return self
end

function CyrHUD.Battle:update()
    local _, bc = GetKeepKeysByIndex(10)
    self.defender = GetKeepAlliance(self.keepID, bc)
    self.keepUA = GetKeepUnderAttack(self.keepID, bc)
    self.siege[ALLIANCE_ALDMERI_DOMINION] = GetNumSieges(self.keepID, bc, ALLIANCE_ALDMERI_DOMINION)
    self.siege[ALLIANCE_DAGGERFALL_COVENANT] = GetNumSieges(self.keepID, bc, ALLIANCE_DAGGERFALL_COVENANT)
    self.siege[ALLIANCE_EBONHEART_PACT] = GetNumSieges(self.keepID, bc, ALLIANCE_EBONHEART_PACT)

    if not self:isBattle() then
        if self.endBattle then
            --Remove after time
            if GetDiffBetweenTimeStamps(GetTimeStamp(), self.endBattle) > 15 then
                CyrHUD.battles[self.keepID] = nil
            end
        else
            self.endBattle = GetTimeStamp()
        end
    end
end

function CyrHUD.Battle:restart()
    self.endBattle = nil
end

----------------------------------------------
-- Getters
----------------------------------------------

--[[
    @return red, green, blue, alpha for background color
        all in range [0,1]
--]]
function CyrHUD.Battle:getBGColor()
    if self.endBattle then
        if self.defender == GetUnitAlliance("player") then
            return .2,.5,.2,.6
        end
        return .5,.5,.5,.3
    end
    local delta = GetDiffBetweenTimeStamps(GetTimeStamp(), self.startBattle)
    if delta < 60 then
        return (60-delta)/120,0,0,.3
    end

    return 0,0,0,.3
end

--[[
    @return elapsed time of battle event
        if an end is specified, will show total lenth
        otherwise will show current length
--]]
function CyrHUD.Battle:getDuration()
    local time = self.endBattle or GetTimeStamp()
    local delta = GetDiffBetweenTimeStamps(time, self.startBattle)
    local out = CyrHUD.formatTime(delta)
    return out
end

--[[
    @return numSiege, color
        numSiege - number of defending siege equipment
        color - color for the defending faction
]]
function CyrHUD.Battle:getDefSiege()
    local siege = self.siege[self.defender]
    if siege == 0 then siege = "" end
    return siege, CyrHUD.info[self.defender].color
end

--[[
    @return numSiege, color
        numSiege - number of defending siege equipment
        color - color for the defending faction
    @note If two attacking factions, will sum the siege and show white for color
]]
function CyrHUD.Battle:getAttSiege()
    local count, faction = 0, nil
    for f,c in pairs(self.siege) do
        if f ~= self.defender and c > 0 then
            count = count + c
            if faction == nil then
                faction = f
            else
                faction = 0
            end
        end
    end
    local color = { hex = "CCCCCC", r=.8, g=.8, b=.8 }
    if faction and faction ~= 0 then
        color = CyrHUD.info[faction].color
    end
    if count == 0 then count = "" end
    return count, color
end

--[[
    @return true iff battle is active
        a) keep is under attack status
        b) there is siege setup at keep
--]]
function CyrHUD.Battle:isBattle()
    if self.keepUA then return true end
    local count = (self.siege[ALLIANCE_ALDMERI_DOMINION] + self.siege[ALLIANCE_DAGGERFALL_COVENANT] + self.siege[ALLIANCE_EBONHEART_PACT])
    return count > 0
end

--[[
    @return icon for battle
        icon is based on resource type, faction, and whether it is under attack
    @see CyrHUD.info
]]
function CyrHUD.Battle:getIcon()
    return CyrHUD.info[self.defender][self.keepType]
end