Module:MVPStandings

From Leaguepedia | League of Legends Esports Wiki
Jump to: navigation, search

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

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 m_team = require('Module:Team')

local lang = mw.getLanguage('en')

local TABLES = { game = 'MatchScheduleGame', series = 'MatchSchedule' }
local HEADING_DATA = {
	both = { 'Rank', 'Times', 'Points', 'Player' },
	times = { 'Rank', 'Times', 'Player' },
	points = { 'Rank', 'Points', 'Player' },
}
local UNIQUE = { MatchScheduleGame = 'UniqueLine', MatchSchedule = 'UniqueMatch' }

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

local h = {}

function h.getTotals(args, page)
	local datatable = h.getDataTable(lang:lc(args.queryfrom))
	local result_count = h.doPlayerCountQuery(args, page, datatable)
	local result_teams = h.doTeamQuery(args, page, datatable)
	local totals = h.countTotals(result_count, result_teams)
	return totals
end

function h.getDataTable(queryfrom)
	if not queryfrom or not TABLES[queryfrom] then
		error('Invalid or missing queryfrom (allowed values are "game" and "series")')
	end
	return TABLES[queryfrom]
end

function h.doPlayerCountQuery(args, page, datatable)
	local query = {
		tables = { ('%s=MVPData'):format(datatable), 'PlayerRedirects=PR' },
		fields = {
			'MVPData.MVP=MVP',
			'MVPData.MVPPoints=Points',
			'PR._pageName=PlayerPage',
		},
		where = h.makePlayerCountWhere(args, page),
		join = 'MVPData.MVP=PR.AllName',
		-- groupBy = UNIQUE[datatable],
		limit = 9999,
		types = {
			Points = 'number',
			Count = 'number'
		}
	}
	return util_cargo.queryAndCast(query)
end

function h.makePlayerCountWhere(args, page)
	local tbl = {
		('MVPData.OverviewPage="%s"'):format(page),
		'MVPData.MVP IS NOT NULL'
	}
	return util_table.concat(tbl, ' AND ')
end

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

function h.makeTeamWhere(args, page)
	local tbl = {
		('TournamentPlayers._pageName="%s"'):format(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'})
	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(m_team.onlyimagelinked(row.Team,{size=45}) or '', util_esports.playerLinked(row.MVP))
		else
			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.makeEmptyWidthRowPX(tbl, headings.widths)
	util_html.makeColspanHeader(tbl, displaytext or 'MVP Standings', #headings.names)
	util_html.makeHeader(tbl, headings.names,{row='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.makeColspanHeader(tbl2, 'Click for Full Standings', #headings.names, nil, util_math.sum(headings.widths))
		util_html.makeEmptyWidthRowPX(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

local p = {}

function p.main(frame)
	local args = util_args.merge(true)
	if not args.queryfrom then
		error('Please specify |queryform=')
	end
	local overviewPage = util_esports.getOverviewPage(args.page)
	local showlimit = tonumber(args.showlimit) or 5
	local result = h.getTotals(args, overviewPage)
	h.processResult(result)
	local headings = h.pickHeadings(lang:lc(args.columns or 'both'))
	return h.printTable(result, showlimit, headings, args.displaytext)
end
return p