Module:MatchDetails

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_map = require('Module:MapUtil') local util_matches = require('Module:MatchesUtil') 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 m_team = require('Module:Team') local m_map = require('Module:Map')

local i18n = require('Module:I18nUtil')

local lang = mw.getLanguage('en')

sep = '%s*,%s*'

local VODLIST = { 'Vod', 'VodPB', 'VodGameStart', 'VodPostgame', 'VodHighlights' }

local HIDDENCLASS = 'toggle-section-hidden' local TAB_TOGGLES = { row = 'mdv-allweeks mdv-week%s %s', all = { show_attr = '.mdv-allweeks', hide_attr = '.mdv-showbuttons', show_class = 'mdv-allweeks', hide_class = 'mdv-showbuttons', show_text = 'show all', hide_text = 'hide all', },	week = { show_attr = '.mdv-week%s', hide_attr = '.mdv-showbutton%s', show_class = 'mdv-allweeks mdv-week%s', hide_class = 'mdv-showbuttons mdv-showbutton%s', } }

local FIELD_ORDER = { match = { 'Team1', 'Team2', 'Score', 'PBP', 'Color', 'Interview', 'With', 'Highlights', 'Wanplus', 'Recap', 'Reddit', 'Posters', 'MVP' }, game = { 'Map', 'Blue', 'Red', 'Selection', 'MH', 'VODs', 'Interview', 'With', 'Reddit', 'MVP', 'Summary' } }

local FIELD_LOOKUP = { match = { pbp = 'PBP', color = 'Color', int = 'Interview', interview = 'Interview', w = 'With', with = 'With', recap = 'Recap', reddit = 'Reddit', mvp = 'MVP', hl = 'Highlights', highlights = 'Highlights', posters = 'Posters', wp = 'Wanplus', wanplus = 'Wanplus', },	game = { b = 'Blue', blue = 'Blue', r = 'Red', red = 'Red', map = 'Map', ssel = 'Selection', ['side selection'] = 'Selection', mh = 'MH', ['match history'] = 'MH', vods = 'VODs', int = 'Interview', interview = 'Interview', w = 'With', with = 'With', mvp = 'MVP', summary = 'Summary', reddit = 'Reddit', } }

local THIS

local h = {}

local p = {} function p.main(frame) local args = util_args.merge i18n.init('MatchDetails') local overviewPage = util_esports.getOverviewPage(args.page) local matchData = h.getMatchData(overviewPage, args) THIS = util_matches.determineThis(matchData, args.This) local gameData = h.getGameData(overviewPage, args) h.addGameDataToMatches(matchData, gameData) local fields = h.pickFields(args.matchfields, args.gamefields) return h.makeOutput(matchData, fields) end

function h.getMatchData(page, args) local matchResult = util_cargo.queryAndCast(h.makeMatchQuery(page, args)) util_map.rowsInPlace(matchResult, h.processMatchRow) local matchData = util_cargo.groupResultOrdered(matchResult, 'Tab') return matchData end

function h.makeMatchQuery(page, args) local query = { tables = 'MatchSchedule', fields = { 'Team1', 'Team2', 'Player1', 'Player2', 'Winner [number]', 'Team1Score [number]', 'Team2Score [number]', 'FF [number]', 'Tab', 'UniqueMatch', 'CastersPBP', 'CastersColor', 'MVP', 'VodInterview', 'VodHighlights', 'InterviewWith', 'Recap', 'Reddit', 'DateTime_UTC=UTC', 'Team1Poster', 'Team2Poster', 'Wanplus', },		where = h.makeMatchWhere(page, args), orderBy = 'N_Page ASC, N_TabInPage ASC, N_MatchInTab ASC', groupBy = 'UniqueMatch', }	return query end

