Module:Farmbox

From Against the Storm Official Wiki
Revision as of 02:00, 28 November 2023 by Aeredor (talk | contribs) (Created to display infoboxes on farming buildings' pages)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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

---
--- Module to create an infobox for displaying on a farm's wiki page.
---
--- Shows the facts from the data about the specified building in an easy-to-
--- read table, with a large icon, information, categories, and the flavor
--- text.
---
--- This should be invoked from Template:Farmbox with the parameter of the
--- building whose infobox should be shown. See the template documentation for
--- more information about parameters and errors and to see examples.
---
--- @module Farmbox
local Farmbox = {}



local Infobox = require("Module:Infobox")
local FarmsData = require("Module:FarmsData")



--region Private constants

local ARG_NAME = "name"

-- Subheading for all the buildings from this template.
local BUILDING_CATEGORY = "Farm Building"

local NBSP = " "

--endregion



--region Private methods

---
--- Builds using the provided wikiInfobox a subtable to lay out headers and
--- fields.
---
---@param wikiInfobox table mw.html object into which we're building this
---@param farmName string the name of the farm the infobox is about
---@return table the Mediawiki html object into which we've been adding things
local function makeInnerTable(wikiInfobox, farmName)

	-- Grab the data we'll use to populate this.
	local farmID = FarmsData.getFarmID(farmName)
	local farmCategory = FarmsData.getFarmCategory(farmName)
	local farmSizeX, farmSizeY = FarmsData.getFarmSize(farmName)
	local farmIsMovable = FarmsData.isFarmMovable(farmName)
	local farmIsEssential = FarmsData.isFarmInitiallyEssential(farmName)
	local farmStorageCap = FarmsData.getFarmStorage(farmName)
	local farmArea = FarmsData.getFarmArea(farmName)
	local farmConstructionTime = FarmsData.getFarmConstructionTime(farmName)
	local farmWorkplaces = FarmsData.getFarmNumberOfWorkplaces(farmName)
	local farmRequiredGoods = FarmsData.getAllFarmRequiredGoods(farmName)
	local farmRecipesTable = FarmsData.getAllFarmRecipes(farmName)

	-- Start the inner table
	local innerTable = wikiInfobox:tag("tr"):tag("td"):newline():tag("table"):css(Infobox.CSS_INNER_TABLE)
	innerTable:newline()

	-- Additional parameters would go here.

	-- Construction toolbar category.
	if farmCategory then

		local categoryIconFilename = Infobox.ICON_FILENAMES_CATEGORIES[farmCategory]
		if categoryIconFilename ~= nil then
			local categoryIconPart = "[[File:" .. categoryIconFilename .. "|" .. Infobox.ICONSIZE_MED .. "|alt=" .. farmCategory .. "]]"

			Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_TOP,
					Infobox.TITLE_CATEGORY, categoryIconPart .. NBSP .. farmCategory)
		end
	end
	-- Expand recipes into a small table
	if farmRecipesTable and #farmRecipesTable > 0 then

		local recipesRows = mw.getCurrentFrame():expandTemplate{ title="Recipe", args={
			building= farmName, display="list"	} }

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_BOT,
				Infobox.TITLE_RECIPES, recipesRows)
	end
	-- Since false is a valid value, have to directly check if it's nil.
	if farmIsMovable ~= nil then

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_TOP,
				Infobox.TITLE_MOVABLE, farmIsMovable and "Yes" or "No")
	end
	if farmIsEssential ~= nil then

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_BOT,
				Infobox.TITLE_ESSENTIAL, farmIsEssential and "Yes" or "No")
	end
	-- Combine sizes into one line
	if farmSizeX ~= nil and farmSizeY ~= nil then

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_TOP,
				Infobox.TITLE_SIZE, farmSizeX .. " × " .. farmSizeY)
	end
	if farmArea then

		Infobox.buildStandardRow(innerTable, "",
				Infobox.TITLE_FARMING_AREA, farmArea)
	end
	if farmStorageCap then

		Infobox.buildStandardRow(innerTable, "",
				Infobox.TITLE_STORAGE_CAPACITY, farmStorageCap)
	end
	if farmWorkplaces then

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_BOT,
				Infobox.TITLE_WORKPLACES, farmWorkplaces)
	end
	if farmConstructionTime then

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_TOP,
				Infobox.TITLE_CONSTRUCTION_TIME, farmConstructionTime)
	end
	-- Need to build a separate table to display building materials
	if farmRequiredGoods then

		local requiredGoodsRows = tostring( Infobox.writeRequiredGoodsRows(farmRequiredGoods) )

		Infobox.buildStandardRow(innerTable, Infobox.CSS_TR_BORDER_BOT,
				Infobox.TITLE_CONSTRUCTION_COST, requiredGoodsRows)

		innerTable:tag("tr"):css(Infobox.CSS_TR_BORDER_BOT)
	end
	if farmID then
		innerTable:tag("tr"):css(Infobox.CSS_TR_BORDER_TOP):css(Infobox.CSS_TR_BORDER_BOT)
				  :tag("th"):wikitext(Infobox.TITLE_ID):done()
				  :tag("td"):wikitext(farmID):done()
				  :done():newline()
	end

	-- Close the table.
	innerTable:done():newline()
	-- Close the table cell and row the inner table is in.
	wikiInfobox:done():done():newline()
end


--endregion



--region Public methods

---
-- Creates an html table to display the data in a floating box.
--
-- @param frame the template's calling context
-- @return wiki markup for the box
function Farmbox.renderFarmbox(frame)
	
	-- Every farm must have a name.
	local farmName = frame.args[ARG_NAME]
	if not farmName or farmName == "" then
		return "You must specify the name of the farm. See [[Template:Farmbox]] for examples."
	end

	-- Use this method here to check to see whether the provided name is valid.
	if not FarmsData.getAllDataForFarm(farmName) then
		return "Farmbox can't find the specified farm: " .. farmName .. "."
	end

	-- Additional template parameters would go here.

	-- Get the data to display.
	local farmDescription = FarmsData.getFarmDescription(farmName)
	local farmIconFilename = FarmsData.getFarmIcon(farmName)

	-- Make the top of the infobox that every one has...
	local wikiInfobox = mw.html.create("table"):css(Infobox.CSS_MAIN):newline()
	-- with a title...
	wikiInfobox:tag("tr")
			   :tag("th"):wikitext(farmName):done()
			   :done():newline()
	-- and a subtitle, showing the functional category...
	wikiInfobox:tag("tr")
			:tag("td"):wikitext(BUILDING_CATEGORY):done()
		:done():newline()
	-- and a large icon.
	if farmIconFilename then
		wikiInfobox:tag("tr")
				   :tag("td"):wikitext("[[File:" .. farmIconFilename .. "]]"):done()
				   :done():newline()
		wikiInfobox:tag("tr"):css(Infobox.CSS_TR_BORDER_BOT)
				   :tag("td"):wikitext(farmName .. ", as seen in-game"):done()
				   :done():newline()
	end
	
	makeInnerTable(wikiInfobox, farmName)

	-- Finish with the flavor text.
	if farmDescription then
		wikiInfobox:tag("tr"):css(Infobox.CSS_TR_BORDER_TOP)
				   :tag("td"):wikitext(farmDescription):done()
				   :done():newline()
	end
	
	return wikiInfobox
end

--endregion

return Farmbox