--[[
Author: Jarth
Filename: MementoBar_Buttons.lua
]] --

-------------------------------------------------------------------------------------------------
-- VARIABLES --
-------------------------------------------------------------------------------------------------
local baseModule = MementoBar

-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-- Button highlight --
-------------------------------------------------------------------------------------------------
function baseModule.ButtonHighlightEnter(frame)
    local highlightColor = baseModule.Saved.HighlightColor
    local buttonBackdrop = GetControl(frame, "Backdrop")

    if buttonBackdrop ~= nil then
        if baseModule.Saved.IsAudioEnabled then
            PlaySound(SOUNDS.QUICKSLOT_MOUSEOVER)
        end

        buttonBackdrop:SetEdgeColor(highlightColor.r, highlightColor.g, highlightColor.b, highlightColor.a)
    end
end

function baseModule.ButtonHighlightExit(frame)
    local edgeColor = baseModule.Saved.EdgeColor
    local buttonBackdrop = GetControl(frame, "Backdrop")

    if buttonBackdrop ~= nil then
        buttonBackdrop:SetEdgeColor(edgeColor.r, edgeColor.g, edgeColor.b, edgeColor.a)
    end
end

function baseModule.ButtonOnClicked(button)
    local id = button:GetId()

    if id > 0 then
        local cooldownRemaining, cooldownDuration = GetCollectibleCooldownAndDuration(id)
        if cooldownRemaining == 0 then
            baseModule:Activate(id)
        end
    end
end

-------------------------------------------------------------------------------------------------
-- PRIVATE FUNCTIONS --
-------------------------------------------------------------------------------------------------
function baseModule:SetupButton(button, left, top)
    button:ClearAnchors()
    button:SetAnchor(TOPLEFT, MementoBar_Frame, TOPLEFT, left, top)
    button:SetHeight(baseModule.Saved.Height)
    button:SetWidth(baseModule.Saved.Width)
    button:SetHidden(false)
end

function baseModule:SetupButtonBinding(button, key, left, top)
    local buttonBinding = GetControl(button, "Binding")

    if buttonBinding ~= nil then
        baseModule:HotkeyUpdateColor(buttonBinding)
        buttonBinding:SetText(baseModule:HoykeyGetKey(button, key))
        buttonBinding:SetDrawLevel(3)
        buttonBinding:ClearAnchors()
        buttonBinding:SetAnchor(baseModule.Saved.KeyBindingLocation, button, baseModule.Saved.KeyBindingLocation, 0, 0)
    end

    if buttonBinding ~= nil then
        buttonBinding:SetHidden(not baseModule.Saved.ShowKeyBinding)
    end
end

function baseModule:SetupButtonTexture(button, key, left, top)
    local buttonTexture = GetControl(button, "Texture")

    if buttonTexture ~= nil then
        button:SetHandler("OnClicked", baseModule.ButtonOnClicked)
        buttonTexture:SetDrawLevel(3)
        buttonTexture:SetTexture(baseModule.Mementos[key].EnabledTexture)
        buttonTexture:ClearAnchors()
        buttonTexture:SetAnchor(TOPLEFT, button, TOPLEFT, baseModule.Saved.Margin, baseModule.Saved.Margin)
        buttonTexture:SetHeight(button:GetHeight() - (2 * baseModule.Saved.Margin))
        buttonTexture:SetWidth(button:GetWidth() - (2 * baseModule.Saved.Margin))
    end
end

function baseModule:SetupButtonBackdrop(button, key, left, top)
    local buttonBackdrop = GetControl(button, "Backdrop")

    if buttonBackdrop ~= nil then
        buttonBackdrop:SetDrawLevel(2)
        buttonBackdrop:SetEdgeTexture(nil, 1, 1, baseModule.Saved.Margin)
        buttonBackdrop:ClearAnchors()
        buttonBackdrop:SetAnchor(TOPLEFT, MementoBar_Frame, TOPLEFT, left, top)
        buttonBackdrop:SetHeight(button:GetHeight())
        buttonBackdrop:SetWidth(button:GetWidth())
    end
end

function baseModule:SetButtonFrameWidth()
    local count, depth, height, width = 0, 0, 0, 0

    for key, value in pairs(baseModule.Saved.SelectedMementos) do
        if IsCollectibleUnlocked(key) and baseModule.Saved.SelectedMementos[key] then
            count = count + 1
        end
    end

    if count > 0 then
        depth = math.ceil(count / baseModule.Saved.BarDepth)
        height = baseModule.Saved.Height * (baseModule.Saved.Horizontal and baseModule.Saved.BarDepth or depth)
        width = baseModule.Saved.Width * (baseModule.Saved.Horizontal and depth or baseModule.Saved.BarDepth)
    end

    baseModule:SetFrameSettings(MementoBar_Frame, count == 0, height, width)
    baseModule:SetFrameSettings(MementoBar_FrameBackdrop, count == 0, height, width)
end

