Jump to content

Module:CricketLeagueProgression/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by SocietyBox (talk | contribs) at 12:18, 21 April 2014 (overflow scrolling). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local p = {}
 
---------- Background colours for table cells ----------
local colours = {
    W = "#99FF99",
    L = "#FFDDDD",
    N = "#DFDFFF",
    D = "#F0E68C",
    T = "#DDFFDD"
}
local classes = {
    W = "yes table-yes2",
    L = "no table-no2",
    N = "noresult"
}
local elimColour = "#DCDCDC" -- Eliminated
 
function trim(s)
    if not s then
        return nil
    else
        return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
    end
end
 
function getArgs(frame)
    local parent = frame:getParent();
    local args = {}
    for k,v in pairs(parent.args) do
        args[k] = trim(v)
    end
    for k,v in pairs(frame.args) do
        args[k] = trim(v)
    end
    return args;
end
 
--
--   Match class
--
local cricmatch = {}
 
cricmatch.__index = function(t, key)
    local ret = rawget(t, key)
    if ret then
        return ret
    end
    ret = cricmatch[key]
    if type(ret) == 'function' then
        return function(...)
            return ret(t, ...)
        end
    else
        return ret
    end
end
 
cricmatch.render = function(m, row, team, points)
	local cell = row.tag('td')
	local home = m.home == team
 
	local result = m.result
	local gained = 0
	if m.result == 'H' then
		result = home and 'W' or 'L'
		gained = home and 2 or 0
	elseif m.result == 'A' then
		result = home and 'L' or 'W'
		gained = home and 0 or 2
	elseif m.result == 'N' or m.result == 'T' then
		gained = 1
	else
		return points
	end
 
	points = points + gained
	cell
		.css('background-color', colours[result])
		.wikitext(string.format('[[#match%d|%d]]', m.id, points))
	if classes[cell] then cell.attr('class', classes[cell]) end
	return points
end
 
function createMatch(id, home, away, result, margin, dl)
    if not home or not away then
        return nil
    end
    local match = {}
    setmetatable(match, cricmatch)
    match.id = id
    match.home = home
    match.away = away
    match.result = result
    match.margin = margin
    match.dl = dl
    return match
end
 
--
--   Html Builder helpers
--
local htmlBuilder = require('Module:HtmlBuilder')
 
--
--   Helper functions
--
function buildLegend(container, types)
    local key = container.tag('table')
        .addClass('wikitable')
        .css('float', 'right')
        .css('text-align', 'center')
        .css('font-size', '90%')
        .css('margin', '0 0 0 10px')
        .tag('td')
        	.css('background-color', colours.W)
        	.css('padding-left', '10px')
        	.css('padding-right', '10px')
        	.wikitext('Win')
    	.done()
        .tag('td')
        	.css('background-color', colours.L)
        	.css('padding', '0 10px')
        	.wikitext('Loss')
    	.done()
        .tag('td')
        	.css('background-color', colours.N)
        	.css('padding', '0 10px')
        	.wikitext('No result')
    	.done()
 
    local list = container.tag('ul')
        .css('font-size', '90%')
        .tag('li')
            .wikitext("'''Note''': The total points " ..
            	"at the end of each group match are listed.")
        .done()
        .tag('li')
            .wikitext("'''Note''': Click on the points (group matches) " ..
            	"or W/L (playoffs) to see the match summary.")
        .done()
    return container
end
 
function getMatchData(args, teams)
    local i, m = 0, 1
    local match
    local matches = {}
    local home, away, result, margin, dl
    while args[i * 5 + 5] do
        home = teams[trim(args[i * 5 + 1])]
        away = teams[args[i * 5 + 2]]
        result = args[i * 5 + 3]
        margin = args[i * 5 + 4]
        dl = args[i * 5 + 5] == "Y"
        match = createMatch(m, home, away, result, margin, dl)
        if match then
            table.insert(matches, match)
            m = m + 1
        end
        i = i + 1
    end
    return matches
end
 
