Module:Distribution

local util_args = require('Module:ArgsUtil') local util_math = require('Module:MathUtil') local util_table = require('Module:TableUtil') local util_text = require('Module:TextUtil') local m_region = require('Module:Region') local m_country = require('Module:Country') local Role = require('Module:Role')

local h = {} local p = {}

function p.main(frame) local args = util_args.merge local regions = h.getRegions(args.regions, args.format, args.sep) local colors = h.getColors(regions, args.colors) local roundData = h.getRoundData(args, colors, #regions) return h.makeOutput(regions, colors, roundData) end

function h.getRegions(regionArg, regionType, sep) local regions = util_text.split(regionArg, sep or '%s*;%s*') h.formatRegions(regions, regionType) return regions end

function h.formatRegions(regions, regionType) if not regionType then return end local regionTypes = util_text.split(regionType,'%s*;%s*') if #regionTypes == 1 then h.formatRegionsConstant(regions, regionTypes[1]) else h.formatRegionsVariable(regions, regionTypes) end end

function h.formatRegionsConstant(regions, regionType) for k, v in ipairs(regions) do		regions[k] = h.formatOneRegion(regions[k], regionType:lower) end end

function h.formatRegionsVariable(regions, regionTypes) for k, v in ipairs(regions) do		regions[k] = h.formatOneRegion(regions[k], regionTypes[k]:lower) end end

function h.formatOneRegion(region, regionType) if regionType == 'region' then return m_region.rightmedium(region) elseif regionType == 'flag' then return m_country.onlyimage(region) elseif regionType == 'country' then return m_country.rightlong(region) elseif regionType == 'role' then return Role(region):flair else return region end end

function h.getColors(regions, colorArg) local lookup = util_text.split(colorArg) local tbl = {} for k, v in ipairs(regions) do		tbl[k] = lookup[v] or h.getHSLColor(k) end return tbl end

function h.getHSLColor(k) return ('hsl(%s,%s%%,%s)'):format(		math.fmod((k-1) * 20,360),		100 - math.floor((k-1) / 18) * 30,		h.getPercentage(k)	) end

function h.getPercentage(k) return ('calc( var(--distribution-constant) var(--distribution-slope) * %s%% )'):format(math.floor((k-1) / 18)) end

function h.getRoundData(args, colors, n)	local rounds = util_text.split(args.rounds,'%s*;%s*') for _, round in ipairs(rounds) do		rounds[round] = h.getOneRoundData(args[round], colors, n)	end return rounds end

function h.getOneRoundData(arg, colors, n)	local values = util_text.split(arg,'%s*;%s*') local widths = h.getRowWidths(values) h.setLastItem(values, colors, n)	return h.makeRoundTableFromValues(values, widths, colors) end

function h.makeRoundTableFromValues(values, widths, colors) local ret = {} for i, val in ipairs(values) do		ret[#ret+1] = h.getOneRoundValue(val, widths[i], colors[i]) end return ret end

function h.getOneRoundValue(val, width, color) return { text = val, width = width, color = color, } end

function h.getRowWidths(row) local total_width = h.getTotalWidth(row) local widths = {} for k, v in ipairs(row) do		local v = tonumber(v) or 1 widths[k] = util_math.roundnum(v / total_width * 100, .01) end return widths end

function h.setLastItem(values, colors, n)	if #values > n then colors[#colors+1] = 'transparent' values[#values] = 'TBD' end end

function h.getTotalWidth(row) local total_width = 0 for _, v in ipairs(row) do		total_width = total_width + (tonumber(v) or 1) end return total_width end

function h.makeOutput(regions, colors, roundData) local tbl = mw.html.create('table') :addClass('wikitable') :addClass('player-distribution') :css({ width = '100%' }) h.printTitleRow(regions, colors, tbl) for _, v in ipairs(roundData) do		local tr = h.printRowAndTitle(tbl, v)		local th = h.printOuterCell(tr, #regions) if roundData[v] then h.printRound(th, roundData[v], #regions) end end return tbl end

function h.printTitleRow(row, colors, tbl) local tr = tbl:tag('tr') tr:tag('th') for k, v in ipairs(row) do		if v ~= '' then tr:tag('td') :addClass('distribution-heading') :addClass('distribution-cell') :css({					width = util_math.roundnum(100 / #row, .01) .. '%',					['background-color'] = colors[k]				}) :wikitext(v) :attr('data-distribution-key', k)		end end return end

function h.printRowAndTitle(tbl, v)	local tr = tbl:tag('tr') tr:tag('th') :wikitext(v) return tr end

function h.printOuterCell(tr, colspan) local td = tr:tag('td'):attr('colspan', colspan) return td end

function h.printRound(td, data, n)	td:css({ padding = '0' }) local tblRound = h.printRoundTable(td) for k, v in ipairs(data) do		h.printInnerCell(tblRound, k, v)	end return end

function h.printRoundTable(td) local tblRound = td:tag('table'):css({		width = 'calc(100% + 2px)',		margin = '-1px'	}):tag('tr') return tblRound end

function h.printInnerCell(tbl, key, data) if not data.text or data.text == '' then return end tbl:tag('td') :css({			width = data.width .. '%',			['background-color'] = data.color		}) :addClass('distribution-cell') :wikitext(data.text) :attr('data-distribution-key', key) return end

return p