模組:Infobox VG/sandbox

local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")

local function has_content(arg)
    return arg ~= nil and arg ~= ""
end

local function get_wikidata_data(args, id)
    local opts = {id}
    opts.fetchwikidata = has_content(args.fetchwikidata) and args.fetchwikidata or "ALL"
    opts.suppressfields = has_content(args.suppressfields) and args.suppressfields or nil
    opts.onlysourced = has_content(args.onlysourced) and args.onlysourced or "yes"
    opts.qid = has_content(args.qid) and args.qid or nil
    opts.refs = has_content(args.refs) and args.refs or "no"
    opts.noicon = has_content(args.noicon) and args.noicon or "no"
    return require("Module:WikidataIB")._getValue(opts)
end

local function collapse(header, content)
    if has_content(header) then
        return mw.getCurrentFrame():expandTemplate {
            title = "Infobox VG/C",
            args = {header, content}
        }
    end
    return content
end

local function get_header_params(param)
    if mw.ustring.find(param, "_") then
        return {param .. " header"}
    end
    if mw.ustring.find(param, " ") then
        return {param .. " header"}
    end
    return {param .. " header", param .. "_header"}
end

local p = {}

-- 信息框式样
local infobox_styles = {
    captionstyle = "text-align: center;",
    subheaderstyle = "text-align: center; vetical-align: middle; font-weight: normal;",
    labelstyle = "white-space: nowrap;"
}

-- 标题和外文名参数
local headers = function(args)
    local result = {}
    local all_parameters = {"title", "original", "japanese", "english", "english2"}

    -- 主标题
    if has_content(args.title) then
        result.above = args.title
    else
        result.above = mw.ustring.gsub(tostring(mw.title.getCurrentTitle().rootText), " %([^)]+%)$", "")
    end

    -- 外文标题
    local foreign_titles = {}
    if has_content(args.original) then
        local str = args.original
        if mw.ustring.find(str, ":") then
            str = mw.ustring.gsub(str, "^([^:]-):(.+)$", '-{<span lang="%1" xml:lang="%1">%2</span>}-')
        end
        table.insert(foreign_titles, str)
    end
    if has_content(args.japanese) then
        local str = '-{<span lang="ja" xml:lang="ja">' .. args.japanese .. "</span>}-"
        table.insert(foreign_titles, str)
    end
    if has_content(args.english) then
        local str = '-{<span lang="en" xml:lang="en">\'\'' .. args.english .. "''</span>}-"
        table.insert(foreign_titles, str)
    end
    if has_content(args.english2) then
        local str = '-{<span lang="en" xml:lang="en">\'\'' .. args.english2 .. "''</span>}-"
        table.insert(foreign_titles, str)
    end

    if table.maxn(foreign_titles) > 0 then
        local str = require("Module:List").unbulleted(foreign_titles)
        result.subheader1 = str
    end

    -- Done
    return result, all_parameters
end

-- 图像与图注参数
local images = function(args)
    local varieties = {"", "-hans", "-hant", "-cn", "-hk", "-mo", "-my", "-sg", "-tw"}
    local result, all_parameters = {}, {}

    -- image系、alt系参数
    local infobox_image_params = {}
    for _, v in ipairs(varieties) do
        local add_para = function(prefix)
            local para = prefix .. v
            table.insert(all_parameters, para)
            infobox_image_params[para] = args[para]
        end
        add_para("image")
        add_para("alt")
    end

    -- 图像尺寸参数
    local image_size_paras = {"image_size", "image size", "imagesize"}
    for _, v in ipairs(image_size_paras) do
        table.insert(all_parameters, v)
    end
    for _, v in ipairs(image_size_paras) do
        if has_content(args[v]) then
            infobox_image_params.size = args[v]
            break
        end
    end
    infobox_image_params.sizedefault = "frameless"

    result.image = require("Module:InfoboxImageVariant2")._main(infobox_image_params)

    -- 图注参数
    table.insert(all_parameters, "caption")
    result.caption = args.caption

    -- Done
    return result, all_parameters
end

