Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Module documentation[view][edit][history][purge]
This documentation is transcluded from Module:Navplate/Park/doc. Changes can be proposed in the talk page.

local NavplatePark = {}

local metatable = {}
local methodtable = {}

metatable.__index = methodtable

local cargo = mw.ext.cargo
local navplate = require( 'Module:Navplate' )

function methodtable.processCargoData( self, cargoResult )
	local outputData = ''
	for k1, v1 in pairs( cargoResult ) do
		local match = false
		for k2, v2 in pairs( cargoResult ) do
			if v1.SortName == v2.SortName and v1.Name ~= v2.Name then
				match = true
			end
		end
		
		if (v1.Name ~= nil) then
			outputData = outputData .. v1.Name
		elseif (v1.PageName ~= nil) then
			outputData = outputData .. '[[' .. v1.PageName .. '|' .. v1.PageName:gsub("%(.*", "") .. ']]'
		end
		
		if match == true then
			outputData = outputData .. '<div style="color: var(--color-subtle); margin-left: -2px; display: inline-block;">'
			if v1.Opened ~= nil then
				outputData = outputData .. '(' .. v1.Opened
				
				if v1.Closed ~= nil and v1.Opened ~= v1.Closed then
					outputData = outputData .. '–' .. v1.Closed
				end
				
				outputData = outputData .. ')'
			else
				outputData = outputData .. "''(unknown)''"
			end
			outputData = outputData .. '</div>'
		end
	end

	return outputData
end

function methodtable.getQueryString( self, tableName, parkLinks )
	local queryString = '('

	for k, v in pairs( parkLinks ) do
		queryString = queryString .. string.gsub('$tablename.Park LIKE "%[[$parkname]]%" OR $tablename.Park LIKE "%[[$parkname|%" OR ', '$parkname', v):gsub("$tablename", tableName)
	end

	queryString = queryString:sub(1, -5)
	queryString = queryString .. ')'

	return queryString
end

function methodtable.getPresentCargoData( self, queryTable, parkLinks )
	local cargoResult = cargo.query(queryTable, "CONCAT( '[[',_pageTitle, '|',Name,']]' )=Name,YEAR(Opened)=Opened,YEAR(Closed)=Closed,Name=SortName,_pageName=PageName", {
		where = self:getQueryString(queryTable, parkLinks) .. ' and Status NOT IN ("defunct", "unknown", "cancelled")',
		groupBy = '_pageID'
	})

	return self:processCargoData(cargoResult)
end

