Module:PickBanHistory

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

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

local lang = mw.getLanguage('en')
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_form = require('Module:FormUtil')
local util_esports = require('Module:EsportsUtil')
local util_table = require('Module:TableUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')
local Sprite = require('Module:Sprite').spriteImage
local FIELDS = {
	'Team1Role1',
	'Team1Role2',
	'Team1Role3',
	'Team1Role4',
	'Team1Role5',
	'Team2Role1',
	'Team2Role2',
	'Team2Role3',
	'Team2Role4',
	'Team2Role5',
	'Team1Ban1',
	'Team1Ban2',
	'Team1Ban3',
	'Team1Ban4',
	'Team1Ban5',
	'Team1Pick1',
	'Team1Pick2',
	'Team1Pick3',
	'Team1Pick4',
	'Team1Pick5',
	'Team2Ban1',
	'Team2Ban2',
	'Team2Ban3',
	'Team2Ban4',
	'Team2Ban5',
	'Team2Pick1',
	'Team2Pick2',
	'Team2Pick3',
	'Team2Pick4',
	'Team2Pick5',
	'Team1',
	'Team2',
	'Winner',
	'Team1Score',
	'Team2Score',
	'OverviewPage',
	'Tab',
	'_pageName'
}
local CELLORDER = {
	{ 'Team1Ban1', classes = { 'pbh-ban', 'pbh-blue', 'pbh-cell' } },
	{ 'Team2Ban1', classes = { 'pbh-ban', 'pbh-red', 'pbh-cell' } },
	{ 'Team1Ban2', classes = { 'pbh-ban', 'pbh-blue', 'pbh-cell' } },
	{ 'Team2Ban2', classes = { 'pbh-ban', 'pbh-red', 'pbh-cell' } },
	{ 'Team1Ban3', classes = { 'pbh-ban', 'pbh-blue', 'pbh-cell' } },
	{ 'Team2Ban3', classes = { 'pbh-ban', 'pbh-red', 'pbh-cell', 'pbh-divider' } },
	
	{ 'Team1Pick1', classes = { 'pbh-blue', 'pbh-cell' }, mandatory = true },
	{ 'Team2Pick1', 'Team2Pick2', classes = { 'pbh-red', 'pbh-cell' }, mandatory = true },
	{ 'Team1Pick2', 'Team1Pick3', classes = { 'pbh-blue', 'pbh-cell' }, mandatory = true },
	{ 'Team2Pick3', classes = { 'pbh-red', 'pbh-cell', 'pbh-divider' }, mandatory = true },
	
	{ 'Team2Ban4', classes = { 'pbh-ban', 'pbh-red', 'pbh-cell' } },
	{ 'Team1Ban4', classes = { 'pbh-ban', 'pbh-blue', 'pbh-cell' } },
	{ 'Team2Ban5', classes = { 'pbh-ban', 'pbh-red', 'pbh-cell' } },
	{ 'Team1Ban5', classes = { 'pbh-ban', 'pbh-blue', 'pbh-cell', 'pbh-divider' } },
	
	{ 'Team2Pick4', classes = { 'pbh-red', 'pbh-cell' }, mandatory = true },
	{ 'Team1Pick4', 'Team1Pick5', classes = { 'pbh-blue', 'pbh-cell' }, mandatory = true },
	{ 'Team2Pick5', classes = { 'pbh-red', 'pbh-cell' }, mandatory = true }
}
local HEADERS = { 'Phase', 'Blue', 'Red', 'Score', 'BB1', 'RB1', 'BB2', 'RB2', 'BB3', 'RB3', 'BP1', 'RP1-2', 'BP2-3', 'RP3', 'RB4', 'BB4', 'RB5', 'BB5', 'RP4', 'BP4-5', 'RP5' }
local ROLE_HEADERS = { 'BR1', 'BR2', 'BR3', 'BR4', 'BR5', 'RR1', 'RR2', 'RR3', 'RR4', 'RR5' }
local COLORS = { 'red', 'blue', 'green', 'yellow' }
local MESSAGE = [[:''Unlike some other charts, this page is based on data that was manually entered to the wiki, and as such it is possible that there are some mistakes. If you notice any, please report it to wiki staff!''
:''Select a highlighting color to the right and then click a champion to toggle highlighting on-off.''
]]

local CLASSES = { RB3 = 'pbh-divider', RP3 = 'pbh-divider', BB5 = 'pbh-divider' }

local FORM_INFO = { form = 'PickBanHistory', template = 'PBH' }

