Halo Esports Wiki
Advertisement

To edit the documentation or categories for this module, click here.


local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')
local lang = mw.getLanguage('en')
local systems = mw.loadData('Module:Systems')

local SUFFIX, SYSTEM

-- structure of data:

-- aboveFold = thisteam, [thisteam] = { list of players }
-- belowFold = {
--		active = { team, team, team, }
--		inactive = { list, of, teams },
--		[team] = { list of players }, ........
-- }


local p = {}
local h = {}

function p.main(frame)
	local args = util_args.merge(true)
	if util_vars.getBool('suppressorgnavbox') then return '' end
	-- get inputs
	h.castArgs(args)
	local vars = h.getVariables(args)
	return p._makeNavbox(vars)
end

function p._makeNavbox(vars)
	if not vars.team then return '' end
	local data = h.getData(vars)
	if not data then return '' end
	SUFFIX = vars.suffix
	SYSTEM = vars.system
	h.processLinks(data)
	return h.makeOutput(data, vars)
end

function h.castArgs(args)
	-- args provided include team and is_player
	-- if we're on a player page, we also will know system already
	-- but if we're on a team page we'll have to query here, which we'll do later
	-- suffix is whether or not we care about the suffix of the page we're on
	args.suffix = util_args.castAsBool(args.suffix)
	args.team = args[1]
end

function h.getVariables(args)
	-- copy args to a separate internal object
	local title = util_title.titleTable()
	local ret = {}
	local titleteam = table.remove(title,1)
	ret.team = args.team
	ret.system = args.system and systems[args.system] or h.getSystemFromTitle(title)
	ret.teamlink = util_title.concatSubpage(ret.team, ret.system)
	ret.suffix = args.suffix and next(title) and table.concat(title,'/')
	ret.state = args.innerstate or 'mw-collapsed'
	return ret
end

function h.getSystemFromTitle(title)
	-- if we're on a team page then the system will be the 2nd part of the title
	-- this only applies to team pages because players aren't system-specific
	if title[1] and systems[title[1]] then
		return systems[table.remove(title,1)]
	end
	return nil
end

function h.getData(vars)
	-- to make a navbox, we must have either an active roster or sister teams
	-- if we have an active roster, we query that and it will go above the fold
	-- if we have sister teams, all of that goes below the fold
	local data = {}
	local active = false
	local thisteam = vars.team
	local thisteamlink = vars.teamlink
	if h.isActive(thisteamlink) then
		active = true
		data.aboveFold = thisteam
		data[thisteam] = { links = {}, names = {} }
		h.getPlayers(thisteamlink, data[thisteam])
	end
	h.addSisterTeamInfoToData(vars, data)
	return (active or data.hasSister) and data
end

function h.isActive(teamlink)
	-- a team is active if both its page exists and also it's not disbanded
	if not mw.title.makeTitle('',teamlink).exists then return false end
	local query = {
		tables = 'Teams',
		fields = 'IsDisbanded',
		where = string.format('_pageName="%s"',teamlink),
		types = { IsDisbanded = 'boolean' },
	}
	return not util_cargo.getOneResult(query)
end

function h.getPlayers(team, data)
	-- query players from cargo
	local query = {
		tables = 'ListplayerCurrent',
		fields = { 'Link', 'ID' },
		where = ('_pageName="%s" AND ID IS NOT NULL'):format(team),
		groupBy = 'Link',
		orderBy = 'N'
	}
	local result = util_cargo.queryAndCast(query)
	for i, row in ipairs(result) do
		data.links[i] = row.Link
		data.names[i] = row.ID
	end
end

function h.addSisterTeamInfoToData(vars, data)
	-- all data about sister teams goes below the fold except sisterDataLocation & hasSister
	-- sisterDataLocation is to be used for the edit button of the navbox
	-- hasSister will be checked to see if we proceed with making the navbox or not & then ignored
	local row = h.getSisterTeamData(vars.team)
	if not row or not next(row) then return end
	data.belowFold = h.parseSisterTeamData(row)
	h.addSisterTeamPlayersToActiveData(data.belowFold)
	data.sisterDataLocation = row._pageName
	data.hasSister = true
end

function h.getSisterTeamData(team)
	local query = {
		tables = 'SisterTeams',
		fields = {
			"Status=Status",
			"_pageName",
			"ActiveList=ActiveList",
			"InactiveList=InactiveList"
		},
		where = ('Team="%s"'):format(m_team.teamlinkname(team)),
	}
	return util_cargo.getOneRow(query)
end

function h.parseSisterTeamData(row)
	local ret = {
		active = util_text.splitNonempty(row.ActiveList),
		inactive = { links = util_text.splitOrNil(row.InactiveList) }
	}
	if next(ret.inactive) then
		ret.inactive.names = mw.clone(ret.inactive.links)
	end
	return ret
end

function h.addSisterTeamPlayersToActiveData(belowFold)
	for _, team in ipairs(belowFold.active) do
		belowFold[team] = { links = {}, names = {} }
		h.getPlayers(team, belowFold[team])
	end
end

-- process links

