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

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

local function n0(val) if val == nil then return 0 end return val end

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

local shortenResourceName = function(str)
    return str:gsub("%^.d$", "")
        :gsub("Castle ","")
        :gsub("[fF]ort ","")
        :gsub("Keep ","")
        :gsub("Lumber ","")
        :gsub("Feste ","")
        :gsub("Kastell ","")
        :gsub("Burg ","")
        :gsub("Holz.+lager", "")

end

local shortenKeepName = function(str)
    return str:gsub(",..$", ""):gsub("%^.d$", "")
    --FR
        :gsub("avant.poste d[eu] ", "")
        :gsub("bastille d[eu]s? ", "")
        :gsub("fort de la ", "")
end


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

function CyrHUD.Battle:update()
    self.defender = GetKeepAlliance(self.keepID, CyrHUD.battleContext)
    self.keepUA = GetKeepUnderAttack(self.keepID, CyrHUD.battleContext)
    self.siege[ALLIANCE_ALDMERI_DOMINION] = GetNumSieges(self.keepID, CyrHUD.battleContext, ALLIANCE_ALDMERI_DOMINION)
    self.siege[ALLIANCE_DAGGERFALL_COVENANT] = GetNumSieges(self.keepID, CyrHUD.battleContext, ALLIANCE_DAGGERFALL_COVENANT)
    self.siege[ALLIANCE_EBONHEART_PACT] = GetNumSieges(self.keepID, CyrHUD.battleContext, 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
        if not self.keepUA and n0(self.siege[self.defender]) > 0 then
            count = "?"
        else
            count = ""
        end
    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()
    if CyrHUD.info[self.defender] == nil then
        return CyrHUD.info.noIcon
    end

    --Debug code
    if CyrHUD.info[self.defender] == nil or CyrHUD.info[self.defender][self.keepType] == nil then
        CyrHUD.error("Bad icon lookup. Defender: " .. self.defender .. " / KeepType: " .. self.keepType)
        return CyrHUD.info.noIcon
    end

    return CyrHUD.info[self.defender][self.keepType]
end