Module:Class555Infobox

From Tyne and Wear Metro wiki

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

local p = {}

local function getUICCheckDigit(baseEVN)
	if #baseEVN ~= 11 then
		error("Base EVN must be 11 digits long")
	end

	local sum = 0
	for i = 1, 11 do
		local digit = tonumber(baseEVN:sub(i, i))
		local weight = ((11 - i) % 2 == 0) and 2 or 1
		local product = digit * weight
		sum = sum + (product > 9 and (product - 9) or product)
	end
	return (10 - (sum % 10)) % 10
end

function p.main(frame)
	local args = frame:getParent().args
	
	local semanticData = {}
	
	local tableElement = mw.html.create( 'table' ):addClass( 'infobox' ):wikitext( '[[Category:Class 555 units| ]]' )
	local captionElement = tableElement:tag( 'caption' )
	local vehicleIdentifier = mw.text.trim(args['Unit number'] or mw.title.getCurrentTitle().text)
	
	captionElement:tag( 'span' ):addClass( 'vehicle-identifier' )
		:wikitext( vehicleIdentifier )
	semanticData['Has vehicle identifier'] = vehicleIdentifier
		
	if args['Official nickname'] then
		captionElement:tag( 'span' ):addClass( 'nickname' )
			:wikitext( args['Official nickname'] )
		semanticData['Has official nickname'] = args['Official nickname']
	end
	
	-- EVN numbers
	local stadlerUnitNumber = vehicleIdentifier:match("^5550(%d%d)$")
	if stadlerUnitNumber then
		local evns = {}

		for car = 1, 5 do
			local baseEVN = "94700990" .. car .. stadlerUnitNumber			
			table.insert(evns, baseEVN .. "-" .. getUICCheckDigit(baseEVN))
		end

		semanticData['Has European Vehicle Number'] = evns
	end
	
	if args['Photo'] then
		tableElement:tag( 'tr' )
			:tag( 'td' ):attr( 'colspan', '2' )
				:wikitext( '[[File:' .. args['Photo'] .. '|300px]]' )
		semanticData['Has primary image'] = 'File:' .. args['Photo']
	end
	
	if args['Status'] then
		local statusKey = mw.text.trim(args['Status']):lower()
		if statusKey == 'active' then
			statusKey = 'passenger service'
		elseif statusKey == 'kilometre accumulation' then
			statusKey = 'local testing'
		end
		tableElement:node(
			require('Module:VehicleStates')._renderStatusRow(statusKey, {
				['local testing'] = { name = 'Kilometre accumulation' }
			})
		)
	end
	
    local dates = {}
    if args['Date ex-works'] then
        table.insert(dates, 'Ex-works<sup title="Left the production line">[?]</sup> ' .. args['Date ex-works'])
        semanticData['Has date ex-works'] = args['Date ex-works']
    end
    if args['Date delivered'] then
        table.insert(dates, 'Delivered to Metro ' .. args['Date delivered'])
        semanticData['Has date delivered to Metro'] = args['Date delivered']
    end
    if args['Date of first daylight test'] then
        table.insert(dates, 'First daylight test ' .. args['Date of first daylight test'])
        semanticData['Has date of first daylight test'] = args['Date of first daylight test']
    end
    if args['Date of first passenger service'] then
        table.insert(dates, 'First passenger service ' .. args['Date of first passenger service'])
        semanticData['Has date of first known passenger service'] = args['Date of first passenger service']
    end
	if args['Date of last known passenger service'] then
		table.insert(dates, 'Last known <abbr title="passenger service">pax</abbr> ' .. args['Date of last known passenger service'])
		semanticData['Has date of last known passenger service'] = args['Date of last known passenger service']
    end
    
    if #dates == 1 then
		tableElement:tag( 'tr' )
			:tag( 'td' ):addClass( 'key-dates' )
				:attr( 'colspan', '2' )
				:wikitext( dates[1] )
	elseif #dates > 1 then
		local row = tableElement:tag( 'tr' )
		row:tag( 'th' ):attr( 'scope', 'row' ):wikitext( 'Key dates' )
		local list = row:tag( 'td' )
			:tag( 'ul' ):addClass( 'key-dates' )
        for _, date in ipairs(dates) do
            list:tag('li'):wikitext(date)
        end
	end
	
	if args['Delivery convoys'] then
		local row = tableElement:tag( 'tr' )
		row:tag( 'th' ):attr( 'scope', 'row' ):wikitext( 'Delivery convoys' )
		local td = row:tag( 'td' )
		local ol = td:tag( 'ol' )
		local allDeliveryVehicles = {}
		for convoy in mw.text.gsplit(args['Delivery convoys'], ',') do
			local vehiclesInConvoy = {}
			for vehicle in mw.text.gsplit(convoy, '%s*%+%s*') do
				if vehicle ~= '' then
			    	table.insert(vehiclesInConvoy, vehicle)
			    	allDeliveryVehicles[vehicle] = true
				end
			end
			if #vehiclesInConvoy > 0 then
				local li = ol:tag( 'li' )
				local convoyStr = table.concat(vehiclesInConvoy, "+")
				
				semanticData['Has delivery convoy'] = semanticData['Has delivery convoy'] or {}
				table.insert(semanticData['Has delivery convoy'], convoyStr)
				
				for i, vehicle in ipairs(vehiclesInConvoy) do
			    	if i > 1 then
			    		li:wikitext( '+' )
		    		end
		    		if mw.title.new( vehicle ).exists then
			        	li:wikitext( '[[' .. vehicle .. ']]' )
		        	else
			        	li:wikitext( vehicle )
		    		end
				end
			end
		end
		allDeliveryVehicles[vehicleIdentifier] = nil
		
		local hasDeliveryConvoyVehicles = {}
		for vehicle, _ in pairs(allDeliveryVehicles) do
			table.insert(hasDeliveryConvoyVehicles, vehicle)
		end
		if #hasDeliveryConvoyVehicles > 0 then
			semanticData['Has delivery convoy vehicle'] = hasDeliveryConvoyVehicles
		end
	end
	
	if args['Artwork A'] or args['Artwork B'] then
		local row = tableElement:tag( 'tr' )
		row:tag( 'th' ):attr( 'scope', 'row' ):wikitext( 'Artworks' )
		local ol = row:tag( 'td' )
			:tag( 'ol' )
		if args['Artwork A'] then
			ol:tag( 'li' ):wikitext( args['Artwork A'] )
			semanticData['Has 555 artwork A'] = args['Artwork A']
		end
		if args['Artwork B'] then
			ol:tag( 'li' ):wikitext( args['Artwork B'] )
			semanticData['Has 555 artwork B'] = args['Artwork B']
		end
	end
	
	local smwResult = mw.smw.set( semanticData )
	if smwResult ~= true then
		tableElement:tag('tr')
			:tag('td')
			:attr('colspan', '2')
			:css('color', 'red')
			:css('font-weight', 'bold')
			:wikitext('SMW Error: ' .. smwResult.error)
	end
	
    return tableElement
end

return p