Module:ItemUtils

From Dune: Awakening Community Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:ItemUtils/doc

-- Module:ItemUtils
-- =============================================================================
-- Shared helper functions used by Module:Item's renderers.
-- Notable: contains ZERO renderers. Those live in Module:Item.
-- This distinction matters. Please remember it.
-- =============================================================================

local p = {}


-- =============================================================================
-- p.buildInfobox
-- =============================================================================
-- Builds an infobox by calling {{Infobox}} via frame:expandTemplate().
--
-- config table accepts:
--   config.title      (string)  — item name in the header
--   config.image      (string)  — filename only, we handle the [[File:]] wrap
--   config.subheader  (string)  — short description below the image
--   config.item_id    (string)  — goes in the collapsible footer
--   config.added      (string)  — version added
--   config.rows       (table)   — array of row definitions:
--                                 {"Label", value}     → standard data row
--                                 {header = "Title"}   → full-width section header
--                                 {full = content}     → full-width data row (stat bars etc.)
--                                 Rows with nil/empty values are silently skipped.
-- =============================================================================
function p.buildInfobox(config)

    local frame = mw.getCurrentFrame()
    local args  = {}

    args.title      = config.title
    args.labelstyle = "width:50%;"

    if config.image and config.image ~= "" then
        args.image = "[[File:" .. config.image .. "|frameless]]"
    end

    if config.subheader and config.subheader ~= "" then
        args.subheader = config.subheader
    end

    if config.item_id and config.item_id ~= "" then
        args.below =
            '<div class="mw-collapsible mw-collapsed" ' ..
            'data-expandtext="show item id" ' ..
            'data-collapsetext="hide item id">' ..
            '<br><div class="mw-collapsible-content" style="display:none;">' ..
            config.item_id ..
            '</div></div>' ..
            '<div class="no-js-fallback">' .. config.item_id .. '</div>'
    end

    local n = 1

    if config.added and config.added ~= "" then
        args["label" .. n] = "Added"
        args["data"  .. n] = config.added
        n = n + 1
    end

    for _, row in ipairs(config.rows) do

        if row.header then
            -- Named key: {header = "Section Title"}
            -- Using named keys because single-element tables and nil values
            -- have a complicated relationship in Lua that we want no part of.
            args["header" .. n] = row.header
            n = n + 1

        elseif row.full ~= nil and tostring(row.full) ~= "" then
            -- Full-width data row: {full = content}
            -- Used for StatRow bars which span the full infobox width.
            args["data" .. n] = tostring(row.full)
            n = n + 1

        elseif row[1] ~= nil and row[2] ~= nil and tostring(row[2]) ~= "" then
            -- Standard label/data row: {"Label", value}
            -- Explicitly checks row[2] ~= nil rather than trusting #row,
            -- because #row lies to your face when row[2] is nil.
            args["label" .. n] = row[1]
            args["data"  .. n] = tostring(row[2])
            n = n + 1
        end
        -- nil values, empty strings, and broken dreams fall through silently.
    end

    return frame:expandTemplate{ title = "Infobox", args = args }
end


-- =============================================================================
-- The remaining helpers — all unchanged, all minding their own business
-- in their own module like they're supposed to.
-- =============================================================================

function p.tierStars(tier)
    tier = tonumber(tier)
    if not tier then return "Unknown" end
    return string.rep("★", tier) .. string.rep("☆", 6 - tier)
end

function p.link(target)
    if not target or target == "" then return "—" end
    return "[[" .. target .. "]]"
end

function p.linkList(items)
    if not items or #items == 0 then return "—" end
    local links = {}
    for _, item in ipairs(items) do
        table.insert(links, "[[" .. item .. "]]")
    end
    return table.concat(links, ", ")
end

function p.error(msg)
    return '<span style="color:#ff4444; font-weight:bold; ' ..
           'background:#2a0000; padding:2px 6px;">' ..
           '⚠ ItemUtils Error: ' .. tostring(msg) ..
           '</span>'
end

return p