Module:Sandbox/User:Californ1a/T/Professions

From Brighter Shores Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Sandbox/User:Californ1a/T/Professions/doc

require('strict')
require('Module:Mw.html extension')
local pt = require('Module:Paramtest')
local yn = require('Module:Yesno')
local lang = mw.language.getContentLanguage()
local p = {}

local icon_size = 20
local ep_icon_size = 16

-- List episodes with their professions
local episodes = {
	{
		free = true,
		name = 'Hopeport',
		color = '#b99f46',
		professions = {'guard', 'chef', 'fisher', 'forager', 'alchemist'},
	}, {
		free = true,
		name = 'Hopeforest',
		color = '#84b876',
		professions = {'scout', 'gatherer', 'woodcutter', 'carpenter'},
	}, {
		name = 'Mine of Mantuban',
		color = '#68ABF1',
		professions = {'minefighter', 'bonewright', 'miner', 'blacksmith', 'stonemason'},
	}, {
		name = 'Crenopolis',
		color = '#979797',
		professions = {'watchperson', 'detective', 'leatherworker', 'merchant'},
	}, {
		released = false,
		name = 'Stonemaw Hill',
		color = '#C57F41',
		professions = {'shieldbearer', 'builder', 'armorer', 'delver'},
	}, {
		released = false,
		name = 'Bleakholm Crags',
		color = '#68ABF1',
		professions = {},
	},
}

-- Get professions levels given an episode order number
function p.filter_by_episode(professions, episodeOrder)
	local filtered = {}
	local episodeProfessions = episodes[episodeOrder].professions

	-- Add the professions and the total for the episode
	for _, profession in ipairs(episodeProfessions) do
		if professions[profession] ~= nil then
			filtered[profession] = professions[profession]
		end
	end

	-- Add the total for the episode
	local ep_name = episodes[episodeOrder].name:lower()
	if professions[ep_name] ~= nil then
		filtered[ep_name] = professions[ep_name]
	end

	return filtered
end

-- Template entrypoint
function p.main(frame)
	return p._main(frame:getParent().args)
end

function p._main(args)
	-- Create main profession and goals lists
	local professions = {
		total = 0
	}
	local goals = {}
	
	-- Build the professions + goals lists
	for i, episode in ipairs(episodes) do
		local ep_name = episode.name:lower()
		professions[ep_name] = 0
		for _, profession in ipairs(episode.professions) do
			-- Add the profession and goal to their respective lists
			professions[profession] = pt.default_to(tonumber(args[profession]), 0)
			goals[profession] = pt.default_to(tonumber(args[profession..' goal']), 0)
			
			-- Add this profession's level to the episode's total
			local value = professions[profession] or 0
			professions[ep_name] = professions[ep_name] + value
		end
		-- Add this episode's total to the overall total
		professions.total = professions.total + professions[ep_name]
	end
	
	-- Non-profession config params
	local other = {
		vertical = yn(pt.default_to(args.vertical, true), true),
		free = yn(pt.default_to(args.free, false), false),
		date = pt.default_to(args.date, ''),
		right = yn(pt.default_to(args.right, false), false),
		infobox = yn(pt.default_to(args.infobox, false), false),
	}
	
	--local debug_str = '<pre>'..mw.text.jsonEncode(professions, mw.text.JSON_PRETTY)..', '..mw.text.jsonEncode(goals, mw.text.JSON_PRETTY)..'</pre>'

	return tostring(p.create_table(professions, goals, other))--..debug_str
end

