Module:MVPStandings

local util_args = require('Module:ArgsUtil') local util_cargo = require('Module:CargoUtil') local util_esports = require('Module:EsportsUtil') local util_html = require('Module:HtmlUtil') local util_math = require('Module:MathUtil') local util_sort = require('Module:SortUtil') local util_table = require('Module:TableUtil') local util_text = require('Module:TextUtil') local util_vars = require("Module:VarsUtil") local i18n = require('Module:i18nUtil')

local Team = require('Module:TeamClass')

local lang = mw.getLanguage('en')

local HEADING_DATA = { both = { 'Rank', 'Times', 'Points', 'Player' }, times = { 'Rank', 'Times', 'Player' }, points = { 'Rank', 'Points', 'Player' }, }

local WIDTHS = { Rank = 45, Times = 50, Points = 60, Player = 200 }

local h = {} local p = {}

function p.main(frame) local args = util_args.merge i18n.init('MVPStandings') local showlimit = tonumber(args.showlimit) or 5 local result = h.getTotals(args) h.processResult(result) local headings = h.pickHeadings(lang:lc(args.columns or 'both')) local displaytext = args.displaytext or i18n.print('defaultHeading') return h.printTable(result, showlimit, headings, displaytext) end

function h.getTotals(args) local result_count = h.doPlayerCountQuery(args) local result_teams = h.doTeamQuery(args) local totals = h.countTotals(result_count, result_teams) return totals end

function h.doPlayerCountQuery(args) -- an mvp can be either in a match or in a game -- therefore it can be stored in either of 2 tables -- so here we have to look at the columns MS.MVP and also MSG.MVP -- and treat them interchangeably, using COALESCE/CASE to achieve this -- yes a better solution would maybe be to have a standalone table just for MVPs -- but that would add too much extra save time to data pages local query = { tables = { 'MatchSchedule=MS', 'MatchScheduleGame=MSG', 'PlayerRedirects=PR1', 'PlayerRedirects=PR2', },		join = { 'MS.UniqueMatch=MSG.UniqueMatch', 'MS.MVP=PR1.AllName', 'MSG.MVP=PR2.AllName', },		fields = { 'COALESCE(MSG.MVP, MS.MVP)=MVP', 'COALESCE(MSG.MVPPoints, MS.MVPPoints)=Points [number]', 'COALESCE(PR1._pageName, PR2._pageName)=PlayerPage', },		where = h.makePlayerCountWhere(args), groupBy = 'CASE WHEN MS.MVP IS NULL THEN MSG.UniqueLine ELSE MS.UniqueMatch END', }	return util_cargo.queryAndCast(query) end

function h.makePlayerCountWhere(args) local tbl = { ('MS.OverviewPage="%s"'):format(util_esports.getOverviewPage(args.page)), 'COALESCE(MSG.MVP, MS.MVP) IS NOT NULL AND COALESCE(MSG.MVP, MS.MVP) != "N/A"', }	return util_table.concat(tbl, ' AND ') end

function h.doTeamQuery(args) local query = { tables = { 'TournamentPlayers', 'PlayerRedirects=PR' }, fields = { 'TournamentPlayers.Link=MVP', 'TournamentPlayers.Team', 'PR._pageName=PlayerPage' },		where = h.makeTeamWhere(args), join = 'TournamentPlayers.Player=PR.AllName', limit = 9999, }	local result = util_cargo.queryAndCast(query) return h.makeTeamDict(result) end

function h.makeTeamWhere(args) local tbl = { ('TournamentPlayers.OverviewPage="%s"'):format(util_esports.getOverviewPage(args.page)), }	return util_table.concat(tbl, ' AND ') end

function h.makeTeamDict(result) local tbl = {} for _, row in ipairs(result) do		if row.PlayerPage or row.MVP then tbl[util_text.ucfirst(row.PlayerPage or row.MVP)] = row.Team end end return tbl end

function h.countTotals(data, data_teams) local tbl = {} for i, row in ipairs(data) do		local player = row.PlayerPage or row.MVP local key = util_text.ucfirst(row.PlayerPage or row.MVP) if player and not tbl[key] then tbl[key] = mw.clone(row) tbl[key].Times = 1 tbl[key].Team = data_teams[key] tbl[#tbl+1] = key elseif player then tbl[key].Times = tbl[key].Times + 1 tbl[key].Points = tbl[key].Points + row.Points end end util_sort.dictByKeys(tbl, {'Points', 'MVP'}, { false, true }) return tbl end

-- process function h.processResult(result) local cur_points local cur_rank = 1 for i, player in ipairs(result) do		local row = result[player] if row.Points ~= cur_points then cur_rank = i			cur_points = row.Points end row.Rank = cur_rank if row.Team then row.Player = ('%s %s'):format(				Team(row.Team):imagelink{len='medium'} or '',				util_esports.playerLinked(row.MVP)			) else util_vars.log(row) row.Player = util_esports.playerLinked(row.MVP) end end end

function h.pickHeadings(columns) if not HEADING_DATA[columns] then error('Invalid columns argument') end local tbl = { names = HEADING_DATA[columns], widths = {} }	for i, v in ipairs(tbl.names) do		tbl.widths[i] = WIDTHS[v] end return tbl end

function h.printTable(result, limit, headings, displaytext) local output = mw.html.create local tbl = output:tag('table') :addClass('wikitable') :addClass('mvp-standings') util_html.printEmptyWidthRowPX(tbl, headings.widths) util_html.printColspanHeader(tbl, displaytext, #headings.names) util_html.printHeaderFromI18n(tbl, headings.names) :addClass('column-label-small') h.addRows(result, headings.names, tbl, 1, limit) if limit < #result then local tbl2 = output:tag('table') :addClass('wikitable mw-collapsible mw-collapsed') :addClass('mvp-standings-more') util_html.printColspanHeader(tbl2, i18n.print('expandText'), #headings.names, nil, util_math.sum(headings.widths)) util_html.printEmptyWidthRowPX(tbl2, headings.widths) h.addRows(result, headings.names, tbl2, limit + 1, #result) end return output end

function h.addRows(result, columns, tbl, i_start, i_end) for i = i_start, i_end do		if result[i] then h.addRow(tbl, result[result[i]], columns) end end return end

function h.addRow(tbl, row, columns) local tr = tbl:tag('tr') util_esports.addTeamHighlighter(tr, row.Team) for _, v in ipairs(columns) do		tr:tag('td'):wikitext(row[v]) end end

return p