Hello there! We are conducting a survey to better understand the user experience in making a first edit. If you have ever made an edit on Gamepedia, please fill out the survey. Thank you!

Module:TournamentResults

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

Documentation for this module may be created at Module:TournamentResults/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_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_toggle = require('Module:ToggleUtil')
local util_vars = require('Module:VarsUtil')
local i18n = require('Module:i18nUtil')
local m_currency = require('Module:Currency')
local m_team = require('Module:Team')

local ROWSPANS = {
	place = true,
	prize_display = true,
	usd = true,
	eur = true,
	prizepct = true,
	qual = true,
	points = true
}

local CLASSES = {
	place = 'tournament-results-place',
	team = 'tournament-results-team',
	player = 'tournament-results-player',
	prize_display = 'tournament-results-prize',
}

local CURRENCY_ORDER = { 'USD', 'Euros' }

local LINE_ARG_ORDER = { 'place', 'forcenewplace', 'sameplaces', 'date', 'prize', 'otherprize', 'prizepct', 'prizeunit', 'points', 'qual', 'quallink', 'qual2', 'qual2link', 'team', 'nocargo', 'date', 'rosterpage', 'groupstage', 'group', 'lastresult', 'lastopponent', 'lastopponentlink', 'lastopponentteam', 'lastoutcome', 'lastresultpoints', 'player', 'playerlink', 'hide', 'qualified' }

local TOGGLES = {
	class = 'TRL_toggle%s',
}

local PRIZE_TOGGLE_DATA = {
	order = {},
	sep = ' • ',
	section = 'prizepool-togglers-currency',
	all = 'prizepool-currency-all',
	hiddenclass = 'prizepool-currency-hidden',
}

local HAS_TOGGLES = false

local h = {}
local p = {}
function p.main(frame)
	i18n.initGlobalFromFile('TournamentResults')
	local args = util_args.merge(true)
	local processedArgs = h.getProcessedArgs(args)
	h.initCurrencyToggle(processedArgs)
	local cols = h.getCols(args, processedArgs)
	local linesData = h.getLinesData(args, processedArgs)
	h.storeCargo(linesData)
	return h.makeOutput(args, processedArgs, cols, linesData)
end

function h.getProcessedArgs(args)
	h.checkConversions({ args.usdrate, args.eurorate })
	local processedArgs = {
		prizeunit = args.prizeunit or 'USD',
		totalprize = util_math.formatNumber(args.totalprize),
		totalprizenum = args.totalprize and util_math.tonumber(args.totalprize),
		usdrate = tonumber(args.usdrate),
		eurorate = tonumber(args.eurorate),
		phase = args.phase,
		nocargo = util_args.castAsBool(args.nocargo),
		preload = args.preload or 'Team',
		showprize = util_args.castAsBool(args.prize),
		showusd = util_args.castAsBool(args.usdrate),
		showeuro = util_args.castAsBool(args.eurorate),
		showpoints = util_args.castAsBool(args.points),
		showqual = util_args.castAsBool(args.qual),
		showteam = util_args.castAsBool(args.showteam),
		showplayer = util_args.castAsBool(args.showplayer),
		combinequal = util_args.castAsBool(args.combinequal),
	}
	processedArgs.hasconversion = processedArgs.usdrate or processedArgs.eurorate
	return processedArgs
end

function h.checkConversions(tbl)
	for _, v in ipairs(tbl) do
		if v and not tonumber(v) then
			error(i18n.print('invalid_currency', i18n.print('conversion_rate')))
		end
	end
end
			
