--[[
  * CyrHUD
  * Author: Sasky
]]--

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

----------------------------------------------
-- Utility
----------------------------------------------
function bl(val)
	if val == nil then return "NIL" elseif val then return "T" else return "F" end
end

function nn(val)
    if val == nil then return "NIL" end
    return val
end

function CyrHUD.formatTime(delta, inclueSec)
    local sec = delta % 60
    delta = (delta - sec) / 60
    local min = delta % 60
    local out = min .. "m"

    if inclueSec then
        out = out .. " " .. sec .. "s"
    end
    return out
end

CyrHUD.errors = {}
CyrHUD.error = function(val)
    if not CyrHUD.errors[val] then
        CyrHUD.errors[val] = 1
        d("|cFF0000ERROR (CyrHUD): " .. val .. " / Please file this bug info at esoui.com")
    end
end

----------------------------------------------
-- Score
----------------------------------------------
function CyrHUD.updateScore()
    local cID = GetCurrentCampaignId()
    local time = CyrHUD.formatTime(GetSecondsUntilCampaignScoreReevaluation(cID), true)
    CyrHUD_UI_Time:SetText(time)
    CyrHUD_UI_AD:SetText("+" .. GetCampaignAlliancePotentialScore(cID, ALLIANCE_ALDMERI_DOMINION))
    CyrHUD_UI_DC:SetText("+" .. GetCampaignAlliancePotentialScore(cID, ALLIANCE_DAGGERFALL_COVENANT))
    CyrHUD_UI_EP:SetText("+" ..  GetCampaignAlliancePotentialScore(cID, ALLIANCE_EBONHEART_PACT))
end

----------------------------------------------
-- Events
----------------------------------------------
function CyrHUD.eventAttackChange(_, keepID, battlegroundContext, underAttack)
    if underAttack then
        CyrHUD.add(keepID)
    elseif CyrHUD.battles[keepID] ~= nil then
        CyrHUD.battles[keepID]:update()
    end
end

function CyrHUD.saveWindowPosition( window )
    _, _, _, _, x, y = window:GetAnchor()
    CyrHUD.cfg.xoff = x
    CyrHUD.cfg.yoff = y
end


----------------------------------------------
-- Notification UI pool
----------------------------------------------
CyrHUD.entryCount = 0
CyrHUD.entries = {}
CyrHUD.createEntry = function()
    local num = CyrHUD.entryCount + 1
    local yoff = num*35-5
    CyrHUD.entryCount = num
    local entry = {}
    local entryName = "CyrHUDEntry" .. num
    entry.main = WINDOW_MANAGER:CreateControl(entryName .. "main", CyrHUD_UI, CT_BACKDROP)
    entry.main:SetDimensions(280, 35)
    entry.main:SetAnchor(TOPLEFT, CyrHUD_UI, TOPLEFT, 0, yoff)
    entry.main:SetCenterColor( 0, 0, 0, .3 )
    entry.main:SetEdgeColor( 0, 0, 0, 0 )

    entry.icon = WINDOW_MANAGER:CreateControl(entryName .. "icon", entry.main, CT_TEXTURE)
    entry.icon:SetAnchor(TOPLEFT, entry.main, TOPLEFT, -2, -2)
    entry.icon:SetDimensions(40,40)
    entry.icon:SetDrawLayer(2)

    entry.ua = WINDOW_MANAGER:CreateControl(entryName .. "ua", entry.main, CT_TEXTURE)
    entry.ua:SetAnchor(TOPLEFT, entry.main, TOPLEFT, -2, -2)
    entry.ua:SetDimensions(40,40)
    entry.ua:SetTexture("/esoui/art/mappins/ava_attackburst_64.dds")
    entry.ua:SetDrawLayer(1)

    local fontMain = "EsoUI/Common/Fonts/univers67.otf|18|soft-shadow-thick"
    entry.name = WINDOW_MANAGER:CreateControl(entryName .. "name", entry.main, CT_LABEL)
    entry.name:SetDimensions(150,30)
    entry.name:SetAnchor(TOPLEFT, entry.main, TOPLEFT, 35, 5)
    entry.name:SetFont(fontMain)

    --local fontSmall = "EsoUI/Common/Fonts/univers67.otf|14|soft-shadow-thin"
    entry.defSiege = WINDOW_MANAGER:CreateControl(entryName .. "defSiege", entry.main, CT_LABEL)
    entry.defSiege:SetDimensions(30,30)
    entry.defSiege:SetAnchor(TOPLEFT, entry.main, TOPLEFT, 220, 5)
    entry.defSiege:SetFont(fontMain)

    entry.attSiege = WINDOW_MANAGER:CreateControl(entryName .. "attSiege", entry.main, CT_LABEL)
    entry.attSiege:SetDimensions(30,30)
    entry.attSiege:SetAnchor(TOPLEFT, entry.main, TOPLEFT, 190, 5)
    entry.attSiege:SetFont(fontMain)

    entry.time = WINDOW_MANAGER:CreateControl(entryName .. "time", entry.main, CT_LABEL)
    entry.time:SetDimensions(30,30)
    entry.time:SetAnchor(TOPLEFT, entry.main, TOPLEFT, 250, 5)
    entry.time:SetFont(fontMain)
    entry.time:SetColor(.8,.8,.8)

    table.insert(CyrHUD.entries, entry)
    return entry
end

