Module:Media

From Zelda Wiki, the Zelda encyclopedia
Jump to: navigation, search

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

local File = require("Module:File")
local Franchise = require("Module:Franchise")
local i18n = require("Module:I18n")
local utilsError = require("Module:UtilsError")
local utilsLayout = require("Module:UtilsLayout")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

-- In the order in which they are to be presented, from left to right
local mediaTypes = {"Artwork", "Render", "Model", "Sprite", "Screenshot", "Map"}

-- Template:InfoField (deprecated - remove once all infoboxes are module-based)
function p._InfoboxCall(frame) 
	local args = frame.args
	local result = args["image"]
	if string.sub(args["image"], 1, 5) == "File:" then
		result = File.image(args["image"], { size = "320x320px", scale = 10 })
	end
	return result
end

-- 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 defaultTypeTab = 1
	local latestReleaseOverall = ""
	
	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 .. " " .. game
			remainingArgs[key] = nil
			
			local file = args[key]
			if utilsString.notEmpty(file) then
				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
					img, exists = File.image(file, {
						size = "320x320px",
						scale = mediaType == "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.
						scaleUsingCargo = true,
					})
				end
				table.insert(gameTabs, {
					label = game,
					content = img,
					tooltip = Franchise.shortName(game)
				})
				if not exists and mw.title.getCurrentTitle().nsText ~= "User" then
					local fileType = i18n.plural("files.types." .. string.lower(mediaType))
					table.insert(categories, "Articles Lacking Images")
					table.insert(categories, "Articles Lacking " .. fileType)
					table.insert(categories, string.format("Articles Lacking %s Images", 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
				end
				if exists and release and release > latestReleaseOverall then
					latestReleaseOverall = release
					defaultTypeTab = #typeTabs + 1
				end
			end
		end
		if #gameTabs > 0 then
			local typeTabContent = utilsLayout.tabs(gameTabs, {
				default = defaultGameTab,
				align = "center",
				tabOptions = {
					position = "bottom",
					columns = 5,
				},
				contentOptions = {
					fixedWidth = 320,
					fixedHeight = 320,
					alignVertical = "center",
				}
			})
			table.insert(typeTabs, {
				label = mediaType,
				tooltip = i18n.getString("captions." .. mediaType),
				content = typeTabContent
			})
		end
	end
	
	local invalidKeys = utilsTable.keys(remainingArgs)
	if #invalidKeys > 0 then
		local msg = string.format("The following keys use an invalid media type or game code: <code>%s</code><p>For a list of valid types, see [[Template:Media]]. For a list of valid games, see [[Module:Franchise]].</p>", utilsTable.print(invalidKeys))
		utilsError.warn(msg)
		table.insert(categories, "Pages with Invalid Arguments")
	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 
		utilsError.warn("Non-canon or ambiguously canon games must not be displayed alongside canon games: ".. utilsMarkup.code(utilsTable.print(nonCanonGames)))
		table.insert(categories, "Pages with Invalid Arguments")
	end
	
	local tabs = utilsLayout.tabs(typeTabs, {
		default = defaultTypeTab,
		align = "center",
		tabOptions = {
			columns = 4,
		}
	})
	return tabs .. utilsMarkup.categories(categories)
end

i18n.loadStrings({
	en = {
		captions = {
			Artwork = "Official artwork provided by Nintendo",
			Map = "In-game map of an area",
			Model = "In-game models",
			Render = "Official models provided by Nintendo",
			Screenshot = "In-game screenshots",
			Sprite = "In-game sprites or icons"
		}
	}
})

return p