Module:Media

-- This modules serves as the code for Template:Media. local p = {} local h = {}

local File = require("Module:File") local Franchise = require("Module:Franchise") local utilsLayout = require("Module:UtilsLayout") local utilsMarkup = require("Module:UtilsMarkup") local utilsTable = require("Module:UtilsTable")

local CAT_INVALID_ARGS = require("Module:Constants/category/invalidArgs")

-- In the order in which they are to be presented, from left to right local mediaTypes = { {		type = "Artwork", category = "Artwork", description = "Official artwork provided by Nintendo", },	{		type = "Render", category = "Renders", description = "Official models provided by Nintendo", },	{		type = "Model", category = "Models", description = "In-game models", },	{		type = "Sprite", category = "Sprites", description = "In-game sprites or icons", },	{		type = "Screenshot", category = "Screenshots", description = "In-game screenshots", },	{		type = "Map", category = "Maps", description = "In-game map of an area", }, }

-- Template:Media function p.Main(frame) local args = frame:getParent.args return p.main(args) end

function p.main(args) local remainingArgs = utilsTable.clone(args) local categories = {} local games = {} local typeTabs = {} local typeTabWithLatestRelease = 1 local latestReleaseOverall = "" local fileCount = 0 local latestImagePerType = {} for _, mediaType in ipairs(mediaTypes) do		local gameTabs = {} local defaultGameTab = 1 local latestReleaseForType = "" for i, game in ipairs(Franchise.enum({ includeSeries = true, includeGroups = true })) do local key = mediaType.type .. " " .. game remainingArgs[key] = nil local file = args[key] if file ~= nil and file ~= "" then fileCount = fileCount + 1 table.insert(games, game) local img, exists if utilsMarkup.containsLink(file) or file ~= mw.text.killMarkers(file) then -- if user specified markup, simply render the markup as-is. img = file exists = true else if not string.find(file, "^File:") then h.warn(string.format("Invalid filename . Filenames must start with  .", file)) table.insert(categories, CAT_INVALID_ARGS) file = "File:"..file end img, exists = File.image(file, {						size = "320x320px",						scale = mediaType.type == "Sprite" and 10 or nil, -- For sprites, scale to a maximum of 10x its original size. Only done for sprites due to scaling being somewhat expensive.						isPixelArt = mediaType.type == "Sprite" or Franchise.graphics(game) == "2D"					}) end table.insert(gameTabs, {					label = game,					content = img,					tooltip = Franchise.shortName(game)				}) if not exists and mw.title.getCurrentTitle.nsText ~= "User" then table.insert(categories, "Articles lacking files") table.insert(categories, "Articles lacking " .. mediaType.category) table.insert(categories, string.format("%s articles lacking files", Franchise.shortName(game))) end local release = Franchise.releaseDate(game) -- empty string here means an unreleased game. This ensures the unreleased is sorted last. -- the 'i' is appended to ensure that multiple unreleased games are sorted in canon order. if release == "" then release = "unreleased"..i				end if exists and release and release > latestReleaseForType then latestReleaseForType = release defaultGameTab = #gameTabs latestImagePerType[#typeTabs + 1] = file end if exists and release and release > latestReleaseOverall then latestReleaseOverall = release typeTabWithLatestRelease = #typeTabs + 1 end end end if #gameTabs > 0 then table.insert(typeTabs, {				label = mediaType.type,				tooltip = mediaType.description,				gameTabs = gameTabs,				defaultGameTab = defaultGameTab,			}) end end remainingArgs["defaultTypeTab"] = nil local defaultTypeTab = utilsTable.findIndex(typeTabs, function(typeTab)		return typeTab.label == args.defaultTypeTab	end) defaultTypeTab = defaultTypeTab or typeTabWithLatestRelease

local invalidKeys = utilsTable.keys(remainingArgs) if #invalidKeys > 0 then local msg = string.format("The following keys use an invalid media type or game code: For a list of valid types, see Template:Media. For a list of valid games, see Module:Franchise. ", utilsTable.print(invalidKeys)) h.warn(msg) table.insert(categories, CAT_INVALID_ARGS) end local gamesByCanonicity = utilsTable.groupBy(games, Franchise.canonicity) local canonGames = gamesByCanonicity["canon"] or {} local nonCanonGames = utilsTable.concat(gamesByCanonicity["non-canon"] or {}, gamesByCanonicity["ambiguous"] or {}) if #canonGames > 0 and #nonCanonGames > 0 then h.warn("Non-canon or ambiguously canon games must not be displayed alongside canon games: ".. utilsMarkup.code(utilsTable.print(nonCanonGames))) table.insert(categories, CAT_INVALID_ARGS) end local content if #typeTabs == 1 and #typeTabs[1].gameTabs == 1 then content = typeTabs[1].gameTabs[1].content else for i, typeTab in ipairs(typeTabs) do			typeTab.content = utilsLayout.tabs(typeTab.gameTabs, {				default = typeTab.defaultGameTab,				align = "center",				tabOptions = {					position = "bottom",					columns = 5,				},				contentOptions = {					alignVertical = "center",					fixedHeight = true,				}			}) end content = utilsLayout.tabs(typeTabs, {			default = defaultTypeTab,			align = "center",			tabOptions = {				columns = 4,			},		}) end local pageImage = latestImagePerType[defaultTypeTab] if pageImage then -- Set the file under the default type and game tab as the article's representative image for page previews mw.ext.seo.set({			image = pageImage		}) end return content .. utilsMarkup.categories(categories) end

function h.warn(msg) local utilsError = require("Module:UtilsError") utilsError.warn(msg) end

return p