--[[
============================================================================
PreviewBackground.lua  (added in v14.4.0)
============================================================================

Lets the user pick a background for the preview model in the main browser
and the TransmogUI dressing room.

Why a separate module:
  - Two consumers (browser preview + TransmogUI preview) both need the
    same setup logic. Centralizing means both stay consistent.
  - The list of available backgrounds is data, not behavior. Easy to
    extend with more presets later without touching consumer code.
  - Persistence (`preview.backgroundID` setting) is one place.

Strategy:
  Insert a Texture FRAME directly behind the DressUpModel. WoW DressUpModel
  itself doesn't render arbitrary 2D backgrounds, but you can place a
  texture in the same parent frame at a lower draw layer. The model then
  sits on top with its transparent background.

  We set the texture either to a built-in WoW image path or a solid color.
============================================================================
]]--
local ADDON_NAME, NS = ...
local ETB = NS.ETB
NS.ETB.PreviewBackground = NS.ETB.PreviewBackground or {}
local PB = NS.ETB.PreviewBackground

-- =============================================================================
-- PRESETS
-- =============================================================================
-- Each preset has either `texture` (a path) or `color` (RGBA), but not both.
-- Texture paths used here are common WoW 5.4.8 assets that should always
-- exist regardless of installed graphics-mod state. If a path doesn't
-- resolve at runtime WoW renders a magenta/yellow checkerboard, which
-- would look ugly but not crash. We fall back to a color in that case.

PB.PRESETS = {
    -- v15.8.2: Use texture paths that are confirmed to exist in MoP 5.4.8.
    -- Previous v15.8.1 attempt used Interface\DressUpFrame\DressingRoom*
    -- paths that don't resolve on 5.4.8 (the actual filenames exist in
    -- WoD+ but not the MoP client), so the model showed no background.
    --
    -- These paths are all part of the standard FrameXML asset library
    -- that ships with the 5.4.8 client and are used by Blizzard's own UI.
    -- Each is a large background that fills the model frame nicely.
    {
        id = "tooltip", label = "Stone",
        texture = "Interface\\Tooltips\\UI-Tooltip-Background",
        texCoord = { 0, 1, 0, 1 },
    },
    {
        id = "parchment_large", label = "Parchment",
        texture = "Interface\\AchievementFrame\\UI-Achievement-Parchment-Horizontal",
        texCoord = { 0, 1, 0, 1 },
    },
    {
        id = "spellbook", label = "Spellbook",
        texture = "Interface\\Spellbook\\Spellbook-Page-1",
        texCoord = { 0, 1, 0, 1 },
    },
    {
        id = "auction", label = "Auction House",
        texture = "Interface\\AuctionFrame\\UI-AuctionFrame-Bid",
        texCoord = { 0, 1, 0, 1 },
    },
    {
        id = "guildbg", label = "Guild Tabard",
        texture = "Interface\\GuildFrame\\GuildFrame",
        texCoord = { 0, 1, 0, 1 },
    },
    {
        id = "talent", label = "Talent Page",
        texture = "Interface\\TalentFrame\\TalentFrameBackground-Mage",
        texCoord = { 0, 1, 0, 1 },
    },
    -- Solid colors (always render correctly; ultimate fallbacks)
    {
        id = "default", label = "Dark",
        color = { 0.05, 0.05, 0.05, 0.85 },
    },
    {
        id = "midnight", label = "Midnight Blue",
        color = { 0.02, 0.04, 0.10, 1.0 },
    },
    {
        id = "warm", label = "Warm Tan",
        color = { 0.20, 0.16, 0.10, 1.0 },
    },
    {
        id = "void", label = "Pure Black",
        color = { 0, 0, 0, 1 },
    },
}

-- Build id-keyed lookup at load
PB._byID = {}
for _, p in ipairs(PB.PRESETS) do PB._byID[p.id] = p end

-- =============================================================================
-- API
-- =============================================================================

