local addonName, ns = ...

------------------------------------------------------------
-- Themed widget factories: flat navy & gold buttons that
-- replace UIPanelButtonTemplate / UIPanelCloseButton.
--
-- The returned buttons keep the normal Button API used at
-- call sites (SetSize/SetPoint/SetScript/SetEnabled/...);
-- SetText/GetText proxy an internal FontString so the label
-- colour is fully theme-controlled.
------------------------------------------------------------

local function setLabelColor(btn, color)
    btn._label:SetTextColor(color:GetRGBA())
end

-- One place computes the label anchor: the button's rest offset (see
-- SetLabelOffset) plus, while pressed, the 1px down-right travel that
-- gives the click its feedback.
local function positionLabel(btn, pressed)
    local push = pressed and 1 or 0
    btn._label:ClearAllPoints()
    btn._label:SetPoint("CENTER", btn, "CENTER",
        btn._labelOffsetX + push, btn._labelOffsetY - push)
end

------------------------------------------------------------
-- Exclusive dialogs: the Import / Export (copy) / Help popups share the
-- FULLSCREEN_DIALOG strata and all open at CENTER. Shown independently, two
-- open dialogs sit at the same frame level and their draw layers interleave —
-- both backdrops and both sets of text blend, so a dialog looks like it has no
-- background. Route every dialog through ShowPopup: it hides the other
-- registered dialogs and raises this one to the front.
------------------------------------------------------------
ns._exclusivePopups = ns._exclusivePopups or {}

function ns.RegisterPopup(frame)
    table.insert(ns._exclusivePopups, frame)
end

function ns.ShowPopup(frame)
    for _, other in ipairs(ns._exclusivePopups) do
        if other ~= frame then other:Hide() end
    end
    frame:Show()
    if frame.Raise then frame:Raise() end
end

-- The registry doubles as the definitive list of sub-windows: closing the
-- main window calls this so no dialog is left orphaned on screen.
function ns.HideAllPopups()
    for _, popup in ipairs(ns._exclusivePopups) do
        popup:Hide()
    end
end

-- Toolbar buttons toggle their own dialog: a second click on the button that
-- opened a dialog closes it. `show` opens it (routing through ShowPopup).
function ns.TogglePopup(frame, show)
    if frame and frame:IsShown() then
        frame:Hide()
    else
        show()
    end
end

function ns.CreateThemedButton(parent, text, name)
    local btn = CreateFrame("Button", name, parent, "BackdropTemplate")
    btn:SetMotionScriptsWhileDisabled(true)
    btn:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 10,
        insets = { left = 2, right = 2, top = 2, bottom = 2 },
    })
    btn:SetBackdropColor(ns.Theme.BUTTON_BG:GetRGBA())
    btn:SetBackdropBorderColor(ns.Theme.BORDER:GetRGBA())

    local label = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    btn._label = label
    btn._labelOffsetX, btn._labelOffsetY = 0, 0
    positionLabel(btn, false)

    function btn:SetText(t) self._label:SetText(t) end
    function btn:GetText() return self._label:GetText() end

    -- Rest-state nudge for the label. Single-glyph labels (+, -, ×) sit
    -- optically high-left of true centre in a small square button: the
    -- FontString box reserves descender space no glyph uses, and the odd
    -- leftover width snaps to the left pixel. Word labels average this
    -- out; glyph buttons opt into a 1px down-right correction.
    function btn:SetLabelOffset(x, y)
        self._labelOffsetX, self._labelOffsetY = x, y
        positionLabel(self, false)
    end

    btn:SetScript("OnEnter", function(self)
        if self:IsEnabled() then
            self:SetBackdropColor(ns.Theme.BUTTON_HOVER_BG:GetRGBA())
            setLabelColor(self, ns.Theme.BUTTON_HOVER_TEXT)
        end
    end)
    btn:SetScript("OnLeave", function(self)
        if self:IsEnabled() then
            self:SetBackdropColor(ns.Theme.BUTTON_BG:GetRGBA())
            setLabelColor(self, ns.Theme.LABEL)
        end
    end)
    btn:SetScript("OnMouseDown", function(self)
        if self:IsEnabled() then
            positionLabel(self, true)
        end
    end)
    btn:SetScript("OnMouseUp", function(self)
        positionLabel(self, false)
    end)

    local baseSetEnabled = btn.SetEnabled
    function btn:SetEnabled(enabled)
        baseSetEnabled(self, enabled)
        setLabelColor(self, enabled and ns.Theme.LABEL or ns.Theme.TEXT_MUTED)
    end
    function btn:Enable() self:SetEnabled(true) end
    function btn:Disable() self:SetEnabled(false) end

    btn:SetText(text or "")
    btn:SetEnabled(true)
    return btn
end

function ns.CreateThemedCloseButton(frame)
    local btn = ns.CreateThemedButton(frame, "×")
    btn:SetSize(20, 20)
    btn:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -5, -5)
    btn:SetScript("OnClick", function() frame:Hide() end)
    -- The close glyph is always heading-gold; re-pin OnLeave so hover
    -- restore doesn't downgrade it to the body-label colour. The
    -- replacement must also restore the backdrop the factory handler
    -- would otherwise reset.
    btn._label:SetTextColor(ns.Theme.HEADING:GetRGBA())
    btn:SetScript("OnLeave", function(self)
        if self:IsEnabled() then
            self:SetBackdropColor(ns.Theme.BUTTON_BG:GetRGBA())
            self._label:SetTextColor(ns.Theme.HEADING:GetRGBA())
        end
    end)
    return btn
end