CyrHUD.getEntry = function()
    CyrHUD.ptr = CyrHUD.ptr + 1
    if #CyrHUD.entries < CyrHUD.ptr then
        CyrHUD.createEntry()
    end
    CyrHUD.entries[CyrHUD.ptr].main:SetHidden(false)
    return CyrHUD.entries[CyrHUD.ptr]
end

CyrHUD.ptr = 0
CyrHUD.reset = function()
    for _,p in pairs(CyrHUD.entries) do
        p.main:SetHidden(true)
    end
    CyrHUD.ptr = 0
end

CyrHUD.print = function(battle)
    local entry = CyrHUD.getEntry()
    entry.icon:SetTexture(battle:getIcon())
    entry.name:SetText(battle.keepName)
    local color = CyrHUD.info[battle.defender].color
    entry.name:SetColor(color.r, color.g, color.b)
    entry.time:SetText(battle:getDuration())
    local ds, dc = battle:getDefSiege()
    entry.defSiege:SetText(ds)
    entry.defSiege:SetColor(dc.r, dc.g, dc.b)
    local as, ac = battle:getAttSiege()
    entry.attSiege:SetText(as)
    entry.attSiege:SetColor(ac.r, ac.g, ac.b)
    local r,g,b,a = battle:getBGColor()
    entry.main:SetCenterColor(r,g,b,a)
    entry.ua:SetHidden(not battle.keepUA)
end

CyrHUD.printAll = function()
    CyrHUD.reset()
    for _,b in pairs(CyrHUD.battles) do
        CyrHUD.print(b)
    end
end

----------------------------------------------
-- Battle management
----------------------------------------------
CyrHUD.battles = {}
CyrHUD.add = function(keepID)
    if CyrHUD.battles[keepID] == nil then
        CyrHUD.battles[keepID] = CyrHUD.Battle(keepID)
    else
        CyrHUD.battles[keepID]:restart()
    end
end

CyrHUD.checkAdd = function(keepID)
    if CyrHUD.battles[keepID] == nil then
        local battle = CyrHUD.Battle(keepID)
        if battle:isBattle() then
            CyrHUD.battles[keepID] = battle
        end
    elseif CyrHUD.battles[keepID]:isBattle() then
        CyrHUD.battles[keepID]:restart()
    end
end

CyrHUD.updateAll = function()
    for i,_ in pairs(CyrHUD.battles) do
        --Update in-place
        CyrHUD.battles[i]:update()
    end
end

CyrHUD.scanKeeps = function()
    for i=3,20 do
        CyrHUD.checkAdd(i)
    end

    for i=132,134 do
        CyrHUD.checkAdd(i)
    end
end

------------------------------------------------------------------------
-- Initialization
------------------------------------------------------------------------
CyrHUD.visible = false
function CyrHUD.init()
    --TODO: Add default quest tracker, other major quest trackers
    --TODO: Make this an option in menu and not default behavior
    --Init saved variables
    local def = {
        xoff = -10,
        yoff = 60
    }
    CyrHUD.cfg = ZO_SavedVars:NewAccountWide("CyrHUD_SavedVars", 1.0, "config", def)
    local _, pt, relTo, relPt = CyrHUD_UI:GetAnchor()
    CyrHUD_UI:ClearAnchors()
    CyrHUD_UI:SetAnchor(pt, relTo, relPt, CyrHUD.cfg.xoff, CyrHUD.cfg.yoff)

    --Init UI
    --if WYK_QuestTracker_MQT then WYK_QuestTracker_MQT:SetAlpha(0) end
    CyrHUD_UI:SetHidden(false)


    --Get initial scan
    CyrHUD.scanKeeps()

    --Add events
    EVENT_MANAGER:RegisterForUpdate("CyrHUDKeepCheck", 5000, function()
        CyrHUD.scanKeeps()
        CyrHUD.updateAll()
    end)
    EVENT_MANAGER:RegisterForUpdate("CyrHUDUIUpdate", 1000, function()
        CyrHUD.printAll()
        CyrHUD.updateScore()
    end)
    EVENT_MANAGER:RegisterForEvent("CyrHUDAttackChange", EVENT_KEEP_UNDER_ATTACK_CHANGED, CyrHUD.eventAttackChange)
    CyrHUD.visible = true
end

function CyrHUD.deinit()
    --if WYK_QuestTracker_MQT then WYK_QuestTracker_MQT:SetAlpha(1) end
    EVENT_MANAGER:UnregisterForUpdate("CyrHUDKeepCheck")
    EVENT_MANAGER:UnregisterForUpdate("CyrHUDUIUpdate")
    EVENT_MANAGER:UnregisterForUpdate("CyrHUDUpdateAPCount")
    CyrHUD_UI:SetHidden(true)
    CyrHUD.visible = false
end

--TODO: Properly setup on Addon init or playerLoad
--TODO: only show while in Cyrodiil
SLASH_COMMANDS["/cyrhud"] = function()
    if CyrHUD.visible then
        CyrHUD.deinit()
    else
        CyrHUD.init()
    end
end

function CyrHUD.playerInit()
    if IsPlayerInAvAWorld() then
        if not CyrHUD.visible then
            CyrHUD.init()
        end
    elseif CyrHUD.visible then
        CyrHUD.deinit()
    end
end

EVENT_MANAGER:RegisterForEvent("CyrHUD-init", EVENT_PLAYER_ACTIVATED, CyrHUD.playerInit)