Module:Release

local p = {} local h = {}

local Franchise = require("Module:Franchise") local utilsArg = require("Module:UtilsArg") local utilsCargo = require("Module:UtilsCargo") local utilsMarkup = require("Module:UtilsMarkup") local utilsRegion = require("Module:UtilsRegion") local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable")

local data = mw.loadData("Module:Releases/Data")

local TABLES = { Games = "GameReleases" } local FIELDS = { Games = { game = "String", system = "String", service = "String", program = "String", region = "String", date = "Date", reference = "Wikitext", } }

function p.CargoDeclare(frame) local medium = frame.args[1] return utilsCargo.declare(TABLES[medium], FIELDS[medium]) end

function p.CargoStore(frame) local medium = frame.args[1] local args, err = utilsArg.parse(frame:getParent.args, p.Templates["Game Releases/Store"]) if err then return utilsMarkup.categories(err.categories) end local rows = {} for _, region in ipairs(data.regions) do		if args[region.param] then local row = utilsTable.merge({}, args, {				region = region.code,				date = args[region.param],				reference = args[region.param .. "R"],			}) utilsCargo.store(TABLES[medium], row) table.insert(rows, row) end end return h.printReleases(medium, rows) end

function p.Releases(frame) return p.printReleases(frame.args[1], frame:getParent.args[1]) end

function p.printReleases(medium, title) local releases = h.fetchReleases(medium, title) local result = h.printReleases(medium, releases) return result end

function h.fetchReleases(medium, title) local tbl = TABLES[medium] local fields = utilsTable.keys(FIELDS[medium]) local query = { where = utilsCargo.allOf({ title = title }) }	local queryResults = utilsCargo.query(tbl, table.concat(fields, ","), query) return queryResults end

function h.evaluateReleases(medium, releases) local releasesByName = utilsTable.groupBy(releases, h.labelers[medium]) local sortedReleasesByName = {} for k, v in pairs(releasesByName) do		local sortedIndex = h.sorters[medium](v[1]) sortedReleasesByName[sortedIndex] = { name = k,			regionDates = v		} end return utilsTable.compact(sortedReleasesByName) end

function h.printReleases(medium, releases) releases = h.evaluateReleases(medium, releases) for i, release in ipairs(releases) do		local dates = {} local regionDates = utilsTable.keyBy(release.regionDates, "region") for _, region in ipairs(data.regions) do			local regionCode = data.regionsByParam[region.param].code local regionDate = regionDates[regionCode] if regionDate then local formattedDate = mw.language.getContentLanguage:formatDate("M d, Y", regionDate.date) local date = utilsRegion.flag(regionCode) .. " " .. formattedDate if not utilsString.isEmpty(regionDate.reference) then date = date .. mw.getCurrentFrame:extensionTag("ref", regionDate.reference) end table.insert(dates, date) end end releases[i] = utilsTable.concat({release.name}, dates) end return utilsMarkup.definitionList(releases, {		class = "releases"	}) end

-- GAMES

function h.labelGameRelease(release) local label if not utilsString.isEmpty(release.service) then label = data.Games.services[release.system][release.service].displayName else label = data.Games.systemsByCode[release.system].name end if not utilsString.isEmpty(release.program) then label = label .. (" (%s)"):format(data.Games.programs[release.system][release.program]) end return label end

function h.sortGameRelease(release) return utilsTable.keyOf(data.Games.systemCodes, release.system) end

h.labelers = { Games = h.labelGameRelease, } h.sorters = { Games = h.sortGameRelease, }

local regionParams = {} local regionParamsOrder = {} for _, region in ipairs(data.regions) do	regionParams[region.param] = { type = "string", desc = "Release date in " .. utilsRegion.region(region.code), trim = true, }	regionParams[region.param .. "R"] = { type = "string", desc = "Source reference for release date.", inline = true, trim = true, }	table.insert(regionParamsOrder, region.param) table.insert(regionParamsOrder, region.param .. "R") end

p.Templates = { ["Game Releases/Store"] = { wip = true, purpose = "Store information about game releases.", storesData = "Data:Releases/Games", format = "block", paramOrder = utilsTable.concat({1, 2, 3, 4}, regionParamsOrder), params = { [1] = {				name = "game", type = "string", required = true, enum = Franchise.enum, desc = "Game identifier.", inline = true, trim = true, },			[2] = {				name = "system", type = "string", required = true, enum = data.Games.systemCodes, desc = "Console or handheld that the game was released for.", inline = true, trim = true, },			[3] = {				name = "service", type = "string", enumDependsOn = "system", enum = function(system) return utilsTable.keys(data.Games.services[system] or {}) end, desc = "Software through which this game release is offered (e.g. Virtual Console).", inline = true, canOmit = true, trim = true, },			[4] = {				name = "program", type = "string", enumDependsOn = "system", enum = function(system) return utilsTable.keys(data.Games.programs[system] or {}) end, desc = "Loyalty program through which this release is offered (e.g. Nintendo 3DS Ambassador Program).", inline = true, canOmit = true, trim = true, }		}	} }

utilsTable.merge(p.Templates["Game Releases/Store"].params, regionParams)

return p