function methodtable.getFormerCargoData( self, queryTable, parkLinks )
	local cargoResult = cargo.query(queryTable, "Name=SortName,CONCAT( '[[',_pageTitle, '|',Name,']]' )=Name,YEAR(Opened)=Opened,YEAR(Closed)=Closed,Name=SortName,_pageName=PageName", {
		where = self:getQueryString(queryTable, parkLinks) .. 'and Status IN ("defunct", "unknown", "cancelled")',
		groupBy = '_pageID'
	})

	local pastResult = cargo.query('Roller_Coaster_Past_Locations,' .. queryTable .. '=RideTable', 
		"IF(Roller_Coaster_Past_Locations.Name IS NULL, RideTable.Name, Roller_Coaster_Past_Locations.Name)=SortName,CONCAT( '[[', Roller_Coaster_Past_Locations._pageTitle, '|',IF(Roller_Coaster_Past_Locations.Name IS NULL, RideTable.Name, Roller_Coaster_Past_Locations.Name),']]' )=Name,YEAR(Roller_Coaster_Past_Locations.Opened)=Opened,YEAR(Roller_Coaster_Past_Locations.Closed)=Closed,Roller_Coaster_Past_Locations._pageName=PageName", {
		where = self:getQueryString('Roller_Coaster_Past_Locations', parkLinks),
		join = 'RideTable._pageID = Roller_Coaster_Past_Locations._pageID',
		groupBy = 'Roller_Coaster_Past_Locations._pageID'
	})

	for k,v in pairs(pastResult) do
		table.insert(cargoResult, v)
	end

	if (#cargoResult > 0) then
		-- Sort alphabetically
		table.sort(cargoResult, function(a,b) return a.SortName < b.SortName end)
	end

	return self:processCargoData(cargoResult)
end

function methodtable.getParkNames( self )
	local parkNames = { self.frameArgs[ 1 ] }
	if (parkName ~= nil) then
		return {{name = parkName, current = true }}
	end
	
	-- If page is a park
	local parkQuery = cargo.query("Amusement_Parks", "_pageTitle=PageTitle", {where = '_pageID = ' .. mw.title.getCurrentTitle().id})
	if #parkQuery > 0 then
		return {{ 
			name = parkQuery[1].PageTitle, 
			current = true
		}}
	end
	
	local function getPrimaryPark()
		local function parkQuery(tableName)
			return cargo.query(tableName, "Park", {where = '_pageID = ' .. mw.title.getCurrentTitle().id})
		end

		local coasterQuery = parkQuery("Roller_Coasters")
		if #coasterQuery > 0 then
			return coasterQuery[1].Park
		end
		
		local ridesQuery = parkQuery("Rides")
		if #ridesQuery > 0 then
			return ridesQuery[1].Park
		end
		
		local slidesQuery = parkQuery("Water_Slides")
		if #slidesQuery > 0 then
			return slidesQuery[1].Park
		end
		
		error("Page not found in Cargo")
	end
	
	local function cleanPark(park)
		if (park == nil) then 
			return nil 
		end

		if string.find(park, "%[%[") == nil then
			return nil
		end

		local parkLink = park:gsub("%[%[", ""):gsub("(|(.+))", ""):gsub("%]%].*", "")
		local redirectQuery = cargo.query("_pageData", "_pageNameOrRedirect=PageName", {
			where = '_pageTitle = "' .. parkLink .. '" AND _pageNamespace = 0',
			groupBy = '_pageName'
		})

		if #redirectQuery > 0 then
			return redirectQuery[1].PageName
		end
		return parkLink
	end
	
	local primaryPark = cleanPark(getPrimaryPark())

	local parks = {}
	
	if (primaryPark ~= nil) then
		table.insert(parks, {
			name = primaryPark,
			current = true
		})
	end
	
	local previousParks = cargo.query("Roller_Coaster_Past_Locations", "Park", {
		where = '_pageID = ' .. mw.title.getCurrentTitle().id, 
		groupBy = 'Park',
		orderBy = 'Ordering'
	})
	for k,v in pairs(previousParks) do
		local cleanPark = cleanPark(v.Park)
		if cleanPark ~= nil then
			table.insert(parks, { name = cleanPark, current = false })
		end
	end
	
	local deduplicatedParks = {}
	for k1, v1 in pairs( parks ) do
		local matches = false
		for k2, v2 in pairs( deduplicatedParks ) do
			if v1.name == v2.name then
				matches = true
			end
		end

		if matches == false then
			table.insert(deduplicatedParks, v1)
		end
	end

	return deduplicatedParks
end

function methodtable.getParkLinks( self, parkName )
	local cargoResult = cargo.query("_pageData", "_pageTitle=PageTitle", {
		where = '_pageNameOrRedirect = "' .. parkName .. '" AND _pageNamespace = 0',
		groupBy = 'PageTitle'
	})

	if (#cargoResult == 0) then
		return { parkName }
	end

	local parkLinks = {}

	for k, v in pairs( cargoResult ) do
		table.insert(parkLinks, v.PageTitle)
	end

	return parkLinks
end

--- Outputs the table
---
--- @return string
function methodtable.make( self )
	if (mw.title.getCurrentTitle().id == 0) then
		return navplate.navplateTemplate({args = {title = 'Navbox will be generated on page save'}})
	end
	
	if mw.title.getCurrentTitle().namespace ~= 0 then
		return navplate.navplateTemplate({args = {title = 'Navbox only generated on pages in the main namespace'}}) .. '[[Category:Navboxes not in main namespace]]'
	end
	
	local parkNames = self:getParkNames()
	local parks = {}
	
	for k, parkName in pairs( parkNames ) do
		local parkLinks = self:getParkLinks(parkName.name)
		
		table.insert(parks, {
			parkName = parkName.name,
			current = parkName.current,
			presentCoasters = self:getPresentCargoData('Roller_Coasters', parkLinks),
			presentRides = self:getPresentCargoData('Rides', parkLinks),
			presentSlides = self:getPresentCargoData('Water_Slides', parkLinks),
			formerCoasters = self:getFormerCargoData('Roller_Coasters', parkLinks),
			formerRides = self:getFormerCargoData('Rides', parkLinks),
			formerSlides = self:getFormerCargoData('Water_Slides', parkLinks)
		})
	end

	local output = ''
	for k, park in pairs( parks ) do
		local args = {
			id = park.parkName,
			open = tostring(park.current),
			title = '[[' .. park.parkName .. '|' .. park.parkName:gsub("%(.*", "") .. ']]',
			header1 = ((park.presentCoasters ~= '' or park.presentRides ~= '' or park.presentSlides ~= '') and 'Present' or nil),
			label2 = 'Coasters',
			list2 = park.presentCoasters,
			label3 = 'Attractions',
			list3 = park.presentRides,
			label4 = 'Water slides',
			list4 = park.presentSlides,
			header5 = ((park.formerCoasters ~= '' or park.formerRides ~= '' or park.formerSlides ~= '') and 'Former' or nil),
			label6 = 'Coasters',
			list6 = park.formerCoasters,
			label7 = 'Attractions',
			list7 = park.formerRides,
			label8 = 'Water slides',
			list8 = park.formerSlides,
		}
		output = output .. tostring(navplate.navplateTemplate({args = args}))
	end
	
	return output
end

--- Set the frame and load args
--- @param frame table
function methodtable.setFrame( self, frame )
	self.currentFrame = frame
	self.frameArgs = require( 'Module:Arguments' ).getArgs( frame )
end

--- New Instance
---
--- @return table NavplatePark
function NavplatePark.new( self )
    local instance = {}
    setmetatable( instance, metatable )
    return instance
end


--- "Main" entry point
---
--- @param frame table Invocation frame
--- @return string
function NavplatePark.main( frame )
    local instance = NavplatePark:new()
	instance:setFrame( frame )

    return instance:make() .. '[[Category:Pages with park navbox]]'
end

return NavplatePark