Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

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

local p = {}

local cargo = mw.ext.cargo
local html = mw.html
local recipeData = mw.loadData('Module:CraftingRecipe/RecipeData')
local categoryIcons = mw.loadData('Module:CraftingRecipe/CategoryIcons')
local stationIcons = mw.loadData('Module:CraftingRecipe/StationIcons')
local propertyIcons = mw.loadData('Module:CraftingRecipe/PropertyIcons')

local function lookupItem(pageName)
	if not pageName or pageName == "" or not cargo then return nil end
	
	local tables = "Items"
	local fields = "name, icon, page_name"
	local where = string.format("page_name = '%s'", pageName:gsub("'", "''"))
	
	local results = cargo.query(tables, fields, { where = where, limit = 1 })
	
	if results and #results > 0 then
		return results[1]
	end
	return nil
end

local function resolveData(args, prefix, index)
	local suffix = index and tostring(index) or ""
	local keyId = prefix .. suffix
	
	local id = args[keyId]
	if not id then return nil end
	
	local data = {
		id = id,
		name = args[keyId .. "_name"],
		icon = args[keyId .. "_icon"],
		link = nil,
		type = args[keyId .. "_type"] or "Object",
		transform = args[keyId .. "_transform"] or "Consume",
		amount = args[keyId .. "_amount"]
	}
	
	local searchName = data.name or id

	if data.type ~= "Category" and data.type ~= "Property" and prefix ~= "station" then
		local cargoData = lookupItem(searchName)
		if cargoData then
			data.name = data.name or cargoData.name
			data.icon = data.icon or cargoData.icon
			data.link = cargoData.page_name
		end
	end
	
	data.name = data.name or id

	if not data.icon then
		if prefix == "station" then
			local foundIcon = stationIcons[data.id]
			if foundIcon then
				data.icon = foundIcon .. "_Icon.webp"
			else
				data.icon = "Icon_World_Gears.png"
			end
		elseif data.type == "Category" then
			local foundIcon = categoryIcons[data.id]
			if foundIcon then
				data.icon = foundIcon .. "_Icon.webp"
			end
		elseif data.type == "Property" then
			local foundIcon = propertyIcons[data.id]
			if foundIcon then
				data.icon = foundIcon .. "_Icon.webp"
			end
		end
	end

	if not data.icon then
		data.icon = "Inv_Unknown_A.webp"
	end

	if not data.link then
		if data.type == "Category" then
			data.link = data.name .. " (Item Category)"
		elseif data.type == "Property" then
			data.link = data.name .. " (Item Property)"
		else
			data.link = data.name
		end
	end
	
	return data
end

local function getRecipeArgs(recipeId)
	local recipe = recipeData[recipeId]
	if not recipe then return nil end

	local args = {}

	if recipe.station then
		args.station = recipe.station
	end

	if recipe.ingredients then
		for i, v in ipairs(recipe.ingredients) do
			local k = "mat" .. i
			args[k] = v.id
			args[k .. "_type"] = v.type
			args[k .. "_name"] = v.name
			args[k .. "_transform"] = v.transform
		end
	end

	if recipe.results then
		for i, v in ipairs(recipe.results) do
			local k = "res" .. i
			args[k] = v.id
			args[k .. "_name"] = v.name
		end
	end

	return args
end

function p.lookup(frame)
	local recipeId = frame.args.recipe
	if not recipeId then return "" end

	local args = getRecipeArgs(recipeId)
	if not args then return "" end

	local mockFrame = {
		args = args,
		expandTemplate = function(self, t) return frame:expandTemplate(t) end
	}

	return p.row(mockFrame)
end

function p.table(frame)
	local recipes = frame.args.recipes
	if not recipes then return "" end

	local output = frame:expandTemplate{ title = 'CraftingTable/Header' }

	for recipeId in mw.text.gsplit(recipes, ",") do
		recipeId = mw.text.trim(recipeId)
		if recipeId ~= "" then
			local args = getRecipeArgs(recipeId)
			if args then
				local mockFrame = {
					args = args,
					expandTemplate = function(self, t) return frame:expandTemplate(t) end
				}
				output = output .. "\n" .. p.row(mockFrame)
			end
		end
	end

	output = output .. "\n" .. frame:expandTemplate{ title = 'CraftingTable/Footer' }
	return output
