local _, addonTable = ...

local ComboPointsMixin = {}

function ComboPointsMixin:Cleanup()
    if self.Frame then
        self.Frame:UnregisterAllEvents()
        self.Frame:Hide()
        self.Frame:ClearAllPoints()
        self.Frame = nil
    end
    self.PointsTextures = {}
    self.initialized = false
end

function ComboPointsMixin:Init()
    local config = addonTable.getConfig()
    local mixin = self
    addonTable.blinkState = true

    mixin.PointsTextures = {}
    mixin.PointSize = 64 * config.scale
    mixin.Frame = CreateFrame("Frame", 'ScritchPopComboPoints', UIParent, BackdropTemplateMixin and "BackdropTemplate")
    mixin.Frame:SetFrameLevel(200)
    mixin.Frame:Show()
    mixin:ApplyLayout()
    mixin:UpdateOpacity()
    
    mixin.Frame:SetMovable(config.movable)
    mixin.Frame:EnableMouse(config.movable)
    mixin.Frame:RegisterForDrag("LeftButton")
    mixin.Frame:SetScript("OnDragStart", mixin.Frame.StartMoving)
    mixin.Frame:SetScript("OnDragStop", function(frame) 
        frame:StopMovingOrSizing() 
        local point, _, relativePoint, xOfs, yOfs = mixin.Frame:GetPoint() 
        config.point = point 
        config.relativePoint = relativePoint 
        config.position_x = xOfs 
        config.position_y = yOfs 
    end)
    
    mixin.Frame:RegisterUnitEvent("UNIT_POWER_UPDATE", "player")
    mixin.Frame:SetScript("OnEvent", function(self, event, unit)
        if unit and unit ~= "player" then return end
        mixin:UpdateDisplay()
    end)

    mixin.Combat = CreateFrame("Frame", nil, mixin.Frame)
    mixin.Combat:RegisterEvent("PLAYER_IN_COMBAT_CHANGED")
    mixin.Combat:SetScript("OnEvent", function() mixin:UpdateOpacity() end)

    local blinkFrame = CreateFrame("Frame", nil, mixin.Frame)
    blinkFrame.elapsed = 0
    blinkFrame:SetScript("OnUpdate", function(self, elapsed)
        if (not config.popping) then return end
        self.elapsed = self.elapsed + elapsed
        if self.elapsed >= config.popSpeed then
            addonTable.blinkState = not addonTable.blinkState
            mixin:UpdateDisplay()
            addonTable.Options:UpdatePreview()
            self.elapsed = 0
        end
    end)

    if (config.energy_bar) then
        addonTable.EnergyBar:createEnergyBar()
    end
end

---------------------------------------------------------------------------

function ComboPointsMixin:SetMovable(value)
    self.Frame:SetMovable(value)
end

function ComboPointsMixin:EnableMouse(value)
    self.Frame:EnableMouse(value)
end

function ComboPointsMixin:Show()
    self.Frame:Show()
end

function ComboPointsMixin:Hide()
    self.Frame:Hide()
end

function ComboPointsMixin:SetScale(scale)
    self.PointSize = 64 * scale
    self.Frame:SetSize(5*self.PointSize, self.PointSize)
end

function ComboPointsMixin:UpdateOpacity()
    local config = addonTable.getConfig()
    local combat = UnitAffectingCombat("player")
    if combat then
        self.Frame:SetAlpha(config.combat_opacity)
    else
        self.Frame:SetAlpha(config.opacity)
    end
end

function ComboPointsMixin:GetFrame()
    return self.Frame
end

---------------------------------------------------------------------------

function ComboPointsMixin:UpdateDisplay()
    if not self.initialized then return end

    local current = UnitPower("player", Enum.PowerType.ComboPoints)
    local max = UnitPowerMax("player", Enum.PowerType.ComboPoints) or 5
    max = max > 0 and max or 5

    for i = 1, max do
        if i <= current then
            self.PointsTextures[i]:SetTexture(getPop())
        else
            self.PointsTextures[i]:SetTexture(getEmpty())
        end
    end

end

function ComboPointsMixin:ApplyLayout()
    local config = addonTable.getConfig()
    local max = UnitPowerMax("player", Enum.PowerType.ComboPoints) or 5
    max = max > 0 and max or 5

    self.Frame:ClearAllPoints()
    self.Frame:SetPoint(config.point, UIParent, config.relativePoint, config.position_x, config.position_y)
    self.Frame:SetSize(5*self.PointSize + 3*config.gap, self.PointSize)

    for i = 1, max do
        if self.PointsTextures[i] then
            self.PointsTextures[i]:Hide()
            self.PointsTextures[i] = nil
        end
        self.PointsTextures[i] = self.Frame:CreateTexture(nil, "BACKGROUND")
        self.PointsTextures[i]:SetSize(self.PointSize, self.PointSize)
        self.PointsTextures[i]:SetTexture(getEmpty())
        self.PointsTextures[i]:ClearAllPoints()
        self.PointsTextures[i]:SetPoint("LEFT", self.Frame, "LEFT", (i-1)*(self.PointSize+config.gap), 0)
        self.PointsTextures[i]:Show()    
    end
    self.initialized = true
    self:UpdateDisplay()
end

addonTable.ComboPointsMixin = ComboPointsMixin