function h.makeMatchWhere(page, args) local tbl = { ('OverviewPage="%s"'):format(page) }	return util_table.concat(tbl,' AND ') end function h.processMatchRow(row) row.Team1Display = h.getPlayerOrTeamDisplay(row, 1) row.Team2Display = h.getPlayerOrTeamDisplay(row, 2) if row.FF then row['Team' .. row.FF .. 'Score'] = 'FF' row['Team' .. util_esports.otherTeamN(row.FF) .. 'Score'] = 'W'	else -- don't print casters if it's a forfeit row.PBP = util_esports.playersLinked(row.CastersPBP) row.Color = util_esports.playersLinked(row.CastersColor) end if row.Team1Score and row.Team2Score then row.Score = ('%s - %s'):format(row.Team1Score, row.Team2Score) else row.Score = 'TBD' end row.MVP = util_esports.playersLinked(row.MVP) row.With = util_esports.playersLinked(row.InterviewWith) row.Recap = util_text.extLink(row.Recap) row.Interview = util_text.extLink(row.VodInterview) row.Highlights = util_text.extLink(row.VodHighlights) row.Reddit = util_text.extLink(row.Reddit) row.Wanplus = util_text.extLink(row.Wanplus) row.Posters = h.getPostersDisplay(row) row.classes = { Team1 = row.Winner == 1 and 'md-winner', Team2 = row.Winner == 2 and 'md-winner' } end

function h.getPlayerOrTeamDisplay(row, i) if not row['Player' .. i] then return row['Team' .. i] and m_team.rightshort(row['Team' .. i]) end return m_team.onlyimageshort(row['Team' .. i]) .. util_esports.playerLinked(row['Player' .. i]) end