function baseModule:SetFrameSettings(frame, isHidden, height, width)
    if frame ~= nil then
        frame:SetHidden(count == 0)
        frame:SetHeight(height)
        frame:SetWidth(width)
    end
end

function baseModule:InitializeButtons()
    local index = 1

    for _, _value in ipairs(baseModule.OrderedMementos) do
        local id = _value.Id
        local left, top = baseModule:GetButtonPosition(index)

        if baseModule.Saved.SelectedMementos[id] and IsCollectibleUnlocked(id) then
            if baseModule.Buttons[id] == nil then
                baseModule.Buttons[id] = baseModule.WM:CreateControlFromVirtual("MementoBar_Button", MementoBar_Frame, "MementoBar_Button", id)
                baseModule.Buttons[id]:SetId(id)
            end

            baseModule:SetupButton(baseModule.Buttons[id], left, top)
            baseModule:SetupButtonBinding(baseModule.Buttons[id], id, left, top)
            baseModule:SetupButtonBackdrop(baseModule.Buttons[id], id, left, top)
            baseModule:SetupButtonTexture(baseModule.Buttons[id], id, left, top)
            baseModule.Buttons[id]:SetHandler("OnMouseEnter", baseModule.ButtonHighlightEnter)
            baseModule.Buttons[id]:SetHandler("OnMouseExit", baseModule.ButtonHighlightExit)
            index = index + 1
        elseif baseModule.Buttons[id] ~= nil then
            baseModule.Buttons[id]:SetHidden(true)
        end
    end
end

function baseModule:GetButtonPosition(index)
    local left = baseModule.Saved.Width * ((index - 1) % baseModule.Saved.BarDepth)
    local top = baseModule.Saved.Height * (math.floor((index - 1) / baseModule.Saved.BarDepth))

    if baseModule.Saved.Horizontal then
        left = baseModule.Saved.Height * (math.floor((index - 1) / baseModule.Saved.BarDepth))
        top = baseModule.Saved.Width * ((index - 1) % baseModule.Saved.BarDepth)
    end

    return left, top
end

function baseModule:RestoreButtons()
    local centerColor = baseModule.Saved.CenterColor
    local edgeColor = baseModule.Saved.EdgeColor
    local timerIsTimerEnabled = baseModule.Saved.IsTimerEnabled
    local timerFont = baseModule.Saved.TimerFont
    local timerFontColor = baseModule.Saved.TimerFontColor

    for _, _value in ipairs(baseModule.OrderedMementos) do
        if baseModule.Buttons[_value.Id] ~= nil then
            local backdrop = GetControl(baseModule.Buttons[_value.Id], "Backdrop")

            if backdrop ~= nil then
                backdrop:SetCenterColor(centerColor.r, centerColor.g, centerColor.b, centerColor.a)
                backdrop:SetEdgeColor(edgeColor.r, edgeColor.g, edgeColor.b, edgeColor.a)
            end

            local label = GetControl(baseModule.Buttons[_value.Id], "Timer")

            if label ~= nil then
                label:SetHidden(not timerIsTimerEnabled)
                label:SetFont(timerFont)
                label:SetColor(timerFontColor.r, timerFontColor.g, timerFontColor.b, timerFontColor.a)
            end
        end
    end
end

function baseModule:Activate(collectibleId)
    if collectibleId and IsCollectibleUsable(collectibleId) then
        baseModule.CountDown.StartTime = GetTimeStamp()
        baseModule.CountDown.CollectibleId = collectibleId
        EVENT_MANAGER:UnregisterForUpdate(baseModule.Addon.Name .. baseModule.CountDown.Event)
        UseCollectible(collectibleId)
        EVENT_MANAGER:RegisterForUpdate(baseModule.Addon.Name .. baseModule.CountDown.Event, baseModule.CountDown.Tick, baseModule.Update)
    end
end

function baseModule.Update()
    local cooldownRemaining, cooldownDuration = GetCollectibleCooldownAndDuration(baseModule.CountDown.CollectibleId)

    if cooldownRemaining > 0 then
        baseModule:UpdateLabel(cooldownRemaining)
    elseif (cooldownDuration > 0 and (GetTimeStamp() < (baseModule.CountDown.StartTime + math.floor(cooldownDuration / 1000)))) then
        baseModule:UpdateLabel(cooldownDuration)
    else
        baseModule:UpdateLabel("")
        EVENT_MANAGER:UnregisterForUpdate(baseModule.Addon.Name .. baseModule.CountDown.Event)
    end
end

function baseModule:UpdateLabel(remaining)
    if type(remaining) == "number" and remaining > 0 then
        remaining = string.format("%.1fs", (math.floor(remaining / 100) / 10))
    end

    for collectibleId in pairs(baseModule.Saved.SelectedMementos) do
        local buttonTimer = GetControl(baseModule.Buttons[collectibleId], "Timer")

        if buttonTimer and baseModule.Mementos[collectibleId] then
            buttonTimer:SetText(remaining)
        end
    end
end