local h = {}
local p = {}

function p.main(frame)
	local args = util_args.merge(true)
	local overviewPage = util_esports.getOverviewPage(args.page)
	if not overviewPage then return '' end
	local pretty = not util_args.castAsBool(args.textonly)
	local result = h.getData(overviewPage, args)
	if not next(result) then return '' end
	h.formatResults(result, pretty)
	return h.makeOutput(result, h.getDisplayText(args, overviewPage), pretty)
end

function h.ChampionSprite(id)
	return Sprite{
		id,
		size = '25',
		type = 'Champion',
		notext = true,
		nolink = true,
		nosize = true
	}
end

-- cargo
function h.getData(page, args)
	return util_cargo.queryAndCast(h.makeQuery(page, args))
end

function h.makeQuery(page, args)
	return {
		tables = 'PicksAndBansS7',
		fields = FIELDS,
		where = h.makeWhere(page, args),
		orderBy = 'N_Page DESC,N_GameInPage DESC',
		limit = 9999,
		groupBy = 'UniqueLine'
	}
end

function h.makeWhere(page, args)
	local team = util_args.nilToFalse(args.team) and m_team.teamlinkname(args.team)
	local tbl = {
		string.format('OverviewPage="%s"', page),
		'Winner IS NOT NULL',
		util_cargo.whereFromArg('N_Page >= "%s"', args.pagestart),
		util_cargo.whereFromArg('N_Page <= "%s"', args.pageend),
		team and ('(Team1="%s" OR Team2="%s")'):format(team, team)
	}
	return util_table.concat(tbl, ' AND ')
end

--process
function h.formatResults(result, pretty)
	if pretty then
		util_table.mapInPlace(result, h.formatRowPretty)
	else
		util_table.mapInPlace(result, h.formatRowPlain)
	end
end

function h.formatRowPretty(row)
	local tbl = h.initRowDataPretty(row)
	for i, cellPreload in ipairs(CELLORDER) do
		local col = #tbl.data+1
		local c1 = cellPreload[1] and row[cellPreload[1]]
		local c2 = cellPreload[2] and row[cellPreload[2]]
		tbl.data[col] = h.getChampionDisplays(c1, c2)
		h.initCellClasses(tbl.classes, col)
		util_table.mergeArrays(tbl.classes[col], cellPreload.classes or {}, h.getChampionClasses(c1, c2))
		tbl.attrs[col] = h.getChampAttrs(c1, c2)
	end
	return tbl
end

function h.initRowDataPretty(row)
	local ret = {
		data = {
			row.Tab and ('[[%s#%s|%s]]'):format(row._pageName,row.Tab,row.Tab) or '',
			m_team.onlyimage(row.Team1) or row.Team1,
			m_team.onlyimage(row.Team2) or row.Team2,
			h.getScore(row)
		},
		classes = h.initColumnClasses(row.Winner),
		attrs = {}
	}
	return ret
end

function h.getScore(row)
	return ((row.Team1Score  or '?') .. ' - ' .. (row.Team2Score or '?')) or string.format(
		'%s - %s, %s',
		row.Team1Score,
		row.Team2Score,
		row.Winner
	)
end

function h.initColumnClasses(winner)
	return {
		[2] = winner == '1' and { 'pbh-winner' } or {},
		[3] = winner == '2' and { 'pbh-winner' } or {},
	}
end

function h.getChampionDisplays(a, b)
	return h.getOneChampionDisplay(a) .. h.getOneChampionDisplay(b)
end

function h.getOneChampionDisplay(champ)
	if not champ then return '' end
	local span = mw.html.create('span')
		:addClass('pbh-champion')
		:attr('data-champion',h.escapeChampForClass(champ))
		:wikitext(h.ChampionSprite(champ))
	return tostring(span)
end

function h.escapeChampForClass(champ)
	if not champ then return nil end
	return lang:lc(champ:gsub("[ '.]",''))
end

function h.initCellClasses(classes, col)
	if not classes[col] then classes[col] = {} end
end

function h.addClassesToCell(classes, cellPreload)
	util_table.mergeArrays(classes, cellPreload.classes)
end