-- 常规栏位参数
local fields = function(args)
    local result, all_parameters = {}, {}

    -- 参数配置
    local subgroup_header = {"街机参数"}
    local params = {
        official = {"[[官方译名]]", alias = {}},
        common = {"常用译名", alias = {}},
        genre = {"[[电子游戏类型|类型]]", alias = {}, wd = "P136"},
        platforms = {"[[系统平台|平台]]", alias = {"platform"}, wd = "P400"},
        developer = {"[[游戏开发者|开发商]]", alias = {}, wd = "P178"},
        publisher = {"[[電子遊戲發行商|发行商]]", alias = {}, wd = "P123"},
        director = {"总监", alias = {}, wd = "P57"},
        producer = {"[[電子遊戲製作人|制作人]]", alias = {}, wd = "P162"},
        designer = {"[[电子游戏设计|设计师]]", alias = {}, wd = "P287"},
        writer = {"编剧", alias = {}, wd = "P50"},
        programmer = {"[[游戏程序师|-{zh-cn:程序; zh-tw:程式;}-]]", alias = {}, wd = "P943"},
        artist = {"[[游戏美工|美术]]", alias = {}, wd = "P3080"},
        composer = {"音乐", alias = {}, wd = "P86"},
        series = {"系列", alias = {}, wd = "P179"},
        engine = {"[[游戏引擎|引-{}-擎]]", alias = {}, wd = "P408"},
        modes = {"模式", alias = {}, wd = "P404"},
        released = {"发行日", alias = {"release"}, wd = "P577"},
        shutdown = {"停运日", alias = {}},
        -- 街机参数
        cabinet = {"框体", alias = {}, subgroup = 1},
        arcade_system = {"[[街机主板|主板]]", alias = {}, subgroup = 1},
        cpu = {"[[中央处理器|CPU]]", alias = {}, subgroup = 1},
        sound = {"音效", alias = {}, subgroup = 1},
        display = {"显示", alias = {}, subgroup = 1}
    }
    local param_order = {
        "official",
        "common",
        "genre",
        "platforms",
        "developer",
        "publisher",
        "director",
        "producer",
        "designer",
        "writer",
        "programmer",
        "artist",
        "composer",
        "series",
        "engine",
        "modes",
        "released",
        "shutdown",
        "cabinet",
        "arcade_system",
        "cpu",
        "sound",
        "display"
    }

    -- 启用网络游戏参数时的修正
    table.insert(all_parameters, "onlinegame")
    if yesno(args.onlinegame, false) then
        params.publisher[1] = "-{zh-cn:运营; zh-tw:營運;}-商"
        params.released[1] = "-{zh-cn:运营; zh-tw:營運;}-日"
    end

    -- 将空格分隔字段名作为别名
    for _, v in ipairs(param_order) do
        local alias_temp = params[v].alias
        table.insert(alias_temp, 1, v)

        local alias = {}
        for _, w in ipairs(alias_temp) do
            table.insert(alias, w)
            if mw.ustring.find(w, "_") then
                local str = mw.ustring.gsub(w, "_", " ")
                table.insert(alias, str)
            end
        end
        params[v].alias = alias
    end

    -- 根据参数名读取标签和资料
    local wikidata_args = {"fetchwikidata", "suppressfields", "onlysourced", "qid", "refs", "noicon"}
    for _, v in ipairs(wikidata_args) do
        table.insert(all_parameters, v)
    end

    local function get_label_and_data(param)
        local info = params[param]

        local label, data, subgroup = info[1], nil, (info.subgroup or 0)
        for _, v in ipairs(info.alias) do
            data = args[v]
            if has_content(data) then
                for _, w in ipairs(get_header_params(v)) do
                    if has_content(args[w]) then
                        data = collapse(args[w], data)
                        break
                    end
                end
                return label, data, subgroup
            end
        end

        -- 指定为空字串值时返回空值
        if data == "" then
            return
        end

        -- 尝试读取wikidata资料
        if info.wd == nil then
            return
        end

        local data = get_wikidata_data(args, info.wd)
        if has_content(data) then
            return label, data, subgroup
        end
    end

    -- 返回给Infobox的字段信息
    local num, previous_subgroup = 0, 0
    for _, v in ipairs(param_order) do
        local label, data, subgroup = get_label_and_data(v)
        if label ~= nil then
            -- 处理header
            if subgroup > previous_subgroup then
                num = num + 1
                result["header" .. tostring(num)] = subgroup_header[subgroup]
                previous_subgroup = subgroup
            end
            -- 处理常规参数
            num = num + 1
            result["label" .. tostring(num)] = label
            result["data" .. tostring(num)] = data
        end
    end

    -- 返回给Check for unknown parameters的合法参数名称
    for _, v in ipairs(param_order) do
        for _, w in ipairs(params[v].alias) do
            table.insert(all_parameters, w)
            -- 加入header参数
            for _, x in ipairs(get_header_params(w)) do
                table.insert(all_parameters, x)
            end
        end
    end

    -- Done
    return result, all_parameters
end

function p.main(frame)
    local args = getArgs(frame, {removeBlanks = false})
    return p._main(args)
end

function p._main(args)
    local result = nil
    local params, all_parameters = {}, {}

    -- 模板式样
    for k, v in pairs(infobox_styles) do
        params[k] = v
    end

    local x = fields(args)

    -- 参数
    local funcs = {headers, images, fields}
    for _, f in ipairs(funcs) do
        local params_temp, all_parameters_temp = f(args)
        for k, v in pairs(params_temp) do
            params[k] = v
        end
        for _, v in ipairs(all_parameters_temp) do
            table.insert(all_parameters, v)
        end
    end

    -- 模板本体
    local temp = ""
    temp = tostring(require("Module:Infobox").infobox(params))

    -- 未知参数检查
    all_parameters.unknown = mw.title.getCurrentTitle().namespace == 0 and "[[Category:含有废弃电子游戏信息框参数的条目|_VALUE_]]" or ""
    all_parameters.preview = "本頁<code>{{[[Template:Infobox VG|Infobox VG]]}}</code>使用了未知參數<code>_VALUE_</code>"
    temp = temp .. tostring(require("Module:Check for unknown parameters 2")._check(all_parameters, args))

    -- 可能使用旗帜的Infobox_VG
    local file_ptns = {}
    table.insert(file_ptns, "%[%[%s*[Ff][Ii][Ll][Ee]%s*:")
    table.insert(file_ptns, "%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:")
    table.insert(file_ptns, "%[%[%s*文件%s*:")
    table.insert(file_ptns, "%[%[%s*[档檔]案%s*:")
    table.insert(file_ptns, "%[%[%s*[图圖]像%s*:")

    local function used_image()
        if mw.title.getCurrentTitle().namespace ~= 0 then
            return false
        end
        for _, v in pairs(all_parameters) do
            if mw.ustring.sub(v, 1, 5) ~= 'image' then
                for _, w in pairs(file_ptns) do
                    if mw.ustring.match(mw.getCurrentFrame():preprocess(args[v]), w) then
                        return true
                    end
                end
            end
        end
        return false
    end
     
    if used_image() then
        temp = temp .. '[[Category:可能在电子游戏信息框中使用旗帜的条目]]'
    end

    -- Done
    return temp
end

return p