function h.initCurrencyToggle(processedArgs)
	local rates = {
		USD = processedArgs.usdrate,
		Euros = processedArgs.eurorate,
	}
	for _, v in ipairs(CURRENCY_ORDER) do
		if rates[v] then
			PRIZE_TOGGLE_DATA.order[#PRIZE_TOGGLE_DATA.order+1] = v
		end
	end
	if next(PRIZE_TOGGLE_DATA.order) then
		table.insert(PRIZE_TOGGLE_DATA.order, 1, 'prize')
		HAS_TOGGLES = true
	end
	util_toggle.oflInit(PRIZE_TOGGLE_DATA)
end

function h.getCols(args, processedArgs)
	local cols = {
		'place',
		processedArgs.showprize and 'prize_display',
		h.pctCol(args),
		processedArgs.showpoints and 'points',
		processedArgs.showqual and 'qual',
		(processedArgs.showteam or processedArgs.preload == 'Team') and 'team',
		(processedArgs.showplayer or processedArgs.preload == 'Player') and 'player',
		
	}
	util_table.removeFalseEntries(cols)
	local names = h.getNames(args)
	cols.displays = {}
	for i, v in ipairs(cols) do
		cols.displays[i] = names[v] or i18n.print('col_' .. v)
	end
	return cols
end

function h.pctCol(args)
	if util_args.castAsBool(args.prize) and not util_args.castAsBool(args.nomoney) then
		return 'prizepct'
	else
		return false
	end
end

function h.getNames(args)
	return {
		points = args.pointstitle,
		team = args.teamtitle
	}
end

function h.getLinesData(args, processedArgs)
	local rowData = {}
	for i, v in ipairs(args) do
		rowData[i] = h.processArgRow(v, processedArgs)
	end
	h.determineRowspans(rowData)
	return rowData
end

function h.processArgRow(str, processedArgs)
	local lineArgs = util_args.splitArgs(str, LINE_ARG_ORDER)
	local lineDisplay = h.makeDisplayLineFromArgs(lineArgs, processedArgs)
	lineDisplay.cargo = h.argsToCargoLine(lineArgs, processedArgs, lineDisplay)
	return lineDisplay
end

function h.makeDisplayLineFromArgs(lineArgs, processedArgs)
	local lineDisplay = {
		place = lineArgs.place and util_esports.placementIcon(lineArgs.place),
		placeraw = lineArgs.place,
		team = m_team.rightmediumlinked(lineArgs.team),
		player = h.getPlayerDisplay(lineArgs, processedArgs),
		points = lineArgs.points,
		qual = h.getQual(lineArgs),
		forcenewplace = util_args.castAsBool(lineArgs.forcenewplace),
		hide = util_args.castAsBool(lineArgs.hide),
	}
	local prizes = h.getPrizeDisplay(lineArgs, processedArgs)
	prizes.prize_display = prizes.prize_toggle or prizes.prize
	util_table.merge(lineDisplay, prizes)
	if processedArgs.combinequal then
		lineDisplay.points = lineDisplay.points or lineDisplay.qual or ''
	end
	return lineDisplay
end

function h.getPlayerDisplay(lineArgs, processedArgs)
	local output = {
		lineArgs.team and m_team.onlyimagelinkedshort(lineArgs.team),
		util_text.intLink(lineArgs.playerlink, lineArgs.player)
	}
	util_table.removeFalseEntries(output, 2)
	return util_table.concat(output, ' ')
end

function h.getQual(lineArgs)
	local quals = util_args.numberedArgsToTable(lineArgs, 'qual') or {}
	lineArgs.qual1link = lineArgs.quallink
	for i, qual in ipairs(quals) do
		local link = lineArgs['qual' .. i .. 'link']
		quals[i] = util_text.intLink(link, qual)
	end
	return util_table.concat(quals,'<br>')
end

function h.getPrizeDisplay(lineArgs, processedArgs)
	if not (lineArgs.prize or lineArgs.prizepct) then
		return { prize = lineArgs.otherprize }
	end
	local prizeNum = h.getPrizeNum(lineArgs, processedArgs)
	if not prizeNum then
		return { prize = lineArgs.otherprize, prizepct = lineArgs.prizepct .. '%' }
	end
	local prizes = {
		prize = h.getPrize(prizeNum, lineArgs, processedArgs),
		usd_number = h.getPrizeConverted(prizeNum, processedArgs.prizeunit, processedArgs.usdrate, 'USD'),
		eur_number = h.getPrizeConverted(prizeNum, processedArgs.prizeunit, processedArgs.eurorate, 'Euro'),
		prizepct = h.getPrizePct(prizeNum, lineArgs, processedArgs),
	}
	prizes.USD = m_currency.short(prizes.usd_number, 'usd')
	prizes.Euros = m_currency.short(prizes.eur_number, 'euro')
	prizes.prize_toggle = h.getPrizeToggle(prizes, processedArgs.prizeunit)
	return prizes
end

function h.getPrizeNum(lineArgs, processedArgs)
	local prize = lineArgs.prize
	if prize then
		if not util_math.tonumber(prize) then
			error(i18n.print('invalid_currency',i18n.print('prize')))
		end
		return util_math.tonumber(prize)
	end
	local prizepct = lineArgs.prizepct
	local totalprize = processedArgs.totalprizenum
	if totalprize then
		return util_math.roundnum(prizepct / 100 * totalprize, .01)
	end
	return nil
end

function h.getPrize(prizeNum, lineArgs, processedArgs)
	local fullPrize = {
		m_currency.short(prizeNum, processedArgs.prizeunit),
		lineArgs.otherprize
	}
	return util_table.concat(fullPrize, ' +&nbsp;',nil,2)
end

function h.getPrizeConverted(prize, prizeunit, rate, unitToGet)
	if prizeunit == unitToGet then
		return prize
	elseif prize and rate then
		return util_math.roundnum(prize * tonumber(rate), .01)
	else
		return nil
	end
end

function h.getPrizePct(prizeNum, lineArgs, processedArgs)
	if lineArgs.prizepct then
		return lineArgs.prizepct .. '%'
	elseif processedArgs.totalprizenum then
		return util_math.roundnum(prizeNum / processedArgs.totalprizenum * 100, .01) .. '%'
	else
		return nil
	end
end

function h.getPrizeToggle(prizes, prizeunit)
	if not HAS_TOGGLES then return nil end
	local tbl = mw.html.create()
	for _, v in ipairs(PRIZE_TOGGLE_DATA.order) do
		util_toggle.oflCellClasses(tbl:tag('span'):wikitext(prizes[v]), PRIZE_TOGGLE_DATA, v)
	end
	return tostring(tbl)
end

function h.argsToCargoLine(lineArgs, processedArgs, lineDisplay)
	if processedArgs.nocargo or lineArgs.nocargo then return end
	local cargoData = {
		Event = util_vars.getVar('Event Name'),
		Tier = util_vars.getVar('Event Tier'),
		Date = lineArgs.date or util_vars.getVar('Event Date'),
		Place = util_math.deserialize(lineArgs.place) or lineArgs.place,
		Prize = lineArgs.prize,
		PrizeUnit = processedArgs.prizeunit,
		Prize_Markup = lineArgs.prize and m_currency.short(lineArgs.prize, processedArgs.prizeunit),
		Prize_USD = lineDisplay.usd_number,
		Prize_Euro = lineDisplay.eur_number,
		Prize_Other = lineArgs.otherprize,
		Team = lineArgs.team and m_team.teamlinkname(lineArgs.team),
		UniqueLine = mw.title.getCurrentTitle().text .. '_' .. util_vars.setGlobalIndex('TRL_line'),
		Phase = processedArgs.phase,
		OverviewPage = mw.title.getCurrentTitle().text,
		ForceNewPlace = lineArgs.forcenewplace,
	}
	
	local extraCargoData
	if processedArgs.preload == 'Player' then
		extraCargoData = h.getPlayerSpecificCargo(lineArgs, processedArgs, lineDisplay)
	elseif processedArgs.preload == 'Team' then
		extraCargoData = h.getTeamSpecificCargo(lineArgs, processedArgs, lineDisplay)
	end
	util_table.merge(cargoData, extraCargoData)
	-- return a table containing the table because maybe we want 2 dif cargo tables
	-- storing per line, e.g. TournamentResults & TournamentRosters
	return { cargoData }
end

function h.getPlayerSpecificCargo(lineArgs, processedArgs, lineDisplay)
	local playerData = {
		_table = 'TournamentResults1v1',
		Player = lineArgs.player,
		PlayerLink = lineArgs.playerlink or lineArgs.player,
	}
	local lastResult = h.playerLastResultCargo(lineArgs)
	util_table.merge(playerData, lastResult)
	return playerData
end

function h.playerLastResultCargo(lineArgs)
	local lastResult = {
		LastResult = lineArgs.lastresult,
		LastOpponent = lineArgs.lastopponent,
		LastOpponentLink = lineArgs.lastopponentlink or lineArgs.lastopponent,
		LastOutcome = lineArgs.lastoutcome and util_esports.outcomes[lineArgs.lastoutcome:lower()],
		LastOpponentTeam = lineArgs.lastopponentteam and m_team.teamlinkname(lineArgs.lastopponentteam),
		OverviewPage = mw.title.getCurrentTitle().text,
	}
	return lastResult
end

function h.getTeamSpecificCargo(lineArgs, processedArgs, lineDisplay)
	local teamData = {
		_table = 'TournamentResults',
		Place_Number = util_math.deserialize(lineArgs.place),
		Qualified = h.determineQualified(lineArgs),
		RosterPage = lineArgs.rosterpage or mw.title.getCurrentTitle().text,
	}
	local teamlink = lineArgs.team and m_team.teamlinkname(lineArgs.team) or ''
	teamData.PageAndTeam = teamData.RosterPage .. '_' .. teamlink
	local lastResult = h.teamLastResultCargo(lineArgs)
	util_table.merge(teamData, lastResult)
	return teamData
end

function h.determineQualified(lineArgs)
	if util_args.castAsBool(lineArgs.qualified) then
		return 'Yes'
	end
	return lineArgs.place == 'Q' and 'Yes'
end

function h.teamLastResultCargo(lineArgs)
	if lineArgs.groupstage then
		return h.lastResultGroupstage(lineArgs)
	elseif lineArgs.lastresultpoints then
		return h.lastResultPoints(lineArgs)
	else
		return h.lastResultDefault(lineArgs)
	end
end

function h.lastResultGroupstage(lineArgs)
	return {
		LastResult = lineArgs.lastresult or lineArgs.groupstage,
		GroupName = lineArgs.group or 'Group Stage',
		LastOpponent_Markup = m_team.rightshortlinked('group stage')
	}
end

function h.lastResultPoints(lineArgs)
	return {
		LastResult = lineArgs.lastresultpoints,
		LastOpponent_Markup = m_team.rightshortlinked('points')
	}
end

function h.lastResultDefault(lineArgs)
	local lastResult = {
		LastResult = lineArgs.lastresult,
		LastOutcome = util_esports.getOutcomeName(lineArgs.lastoutcome)
	}
	if lineArgs.lastopponent then
		lastResult.LastTeam = m_team.teamlinkname(lineArgs.lastopponent)
		lastResult.LastOpponent_Markup = m_team.rightshortlinked(lineArgs.lastopponent)
	end
	return lastResult
end

function h.determineRowspans(rowData)
	local curPlace, curRow, count
	for _, row in ipairs(rowData) do
		if curPlace ~= row.placeraw or row.forcenewplace then
			if curRow then
				curRow.rowspan = count
			end
			curRow = row
			count = 1
			curPlace = row.placeraw
		else
			count = count + 1
		end
	end
	if count or 0 > 1 then
		curRow.rowspan = count
	end
end

-- cargo
function h.storeCargo(linesData)
	if h.doWeStoreCargo() then
		for _, line in ipairs(linesData) do
			local cargoData = line.cargo
			if cargoData then
				for _, tbl in ipairs(cargoData) do
					util_cargo.store(tbl)
				end
			end
		end
	end
end

function h.doWeStoreCargo()
	return mw.title.getCurrentTitle().nsText == ''
end

-- make output
function h.makeOutput(args, processedArgs, cols, linesData)
	h.initializeToggleData()
	local output = mw.html.create()
	output:wikitext(h.introSentence(args, processedArgs))
	h.printCurrencyToggles(output)
	h.printTable(output, cols, linesData)
	h.creditCurrencyRates(output, args, processedArgs)
	return output
end

function h.initializeToggleData()
	local i = util_vars.setGlobalIndex('TRL_i')
	TOGGLES.class = TOGGLES.class:format(i)
end

function h.introSentence(args, processedArgs)
	if not args.totalprize then return '' end
	local tempdate = util_args.nilToFalse(args.tempprizedate)
	local sentenceParts = {
		m_currency.long(processedArgs.totalprize, processedArgs.prizeunit),
		tempdate and i18n.print('temp_date', tempdate),
		i18n.print('intro'),
	}
	return util_table.concat(sentenceParts, ' ')
end

function h.printCurrencyToggles(output)
	if not HAS_TOGGLES then return end
	local div = output:tag('div'):addClass('toggle-button')
	util_toggle.printOptionFromListTogglers(div, PRIZE_TOGGLE_DATA)
end

function h.printTable(output, cols, linesData)
	local tbl = output:tag('table')
		:addClass('wikitable2')
		:addClass('tournament-results')
		:addClass('zebra-manual')
	h.printStartCols(tbl, cols)
	local hidden = h.printLines(tbl, cols, linesData)
	if hidden then
		h.endHiddenResults(tbl, #cols)
	end
end

function h.printStartCols(tbl, cols)
	local tr = tbl:tag('tr')
	for i, v in ipairs(cols) do
		tr:tag('th')
			:wikitext(cols.displays[i])
	end
end

function h.printLines(tbl, cols, linesData)
	local hidden = false
	local rowspanLeft = 0
	local odd = false
	for _, line in ipairs(linesData) do
		if line.hide then
			hidden = true
			h.printShowButton(tbl, #cols)
		end
		local tr = tbl:tag('tr')
		if hidden then
			util_toggle.sepCellClasses(tr, TOGGLES)
		end
		local isFullRow = h.printOneLine(tr, cols, line, rowspanLeft, odd)
		if rowspanLeft == 1 then odd = not odd end
		if odd then
			tr:addClass('zebra-manual-odd')
		end
		if line.rowspan then
			rowspanLeft = line.rowspan
		else
			rowspanLeft = rowspanLeft - 1
		end
	end
	return hidden
end

function h.printShowButton(tbl, colspan)
	local tr = tbl:tag('tr')
	local th = tr:tag('th')
		:attr('colspan', colspan)
	util_toggle.printSepToggler(th, TOGGLES)
	util_toggle.sepCellClasses(tr, TOGGLES, true)
end

function h.printOneLine(tr, cols, lineDisplay, rowspanLeft, odd)
	local isFullRow = false
	for _, col in ipairs(cols) do
		if rowspanLeft > 1 and ROWSPANS[col] then
			-- pass
		else
			local td = tr:tag('td')
				:wikitext(lineDisplay[col])
				:addClass(CLASSES[col])
			if ROWSPANS[col] then
				td:attr('rowspan', lineDisplay.rowspan)
			end
		end
	end
end

function h.endHiddenResults(tbl, colspan)
	local tr = tbl:tag('tr')
	local th = tr:tag('th')
		:attr('colspan', colspan)
	util_toggle.sepCellClasses(tr, TOGGLES, false)
	util_toggle.printSepToggler(th, TOGGLES, true)
end

function h.creditCurrencyRates(output, args, processedArgs)
	if not (args.conversionsource and processedArgs.hasconversion) then
		return nil
	end
	local source = args.conversionsource:lower()
	local date = args.conversiondate
	local rates = {
		USD = processedArgs.usdrate,
		Euros = processedArgs.eurorate,
	}
	local originalUnit = processedArgs.prizeunit
	output:wikitext(i18n.print('credit_' .. source,date or i18n.print('unknown_date')))
	local ul = output:tag('ul')
	for _, v in ipairs(CURRENCY_ORDER) do
		if rates[v] then
			util_vars.log(v)
			ul:tag('li')
				:wikitext(m_currency.long(1, originalUnit))
				:wikitext(' = ')
				:wikitext(m_currency.long(rates[v], v))
		end
	end
	return output
end

return p