function renderTeam(tbl, count, team, matches, koStages, total)
	local row = tbl.tag('tr')
		.tag('th')
			.css('text-align', 'left')
			.css('padding-right', '10px')
			.css('border-right', 'black solid 2px')
			.css('min-width', '160px')
			.wikitext(string.format('[[%s|%s]]', team.pageName, team.fullName))
		.done()
	local points = 0
	for i = 1, count do
		if matches[i] then
			points = matches[i].render(row, team, points)
		else
			row.tag('td')
		end
	end
	local cell, koMatches, koMatch, result, colour, matchNo
	local eliminated = true
	for i = 1, #koStages do
		result = nil
		cell = row.tag('td')
		if i == 1 then cell.css('border-left', 'black solid 2px') end
		koMatches = koStages[i].matches
		for j = 1, #koMatches do
			total = total + 1
			koMatch = koMatches[j]
			if result then
			elseif not koMatch.winner then
				eliminated = false
			else
				if koMatch.winner == team.code then
					result = 'W'
					matchNo = total
				elseif koMatch.loser == team.code then
					result = 'L'
					matchNo = total
				end
			end
		end
		if result then
			cell.css('background-color', colours[result])
				.wikitext(string.format('[[#match%d|%s]]', matchNo, result))
		elseif eliminated then
			cell.css('background-color', elimColour)
		end
	end
end
 
p.create = function(args, teams, koName, koStages)
    local matches = getMatchData(args, teams)
    local wrapper = htmlBuilder.create('div')
 
	local codes, results = {}, {}
	local count = 0
	for _, match in ipairs(matches) do
        local home = match.home.code
        local away = match.away.code
		if not results[home] then
			table.insert(codes, home)
			results[home] = {}
		end
		if not results[away] then
			table.insert(codes, away)
			results[away] = {}
		end
		table.insert(results[home], match)
		table.insert(results[away], match)
		count = math.max(count, #results[home], #results[away])
	end
    local teamsort = function(t1, t2)
        return teams[t1].fullName < teams[t2].fullName
    end
    table.sort(codes, teamsort)
 
	local container = wrapper.tag('div')
		.css('float', 'left')
		.css('max-width', '100%')
	local tbl = container.tag('table')
		.attr('class', 'wikitable')
		.css('width', '100%')
		.css('text-align', 'center')
		.css('display', 'block')
		.css('overflow', 'auto')
		.css('border', 'none')

	-- headers
	local row = tbl.tag('tr')
	row
		.tag('th')
			.attr('scope', 'col')
			.attr('rowspan', '2')
			.css('border-right', 'black solid 2px')
			.wikitext('Team')
		.done()
		.tag('th').attr('colspan', count).wikitext('Group matches').done()
	if koStages then
		row.tag('th')
			.attr('colspan', #koStages)
			.css('border-left', 'black solid 2px')
			.wikitext(koName or 'Knockout matches')
	end
 
	row = tbl.tag('tr')
	for i = 1, count do
		row.tag('th').attr('scope', 'col').css('width', '18px').wikitext(i)
	end
	local cell
	for i = 1, #koStages do
		cell = row.tag('th')
			.attr('scope', 'col')
			.css('width', '18px')
			.tag('abbr')
				.attr('title', koStages[i].name)
				.wikitext(koStages[i].abbr)
			.done()
		if i == 1 then cell.css('border-left', 'black solid 2px') end
	end
 
	-- matches
    for _, code in ipairs(codes) do
    	renderTeam(tbl, count, teams[code], results[code], koStages, #matches)
	end
 
	buildLegend(container)
	wrapper.tag('div').css('clear', 'left')
    return tostring(wrapper)
end
 
p.IPL = function(frame)
    local args = getArgs(frame)
    local teams = mw.loadData("Module:IndianPremierLeague/Teams")
    local teamsAssoc = {}
    local i = 1
    while teams[i] do
        teamsAssoc[teams[i].code] = teams[i]
        i = i + 1
    end
	local playoffs = {
		{ name = 'Qualifier 1 or Eliminator', abbr = 'Q1/E', matches = {
			{ winner = args.P1W, loser = args.P1L },
			{ winner = args.P2W, loser = args.P2L }
		}},
		{ name = 'Qualifier 2', abbr = 'Q2', matches = {
			{ winner = args.P3W, loser = args.P3L }
		}},
		{ name = 'Final', abbr = 'F', matches = {
			{ winner = args.P4W, loser = args.P4L }
		}}
	}
    return p.create(args, teamsAssoc, "Playoffs", playoffs)
end
 
return p