function h.getPostersDisplay(row) if not row.Team1Poster and not row.Team2Poster then return nil end local tbl = {} tbl[#tbl+1] = row.Team1Poster and util_text.intLink(':' .. row.Team1Poster, m_team.short(row.Team1)) tbl[#tbl+1] = row.Team2Poster and util_text.intLink(':' .. row.Team2Poster, m_team.short(row.Team2)) return util_table.concat(tbl, ' • ') end

function h.getGameData(page, args) local gameResult = util_cargo.queryAndCast(h.makeGameQuery(page, args)) util_map.rowsInPlace(gameResult, h.processGameRow) local gameData = util_cargo.groupResultByValue(gameResult, 'UniqueMatch') return gameData end

function h.makeGameQuery(page, args) local query = { tables = 'MatchScheduleGame', fields = { 'Map', 'Blue', 'Red', 'Winner [number]', 'Selection', 'Recap', 'VodPB', 'VodGameStart', 'VodPostgame', 'Vod', 'VodHighlights', 'VodInterview', 'InterviewWith', 'MVP', 'MatchHistory', 'UniqueMatch', 'WrittenSummary=Summary', 'Reddit', },		where = h.makeGameWhere(page, args), orderBy = 'N_Page ASC, N_TabInPage ASC, N_MatchInTab, N_GameInMatch', limit = 9999, groupBy = 'UniqueLine', }	return query end

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

function h.processGameRow(row) local hasteams = row.Blue and row.Red local sel = h.getSelectionSide(row) row.Map = m_map.linkedDisplay(row.Map) row.VODs = h.makeGameVodList(row) row.Interview = util_text.extLink(row.VodInterview) row.Blue = m_team.short(row.Blue) row.Red = m_team.short(row.Red) row.Selection = row.Selection and m_team.short(row.Selection) row.Recap = util_text.extLink(row.Recap) row.MH = util_text.extLink(row.MatchHistory) row.MVP = util_esports.playersLinked(row.MVP) row.With = util_esports.playersLinked(row.InterviewWith) row.Summary = h.makeSummary(row.Summary) row.Reddit = util_text.extLink(row.Reddit) row.classes = { Blue = row.Winner == 1 and 'md-winner', Red = row.Winner == 2 and 'md-winner', Selection = hasteams and row.Selection and ('standings-mh%s'):format(sel) } end

function h.getSelectionSide(row) if not row.Selection then return end return row.Selection == row.Blue and 'Blue' or 'Red' end

function h.makeGameVodList(row) local tbl = {} for _, v in ipairs(VODLIST) do		if row[v] then tbl[#tbl+1] = ('[%s %s]'):format(row[v], i18n.print(v)) end end return table.concat(tbl, ' &#8226; ') end

function h.makeSummary(summary) if not summary then return nil end local popupButton = util_toggle.popupButton popupButton.wrapper :addClass('written-summary-outer') popupButton.inner:addClass('written-summary-inner') :wikitext(summary) return tostring(popupButton.tbl) end

function h.addGameDataToMatches(matchData, gameData) for _, tab in ipairs(matchData) do		for _, row in ipairs(tab) do			row.gameData = gameData[row.UniqueMatch] or { { classes = {} } } end end return true end

-- output function h.pickFields(matcharg, gamearg) local matchfields = util_text.split(matcharg or '',sep) local gamefields = util_text.split(gamearg or '',sep) local tbl = { match = { 'Team1Display', 'Team2Display', 'Score' }, game = {} }	for _, v in ipairs(matchfields) do		tbl.match[#tbl.match+1] = FIELD_LOOKUP.match[lang:lc(v)] end for _, v in ipairs(gamefields) do		tbl.game[#tbl.game+1] = FIELD_LOOKUP.game[lang:lc(v)] end util_table.sortByKeyOrder(tbl.match, FIELD_ORDER.match) util_table.sortByKeyOrder(tbl.game, FIELD_ORDER.game) return tbl end

function h.makeOutput(matchData, fields) local colspan = #fields.match + #fields.game local output = mw.html.create local tbl = output:tag('table') :addClass('wikitable') :addClass('md-table') :attr('id','md-table') :css('min-width', math.max(22, 2 * colspan) .. 'em') if #matchData > 1 then util_toggle.printToggleHeader(tbl, colspan, i18n.print("header"), TAB_TOGGLES.all) else util_html.printColspanHeader(tbl, i18n.print("header"), colspan) end for i, tabData in ipairs(matchData) do		h.printTab(tbl, tabData, fields, i, THIS == i)	end return output end

function h.printTab(tbl, tabData, fields, i, isfocused) h.printColspanHeading(tbl, tabData.name, fields, i, isfocused) local toggle_class = h.getRowToggleClass(i, isfocused) h.printHeading(tbl, fields, toggle_class) for _, row in ipairs(tabData) do		h.printRow(tbl, row, fields, toggle_class) end end

function h.printColspanHeading(tbl, name, fields, i, isfocused) local toggle_data = h.getWeekToggleData(i, isfocused) local colspan = #fields.match + #fields.game util_toggle.printToggleHeader(tbl, colspan, name, toggle_data) end

function h.getWeekToggleData(i, isfocused) local data = mw.clone(TAB_TOGGLES.week) data.initshown = isfocused util_toggle.prepDataByWeek(data, i)	return data end

function h.getRowToggleClass(i, isfocused) return TAB_TOGGLES.row:format(i, isfocused and '' or HIDDENCLASS) end

function h.printHeading(tbl, fields, toggle_class) local tr = tbl:tag('tr') :addClass('column-label-small') :addClass(toggle_class) for _, v in ipairs(fields.match) do		tr:tag('th'):wikitext(i18n.print(v) or v)	end for _, v in ipairs(fields.game) do		tr:tag('th'):wikitext(i18n.print(v) or v)	end return end

function h.printRow(tbl, row, fields, toggle_class) local tr = tbl:tag('tr') :addClass(toggle_class) local rowspan = h.getRowspan(fields.game, row.gameData, row.FF) h.printMatchFields(tr, row, fields.match, rowspan) local gameData = row.FF and { { classes = {} } } or row.gameData h.printGamesFields(tbl, tr, gameData, fields.game, toggle_class) end

function h.getRowspan(game, gameData, isFF) if not game or not next(gameData) or isFF then return 1 else return #gameData end end

function h.printMatchFields(tr, row, fields, rowspan) for _, v in ipairs(fields) do		tr:tag('td') :attr('rowspan',rowspan) :addClass(row.classes[v] or '') :wikitext(row[v]) end end

function h.printGamesFields(tbl, tr, gameData, fields, toggle_class) for i, game in ipairs(gameData) do		if i ~= 1 then tr = tbl:tag('tr') :addClass(toggle_class) end h.printOneGameFields(tr, game, fields) end end

function h.printOneGameFields(tr, game, fields) for _, v in ipairs(fields) do		tr:tag('td') :addClass(game.classes[v] or '') :wikitext(game[v]) end end

return p