function p.create_row(tbl, episodeOrder, professions, goals, vertical)
	if vertical then
		tbl:tag('tr')
	end
	
	-- Create icons
	local cache = {}
	for _,profession in ipairs(episodes[episodeOrder].professions) do
		local PRO = pt.ucflc(profession)
		local size = icon_size
		if profession == 'alchemist' then -- Alchemist icon is a bit larger than others
			size = icon_size - 5
		end
		local icon = mw.ustring.format('[[File:%s small icon.png|link=%s|%spx]]', PRO, PRO, size)
		cache[profession] = {
			name = PRO,
			icon = icon
		}
		if vertical then
			tbl:tag('td')
				:css({border='none'})
				:wikitext(icon)
			:done()
		end
	end
	
	if vertical then
		tbl:done() -- /tr
	end
	tbl:tag('tr')
	
	-- Create levels
	for _, profession in ipairs(episodes[episodeOrder].professions) do
		local PRO = cache[profession].name
		local lvl = tostring(professions[profession])
		if goals[profession] ~= 0 then
			lvl = lvl..'/'..tostring(goals[profession])
		end
		
		if vertical then
			tbl:tag('td')
				:css({border='none'})
				:wikitext(lvl)
			:done()
		else
			tbl:tag('td')
				:wikitext(cache[profession].icon..' '..lvl)
			:done()
		end
	end
	
	return tbl:done()
end

function p.create_episode_table(episodeOrder, professions, goals, other)
	local ep_professions = episodes[episodeOrder].professions
	local profession_count = #ep_professions
	local EP = episodes[episodeOrder].name
	local ep_name = episodes[episodeOrder].name:lower()
	local out = mw.html.create('tr'):tag('td'):tag('table')
		:addClass('center')
		:IF(other.infobox)
			:addClass('infobox')
			:addClass('infobox-'..EP:gsub(' ', '_'))
			:css({
				margin = '0',
				['table-layout'] = 'auto',
				width = '100%',
				float = 'unset',
			})
		:ELSE()
			:addClass('wikitable')
			:css({margin='0', padding='0'})
		:END()
		:tag('tr')
			:tag('th')
				:IF(other.infobox)
					:addClass('infobox-header')
					:css({padding='0.5em'})
				:ELSE()
					:css({
						['background-color'] = episodes[episodeOrder].color,
						padding='0 0.5em',
					})
				:END()
				:attr({colspan = profession_count})
				:wikitext(mw.ustring.format('[[File:%s episode icon.png|link=%s|%spx]] [[%s]] (%s)', EP, EP, ep_icon_size, EP, professions[ep_name]))
			:done()
		:done()
		
	out = p.create_row(out, episodeOrder, professions, goals, other.vertical)
	
	return out:done():done():done() -- /table /td /tr
end

local function getReleasedEpisodes()
	local filtered = {}
	for i, episode in ipairs(episodes) do
		if episode.released ~= false then
			table.insert(filtered, episode)
		end
	end
	return filtered
end

function p.create_table(professions, goals, other)
	local ep_tbl = {}
	local released_episodes = getReleasedEpisodes()
	for i in ipairs(released_episodes) do
		local ep_lvls = p.filter_by_episode(professions, i)
		local ep_goals = p.filter_by_episode(goals, i)
		table.insert(ep_tbl, p.create_episode_table(i, ep_lvls, ep_goals, other))
	end
	
	local out = mw.html.create('table')
		:tag('caption')
			:css({['font-weight']='bold'})
			:wikitext(mw.ustring.format('[[File:Professions icon.png|link=Professions|%spx]] [[Professions]] (%s)', ep_icon_size, professions.total))
		:done()
		
		
	for i, tbl in ipairs(ep_tbl) do
		if (not other.free and episodes[i].free ~= true)
			or episodes[i].free == true then
			out:node(tbl)
		end
	end
		
	if pt.has_content(other.date) then
		out:tag('tr')
			:tag('td')
				:css({['text-align']='center'})
				:tag('small')
					:tag('b')
						:wikitext('Last Updated:')
					:done()
					:tag('br'):done()
					:IF(other.date == 'now')
						:wikitext(lang:formatDate('j F Y', mw.getCurrentFrame():preprocess('{{REVISIONTIMESTAMP}}')))
					:ELSE()
						:wikitext(other.date)
					:END()
				:done()
			:done()
		:done()
	end
		
	out:allDone()
	
	local div = out
	if other.right then
		div = mw.html.create('div')
			:css({float='right'})
			:node(out)
		:done()
	end
	
	return div
end

return p