-- need to figure out how to deal with different systems & links
-- but i think that will be handled with team links / sister team concepts
function h.processLinks(data)
	-- we want the navbox to link to corresponding subpages always
	-- so make a long list of all links we have, and then determine existence
	-- make a lookup table that we'll refer to when printing to decide if we link to the subpage or not
	local links = h.getListOfAllLinks(data)
	util_title.concatSubpages(links, SUFFIX)
	local linksHash = util_table.hash(util_title.whichPagesExist(links))
	h.processLinksInData(data, linksHash)
	return
end

function h.getListOfAllLinks(data)
	local links = {}
	if data.aboveFold then
		links[#links+1] = data.aboveFold
		links[#links+1] = util_title.concatSubpageSystem(data.aboveFold, SYSTEM)
		util_table.mergeArrays(links,data[data.aboveFold].links)
	end
	if data.belowFold then
		util_table.mergeArrays(links,data.belowFold.inactive.links)
		for k, v in ipairs(data.belowFold.active) do
			links[#links+1] = v
			util_table.mergeArrays(links,data.belowFold[v].links)
		end
	end
	return links
end

function h.processLinksInData(data, linksHash)
	-- we need 3 pieces of information per link: the link, the display, and whether the proper subpage exists (so we can add the class if needed)
	-- where before we had a table of links, we can add tables of names/exists by adding extra data
	-- where we had a constant, we need to transform to having a table of information
	h.addExtraDataToLinkTables(data[data.aboveFold], linksHash)
	data.aboveFold = h.transformLinkToTable(data.aboveFold, linksHash)
	if data.belowFold then
		for key, team in ipairs(data.belowFold.active) do
			h.addExtraDataToLinkTables(data.belowFold[team], linksHash)
			data.belowFold.active[key] = h.transformLinkToTable(team, linksHash)
		end
		h.addExtraDataToLinkTables(data.belowFold.inactive, linksHash)
	end
	return
end

function h.addExtraDataToLinkTables(list, hash)
	if not list or not next(list) then return end
	if not list.exists then list.exists = {} end
	for k, v in ipairs(list.links) do
		newlink = util_title.concatSubpage(v, SUFFIX)
		list.exists[k] = hash[lang:ucfirst(newlink)]
		list.links[k] = list.exists[k] and newlink or v
	end
	return
end

function h.transformLinkToTable(link, linksHash)
	if not link then return nil end
	local newlink = util_title.concatSubpage(link, SUFFIX)
	local exists = linksHash[lang:ucfirst(newlink)]
	return {
		name = link,
		exists = exists,
		link = exists and newlink or link
	}
end

-- print output
function h.makeOutput(data, args)
	-- navboxargs will be sent to Template:Navbox
	-- if there's an active roster, then the active roster is printed expanded above the fold
	-- then if there's sister team data we print that below the fold
	local thisteam = data.aboveFold
	local navboxargs = {
		name = data.sisterDataLocation or 'OrgNavbox',
		state = 'mw-collapsible'
	}
	local i = 1
	if thisteam then
		navboxargs.group1 = h.makeOneLink(
			util_title.concatSubpageSystem(thisteam.link, SYSTEM),
			m_team.teammediumname(thisteam.name),
			thisteam.exists
		)
		navboxargs.list1 = h.makeListOutput(data[thisteam.name])
		navboxargs.title = h.makeNavboxTitle(thisteam.name, 'Roster')
		i = i + 1
	else
		navboxargs.title = h.makeNavboxTitle(args.team, 'Organization')
	end
	
	if data.belowFold then
		navboxargs['list' .. i] = h.belowFold(data.belowFold, args.innerstate)
	end
	return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end

function h.makeNavboxTitle(thisteam, defaulttext)
	return ('<span class="%s">%s</span> %s'):format(
		SUFFIX and 'no-subpage' or '',
		m_team.rightlonglinked(thisteam, { system = SYSTEM, size = 45 }),
		SUFFIX and ('- ' .. SUFFIX) or defaulttext
	)
end

function h.belowFold(data, state)
	-- print all of the active teams along with their list of players
	-- then print all of the inactive teams just as a list
	-- we return an already-made template that gets passed to the outer navbox as an arg
	local navboxargs = {
		'child',
		title = 'Other Teams In Organization (Click [Show] to the Right)',
		state = state
	}
	for k, v in ipairs(data.active) do
		navboxargs['group' .. k] = h.makeOneLink(
			util_title.concatSubpageSystem(v.link, SYSTEM),
			v.name,
			v.exists
		)
		navboxargs['list' .. k] = h.makeListOutput(data[v.name])
	end
	if data.inactive then
		navboxargs.below = h.makeListOutput(data.inactive)
	end
	return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end

function h.makeListOutput(list)
	-- concat a list of links, doesn't matter if it's players or teams
	-- assume we want the output to be non-nil though because maybe there aren't any players atm but the team is active
	local tbl = {}
	for k, link in ipairs(list.links or {}) do
		tbl[k] = h.makeOneLink(link, list.names[k], list.exists[k])
	end
	local output = table.concat(tbl,' &#8226; ')
	return output
end

function h.makeOneLink(link, name, exists)
	-- concat link and display, adding the span class if it's not linking to the right subpage
	if (not SUFFIX) or exists then
		return util_text.intLink(link, name)
	else
		return ('<span class="no-subpage">[[%s|%s]]</span>'):format(link, name)
	end
end	

return p
Advertisement