function h.getChampionClasses(a, b)
	local ret = {}
	ret[#ret+1] = h.toClass(h.escapeChampForClass(a))
	ret[#ret+1] = h.toClass(h.escapeChampForClass(b))
	return ret
end

function h.toClass(str)
	if not str then return nil end
	return ('pbh-%s'):format(str)
end

function h.getChampAttrs(c1, c2)
	return {
		['data-c1'] = h.escapeChampForClass(c1),
		['data-c2'] = h.escapeChampForClass(c2),
	}
end

function h.formatRowPlain(row)
	local tbl = {
		data = {
			row.Tab and ('[[%s#%s|%s]]'):format(row._pageName,row.Tab,row.Tab) or '',
			row.Team1,
			row.Team2,
			h.getScore(row),
		},
		classes = h.initColumnClasses(row.Winner),
		attrs = {}
	}
	for i, cellPreload in ipairs(CELLORDER) do
		local col = #tbl.data+1
		local c1 = h.getChampionText(cellPreload[1], row[cellPreload[1]])
		local c2 = h.getChampionText(cellPreload[2], row[cellPreload[2]])
		tbl.data[col] = ((c1 or '') .. (c2 and string.format(', %s',c2) or ''))
		h.initCellClasses(tbl.classes, col)
		util_table.mergeArrays(tbl.classes[col], cellPreload.classes)
	end
	for i = 1,2 do
		for j = 1,5 do
			tbl.data[#tbl.data+1] = row[('Team%sRole%s'):format(i,j)] or 'MISSING DATA'
		end
	end
	return tbl
end

function h.getChampionText(preloadValue, rowValue)
	if preloadValue and rowValue then
		return rowValue
	elseif preloadValue then
		return 'MISSING DATA'
	end
end

-- print
function h.getDisplayText(args, overviewPage)
	if args.display then return args.display end
	return h.getDefaultDisplayText(overviewPage) or overviewPage
end

function h.getDefaultDisplayText(page)
	local query = {
		tables = 'Tournaments',
		fields = 'Name',
		where = string.format('_pageName="%s"', page)
	}
	return util_cargo.getOneResult(query)
end

function h.makeOutput(result, event, pretty)
	local output = mw.html.create()
	output:wikitext(MESSAGE)
	h.printTable(output, result, event, pretty)
	if pretty then output:node(h.printColorPicker()) end
	return output
end

function h.printTable(outer, formatted, event, pretty)
	local div = outer:tag('div'):attr('id','pbh-outer'):addClass('wide-content-scroll')
	local tbl = div:tag('table')
		:addClass('wikitable')
		:attr('id','pbh-table')
	h.addHeader(tbl, event, pretty)
	for _, row in ipairs(formatted) do
		local tr = tbl:tag('tr')
		for i, cellPreload in ipairs(row.data) do
			local td = tr:tag('td')
			td:wikitext(cellPreload)
			for attr, val in pairs(row.attrs[i] or {}) do
				td:attr(attr,val)
			end
			for _, class in ipairs(row.classes[i] or {}) do
				td:addClass(class or '')
			end
		end
	end
	return tbl
end

function h.addHeader(tbl, event, pretty)
	local headers = h.getHeaders(pretty)
	local th = tbl:tag('tr'):tag('th'):attr('colspan',#headers)
	th:wikitext(string.format(
		'Pick and Ban Order - [[%s]]',
		event
	))
	if pretty then
		th:wikitext(string.format(
			' <span class="plainlinks">([%s View Text-Only Version])</span>',
			util_form.fullURL(FORM_INFO, { textonly = 'Yes', page = event })
		))
	end
	local tr = tbl:tag('tr')
	for k, cellPreload in ipairs(headers) do
		tr:tag('th'):wikitext(cellPreload)
		:addClass(CLASSES[cellPreload])
	end
	return tr
end

function h.getHeaders(pretty)
	if pretty then
		return HEADERS
	else
		return util_table.mergeArrays(HEADERS, ROLE_HEADERS)
	end
end

function h.printColorPicker()
	local tbl = mw.html.create('div')
	tbl:attr('id','pbh-setcolor-box')
	for k, cellPreload in ipairs(COLORS) do
		tbl:tag('div')
			:addClass('pbh-setcolor')
			:addClass(k == 1 and 'pbh-current-tool' or '')
			:attr('data-pbhcolor', cellPreload)
			:css('background-color',cellPreload)
	end
	tbl:tag('div')
		:attr('id','pbh-remove')
		:attr('title','Clear')
	tbl:tag('div')
		:attr('id','pbh-removeall')
		:attr('title','Clear All')
	tbl:tag('div')
		:attr('id','pbh-undo')
		:attr('title','Undo Clear All')
		:css('display','none')
	return tbl
end
return p