end

function p.row(frame)
	local args = frame.args
	local tr = html.create('tr')
	
	local res1 = resolveData(args, "res", 1) or resolveData(args, "result", nil)
	local productTd = tr:tag('td')
	
	if res1 then
		local templateArgs = {
			[1] = res1.link,
			name = res1.link,
			override_icon = res1.icon
		}
		productTd:wikitext(frame:expandTemplate{ title = 'MdItemIcon', args = templateArgs })
		
		if res1.amount and tonumber(res1.amount) > 1 then
			productTd:wikitext(" ×" .. res1.amount)
		end
	end

	local inputs = {}
	
	local station = resolveData(args, "station", nil)
	if station then
		station.isStation = true
		table.insert(inputs, station)
	end
	
	for i = 1, 5 do
		local item = resolveData(args, "mat", i)
		if item then table.insert(inputs, item) end
	end
	
	local maxColumns = 5
	local filledColumns = 0
	
	for _, item in ipairs(inputs) do
		if filledColumns < maxColumns then
			local td = tr:tag('td')
			
			if item.isStation then
				td:addClass('recipe-status-station')
			elseif item.transform == "Keep" or item.transform == "None" then
				td:addClass('recipe-status-keep')
			elseif item.transform == "Boost" then
				td:addClass('recipe-status-boost')
			end
			
			local templateArgs = {
				[1] = item.link,
				name = item.link,
				override_icon = item.icon
			}
			td:wikitext(frame:expandTemplate{ title = 'MdItemIcon', args = templateArgs })
			
			if item.amount and tonumber(item.amount) > 1 then
				td:tag('small'):wikitext(" (" .. item.amount .. ")")
			end
			
			filledColumns = filledColumns + 1
		end
	end
	
	if filledColumns < maxColumns then
		tr:tag('td')
			:attr('colspan', maxColumns - filledColumns)
			:css('background-color', 'transparent')
	end

	return tostring(tr)
end

function p.resolveRow(frame)
	local args = {}
	for k, v in pairs(frame.args) do
		args[k] = v
	end

	if args[1] then
		local recipeArgs = getRecipeArgs(args[1])
		if recipeArgs then
			for k, v in pairs(recipeArgs) do
				if args[k] == nil then
					args[k] = v
				end
			end
		end
	end

	local tr = html.create('tr')
	
	local res1 = resolveData(args, "res", 1) or resolveData(args, "result", nil)
	local productTd = tr:tag('td')
	
	if res1 then
		local templateArgs = {
			[1] = res1.link,
			name = res1.link,
			override_icon = res1.icon
		}
		productTd:wikitext(frame:expandTemplate{ title = 'MdItemIcon', args = templateArgs })
		
		if res1.amount and tonumber(res1.amount) > 1 then
			productTd:wikitext(" &times;" .. res1.amount)
		end
	end

	local inputs = {}
	
	local station = resolveData(args, "station", nil)
	if station then
		station.isStation = true
		table.insert(inputs, station)
	end
	
	for i = 1, 5 do
		local item = resolveData(args, "mat", i)
		if item then table.insert(inputs, item) end
	end
	
	local maxColumns = 5
	local filledColumns = 0
	
	for _, item in ipairs(inputs) do
		if filledColumns < maxColumns then
			local td = tr:tag('td')
			
			if item.isStation then
				td:addClass('recipe-status-station')
			elseif item.transform == "Keep" or item.transform == "None" then
				td:addClass('recipe-status-keep')
			elseif item.transform == "Boost" then
				td:addClass('recipe-status-boost')
			end
			
			local templateArgs = {
				[1] = item.link,
				name = item.link,
				override_icon = item.icon
			}
			td:wikitext(frame:expandTemplate{ title = 'MdItemIcon', args = templateArgs })
			
			if item.amount and tonumber(item.amount) > 1 then
				td:tag('small'):wikitext(" (" .. item.amount .. ")")
			end
			
			filledColumns = filledColumns + 1
		end
	end
	
	if filledColumns < maxColumns then
		tr:tag('td')
			:attr('colspan', maxColumns - filledColumns)
			:css('background-color', 'transparent')
	end

	return tostring(tr)
end

return p