-- Reference only. Do not add this file to GH3.toc.
-- This file demonstrates the New UI art-frame pattern for WoW Lua 5.1.

local PatternArtFrame = {}

local function ApplyRect(frame, parent, rect)
    if not frame or not parent or not rect then
        return
    end

    frame:ClearAllPoints()
    frame:SetPoint("TOPLEFT", parent, "TOPLEFT", rect.x, rect.y)
    frame:SetSize(rect.w, rect.h)
end

local function CreateFallbackBackground(frame)
    local background = frame:CreateTexture(nil, "BACKGROUND")
    background:SetAllPoints(frame)
    background:SetColorTexture(0.10, 0.10, 0.12, 0.94)
    frame.FallbackBackground = background
end

local function CreateArtFrame(parent, rect, asset)
    local frame = CreateFrame("Frame", nil, parent, BackdropTemplateMixin and "BackdropTemplate" or nil)
    ApplyRect(frame, parent, rect)
    local hasAuthoredArt = type(asset) == "table" and type(asset.texture) == "string" and asset.texture ~= ""

    if frame.SetBackdrop then
        frame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Buttons\\WHITE8X8",
            edgeSize = 1,
            insets = {
                left = 1,
                right = 1,
                top = 1,
                bottom = 1,
            },
        })
        frame:SetBackdropColor(hasAuthoredArt and 0 or 0.08, hasAuthoredArt and 0 or 0.08, hasAuthoredArt and 0 or 0.10, hasAuthoredArt and 0 or 0.92)
        frame:SetBackdropBorderColor(0.34, 0.34, 0.40, 1)
    elseif not hasAuthoredArt then
        CreateFallbackBackground(frame)
    end

    local texturePath = asset and asset.texture or nil
    local sourceWidth = asset and tonumber(asset.sourceWidth) or rect.w or 1
    local sourceHeight = asset and tonumber(asset.sourceHeight) or rect.h or 1
    local insets = asset and asset.insets or {}

    local texture = frame:CreateTexture(nil, hasAuthoredArt and "ARTWORK" or "BACKGROUND")
    texture:SetAllPoints(frame)
    if hasAuthoredArt then
        texture:SetTexture(texturePath)
        texture:SetVertexColor(1, 1, 1, 1)
    else
        texture:SetColorTexture(0.12, 0.12, 0.14, 0.98)
    end
    frame.Texture = texture

    local scaleX = (rect.w or 1) / math.max(1, sourceWidth)
    local scaleY = (rect.h or 1) / math.max(1, sourceHeight)
    local left = math.floor(((tonumber(insets.left) or 0) * scaleX) + 0.5)
    local right = math.floor(((tonumber(insets.right) or 0) * scaleX) + 0.5)
    local top = math.floor(((tonumber(insets.top) or 0) * scaleY) + 0.5)
    local bottom = math.floor(((tonumber(insets.bottom) or 0) * scaleY) + 0.5)

    local content = CreateFrame("Frame", nil, frame)
    content:SetPoint("TOPLEFT", frame, "TOPLEFT", left, -top)
    content:SetSize(
        math.max(1, (rect.w or 1) - left - right),
        math.max(1, (rect.h or 1) - top - bottom)
    )
    content.Insets = {
        left = left,
        right = right,
        top = top,
        bottom = bottom,
    }

    frame.Content = content
    return frame
end

local function CreateDecoratedFrame(parent, rect, spec)
    local frame = CreateArtFrame(parent, rect, spec and spec.frame or spec)
    local content = frame.Content
    local body = content

    if spec and spec.header then
        local header = frame:CreateTexture(nil, "ARTWORK")
        header:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1)
        header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -1, -1)
        header:SetHeight(tonumber(spec.header.height) or 32)
        if type(spec.header.texture) == "string" and spec.header.texture ~= "" then
            header:SetTexture(spec.header.texture)
            header:SetVertexColor(1, 1, 1, 0.96)
        else
            header:SetColorTexture(0.09, 0.08, 0.06, 0.82)
        end
        frame.HeaderTexture = header

        local titleText = spec.header.title or nil
        if type(titleText) == "string" and titleText ~= "" then
            local title = content:CreateFontString(nil, "OVERLAY", "GameFontNormal")
            title:SetPoint("TOPLEFT", content, "TOPLEFT", 0, 0)
            title:SetText(titleText)
            frame.TitleText = title
        end

        body = CreateFrame("Frame", nil, frame)
        body:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(tonumber(spec.header.bodyOffsetY) or 26))
        body:SetPoint("BOTTOMRIGHT", content, "BOTTOMRIGHT", 0, 0)
    end

    frame.Body = body
    return frame
end

local function CreateCardFrame(parent, rect, spec)
    local frame = CreateArtFrame(parent, rect, spec and spec.frame or spec)
    local content = frame.Content
    local iconSize = tonumber(spec and spec.iconSize) or 58
    local titleText = spec and spec.title or "Card"
    local valueText = spec and spec.value or "-"
    local titleColor = spec and spec.titleColor or { 0.96, 0.93, 0.84, 1 }
    local valueColor = spec and spec.valueColor or { 0.96, 0.93, 0.84, 1 }

    if spec and spec.icon and spec.icon ~= "" then
        local icon = frame:CreateTexture(nil, "OVERLAY")
        icon:SetSize(iconSize, iconSize)
        icon:SetPoint("LEFT", content, "LEFT", 0, -1)
        icon:SetTexture(spec.icon)
        icon:SetVertexColor(1, 1, 1, 0.98)
        frame.IconTexture = icon
    end

    local body = CreateFrame("Frame", nil, frame)
    body:SetPoint("TOPLEFT", content, "TOPLEFT", iconSize + 18, 0)
    body:SetPoint("BOTTOMRIGHT", content, "BOTTOMRIGHT", 0, 0)

    local title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    title:SetPoint("TOP", body, "TOP", 0, -2)
    title:SetWidth(rect.w)
    title:SetJustifyH("CENTER")
    title:SetWordWrap(false)
    title:SetText(titleText)
    title:SetTextColor(titleColor[1], titleColor[2], titleColor[3], titleColor[4] or 1)

    local value = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    value:SetPoint("CENTER", body, "CENTER", 0, -4)
    value:SetWidth(rect.w)
    value:SetJustifyH("CENTER")
    value:SetWordWrap(false)
    value:SetText(valueText)
    value:SetTextColor(valueColor[1], valueColor[2], valueColor[3], valueColor[4] or 1)

    frame.Body = body
    frame.TitleText = title
    frame.ValueText = value
    return frame
end

local function CreateReferenceExample(parent)
    local asset = {
        texture = "Interface\\Buttons\\WHITE8X8",
        sourceWidth = 512,
        sourceHeight = 128,
        insets = {
            left = 36,
            right = 36,
            top = 10,
            bottom = 12,
        },
    }

    local frame = CreateArtFrame(parent, { x = 20, y = -20, w = 300, h = 90 }, asset)

    local title = frame.Content:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    title:SetPoint("TOPLEFT", frame.Content, "TOPLEFT", 0, 0)
    title:SetText("Title Anchors To Content")

    local value = frame.Content:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    value:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
    value:SetText("42")

    frame.TitleText = title
    frame.ValueText = value
    return frame
end

PatternArtFrame.ApplyRect = ApplyRect
PatternArtFrame.CreateArtFrame = CreateArtFrame
PatternArtFrame.CreateDecoratedFrame = CreateDecoratedFrame
PatternArtFrame.CreateCardFrame = CreateCardFrame
PatternArtFrame.CreateReferenceExample = CreateReferenceExample

return PatternArtFrame