-- Attach a background texture behind the model. v15.8.2: create the
-- background as a child FRAME on top of the parent's own backdrop (the
-- parent has a parchment SetBackdrop that was covering our texture in
-- v15.8.1, making the background appear "not showing"). The child frame
-- sits at FrameLevel parent+0 so it draws above the parchment but below
-- the model itself.
--
-- modelFrame: the DressUpModel-like frame (used for size + anchor reference)
-- parentFrame: the frame that hosts the background sub-frame
function PB:Attach(modelFrame, parentFrame)
    if not modelFrame or not parentFrame then return nil end

    -- Tear down a prior attach if Attach is called twice (defensive)
    if parentFrame._etbPreviewBgFrame then
        parentFrame._etbPreviewBgFrame:Hide()
        parentFrame._etbPreviewBgFrame:SetParent(nil)
    end

    -- Dedicated sub-frame for the background — gives us our own draw stack
    -- separate from the parent's parchment SetBackdrop.
    local bgFrame = CreateFrame("Frame", nil, parentFrame)
    bgFrame:SetAllPoints(modelFrame)
    -- Just above the parent's backdrop but below any UI overlays.
    if parentFrame.GetFrameLevel and bgFrame.SetFrameLevel then
        bgFrame:SetFrameLevel(parentFrame:GetFrameLevel())
    end

    -- Use ARTWORK layer (above the parent's BACKGROUND-drawn parchment).
    local bg = bgFrame:CreateTexture(nil, "ARTWORK")
    bg:SetAllPoints()

    parentFrame._etbPreviewBgFrame = bgFrame
    parentFrame._etbPreviewBg = bg

    -- Apply current preset (saved or default)
    local id = self:GetCurrentID()
    self:SetPresetByID(parentFrame, id)
    return bg
end

-- Apply the named preset to a previously-Attached host frame.
function PB:SetPresetByID(parentFrame, presetID)
    if not parentFrame or not parentFrame._etbPreviewBg then return end
    local preset = self._byID[presetID] or self._byID["default"]
    local tex = parentFrame._etbPreviewBg

    if preset.texture then
        -- SetTexture returns truthy on success, false on bad path. If the
        -- texture fails to load (path doesn't exist on this client),
        -- fall back to a solid color so the user still sees SOMETHING
        -- instead of the parent's parchment bleed-through.
        local ok = tex:SetTexture(preset.texture)
        if ok ~= false then
            if preset.texCoord then
                tex:SetTexCoord(unpack(preset.texCoord))
            else
                tex:SetTexCoord(0, 1, 0, 1)
            end
            tex:SetVertexColor(1, 1, 1, 1)  -- reset any tint from prior preset
        else
            -- Texture path didn't resolve; show a warm-tan fallback so the
            -- "background" effect is at least visible.
            tex:SetTexture(nil)
            tex:SetColorTexture(0.20, 0.16, 0.10, 1.0)
        end
    elseif preset.color then
        tex:SetTexture(nil)  -- clear any texture
        tex:SetColorTexture(unpack(preset.color))
    end
end

-- Persistence: read the saved current preset ID (or default).
function PB:GetCurrentID()
    if ETB.Settings and ETB.Settings.Get then
        local id = ETB.Settings:Get("preview.backgroundID")
        if id and self._byID[id] then return id end
    end
    return "default"
end

-- Save the chosen preset ID and propagate to all attached frames.
function PB:SetCurrentID(presetID)
    if not self._byID[presetID] then return end
    if ETB.Settings and ETB.Settings.Set then
        ETB.Settings:Set("preview.backgroundID", presetID)
    end
    -- Propagate: any tracked attachment gets re-applied
    for _, frame in ipairs(self._attached or {}) do
        self:SetPresetByID(frame, presetID)
    end
end

-- Track attachments so SetCurrentID can refresh all of them
local _origAttach = PB.Attach
function PB:Attach(modelFrame, parentFrame)
    self._attached = self._attached or {}
    local result = _origAttach(self, modelFrame, parentFrame)
    if result then self._attached[#self._attached + 1] = parentFrame end
    return result
end

-- Convenience: cycle to next preset (used by a quick toggle button).
function PB:CycleNext()
    local cur = self:GetCurrentID()
    local idx = 1
    for i, p in ipairs(self.PRESETS) do
        if p.id == cur then idx = i; break end
    end
    local nextIdx = (idx % #self.PRESETS) + 1
    self:SetCurrentID(self.PRESETS[nextIdx].id)
    return self.PRESETS[nextIdx]
end
