-- Data is in Module:Track gauge/data
local p = {}
local gaugeDataAll = nil
local dataPageName = 'Module:Track gauge/data' -- sandbox here
-- prepareArgs -- Normalise Arguments coming from an #invoke or from a module
local function prepareArgs(frame)
	local origArgs
	if frame == mw.getCurrentFrame then
		origArgs = frame:getParent.args
		for k, v in pairs(frame.args) do
			origArgs = frame.args
			break
		end
	else
		origArgs = frame
	end
	local args = {}
	-- searchAlias is the cleaned value of args[1]. args[1] is kept as rawInput for error message
	local searchAlias = ''
	local rawDisp
	for k, v in pairs(origArgs) do
		if tonumber(k) == nil then -- Named argment
			if k == 'disp' then
				rawDisp = v -- Keep raw disp input to pass through plain (wiki)text
				args[k] = mw.ustring.lower(v)
			elseif k == 'first' then
				v = mw.ustring.lower(v)
				if v == 'met' or v == 'metric' then
					v = 'met'
				elseif v == 'imp' or v == 'imperial' then
					v = 'imp'
				else k = 'trashparam_first' end
				args[k] = v
			elseif k == 'nowrap' or k == 'wrap' then -- wrap=y deprecated; reading: nowrap=off
				v = mw.ustring.lower(v)
				if v == '' or v == 'off' or v == 'on' or v == 'all' then
				elseif v == 'inline' or (k == 'wrap' and v == 'y') then
					v = 'off'
				else v = '' end
				args['nowrap'] = v
			else
				args[k] = mw.ustring.lower(v)
			end
		else
			args[k] = v -- Keep rawInput in [1] for error message
			if k == 1 then
			-- Unnamed argument, the alias to be searched
			-- Cleanup
				searchAlias = p.normaliseAliasInput(v)
			end
		end
	end
	args['searchAlias'] = searchAlias
	if rawDisp then args['rawDisp'] = rawDisp end
	return args
end
-- normaliseAliasInput
function p.normaliseAliasInput(aliasIn)
	local a
	a = mw.ustring.lower(mw.ustring.gsub)
	a = mw.ustring.gsub
	a = mw.ustring.gsub
	a = mw.ustring.gsub
	a = mw.ustring.gsub
	a = mw.ustring.gsub
	a = mw.ustring.gsub
	return a	
end
-- debugReturnArgs -- Debug function.
function p.debugReturnArgs(frame)
	local args = prepareArgs(frame)
	local retArgs = {}
	for k, a in pairs(args) do
		table.insert
	end
	return 'Args: ' .. table.concat
end
-- getTrackGaugeEntry -- Find entry data for a single gauge (alias)
function p.getTrackGaugeEntry(searchAlias)
	gaugeDataAll = mw.loadData(dataPageName)
	if searchAlias == '' then
		return nil
	end
	local tgEntry = nil
	for i, tgEntry in ipairs(gaugeDataAll) do
		for j, alias in ipairs(tgEntry.aliases) do
			if alias == searchAlias then
				return tgEntry
			end
		end
	end
end
-- noWrap -- Add span tags to prevent a string from wrapping.
local function noWrap(s)
	return mw.ustring.format
end
-- frac -- A slimmed-down version of the template (a nowrap is to be added with the unit)
local function frac
	return mw.ustring.format
end
-- catMentions -- Wikicode for "article mentions gauge" categories
function p.catMentions
	local ns = 'Category:'
	local cat

	if tgEntry == nil then
		-- Parent, the container cat
		cat = 'Articles that mention a specific track gauge'
	else
		cat = 'Articles that mention track gauge ' .. tgEntry.id .. ' mm'
	end
	-- Argument 'label' can be used to add a catsort. Catsort is not used (as of 20 May 2014)
	if sortlabel ~= nil then
		sortlabel = '|' .. sortlabel
	else
		sortlabel = ''
	end
	if doReturn ~= nil then
		if doReturn == 'fullpagename' then
			return ns .. cat
		elseif doReturn == 'pagename' then -- plaintext, no namespace
			return cat
		elseif doReturn == 'show' then -- colontrick
			return ':' .. ns .. cat .. sortlabel .. ''
		else -- unknown arg value
			return ns .. cat
		end
	else -- Returns straight categorisation (wikitext)
		return '' .. ns .. cat .. sortlabel .. ''
	end
end
-- formatImp -- Formats imperial units size into a single text element
function p.formatImp
	local ret = {}
	local ft = tgEntry.ft
	if ft then
		local ftlink = addUnitlink and measurementToLink ~= 'imp' and 'ft' or 'ft'
		table.insert(ret, mw.ustring.format)
	end
	local inches = tgEntry['in']
	local num = tgEntry.num
	local den = tgEntry.den
	if inches and not num and not den then
		table.insert
	elseif num and den then
		table.insert(ret, frac)
	end
	if inches or num and den then
		local incheslink = addUnitlink and measurementToLink ~= 'imp' and 'in' or 'in'
		table.insert
	end
	local gaugeSize
	if setNowrap then
		gaugeSize = noWrap(table.concat)
	else
		gaugeSize = table.concat
	end
	if measurementToLink == 'imp' and tgEntry.pagename ~= nil then
		return mw.ustring.format
	else
		return gaugeSize
	end
end
-- formatMet -- Formats metric measurements into a single formatted text element. Public for autodocument
function p.formatMet
	local m = tgEntry.m
	local gaugeSize
	if m then
		local mUnit = addUnitlink and measurementToLink ~= 'met' and 'm' or 'm'
		gaugeSize = mw.ustring.format
	else
		local mm = tgEntry.mm
		mm = tonumber(mm)
		if mm then
			mm = mw.getContentLanguage:formatNum(mm)
		end
		local mmUnit = addUnitlink and measurementToLink ~= 'met' and 'mm' or 'mm'
		gaugeSize = mw.ustring.format
	end
	if setNowrap then
		gaugeSize = noWrap(gaugeSize)
	end
	if measurementToLink == 'met' and tgEntry.pagename ~= nil then
		return mw.ustring.format
	else
		return gaugeSize
	end
end
-- formatAltName
function formatAltName
	-- Assumed: at least one to add is true.
	if tgEntry.name == nil then
		-- Not checked: link does exist alone
		return ''
	end
	local retAlt = {}
	if disp == 'br' then
		table.insert
	else
		table.insert
	end
	if setNowrap then
		table.insert
	end
	return table.concat
end
-- main -- The basic module
function p.main(frame)
	-- In general: tgEntry (from TG/data) is passed to the functions, arguments are processed here.
	local title = mw.title.getCurrentTitle
	local args = prepareArgs(frame)
	local tgEntry = p.getTrackGaugeEntry(args.searchAlias)

	-- Categorise the page if no gauge information was found.
	if tgEntry == nil then
		local category = ''
		if title:inNamespaces then
			local sort1
			if (args[1] or '') == '' then -- Blank input, sort top.
				sort1 = ' '
			else
				sort1 = args[1] .. ', '
			end
			category = mw.ustring.format
		end
		return (args[1] or '') .. category
	end

	-- Check and set args & tgEntry props: disp, first, nowrap, first
	local disp = args.disp or ''
	local first = args.first or tgEntry.def1
	local unitlink = args.unitlink or ''
	local nowrap = args.nowrap or ''
	local setNowrapElement = (nowrap == '' or nowrap == 'off') -- To prevent nested nowrap tags
	local measurementToLink
	if args.lk == 'on' then
		if disp == '1' then
			measurementToLink = first -- Can make metric text links to the imp linked page
		else
			measurementToLink = tgEntry.def1 -- When first=swapped, this could link 2nd measure.
		end
	end
	-- String the text elements together (compose the return table)
	local ret = {}
	-- nowrap opening tag
	if nowrap == 'all' or nowrap == 'on' then
		table.insert
	end
	-- First measure
	if first == 'met' then
		table.insert(ret,
			p.formatMet)
	else
		table.insert(ret,
			p.formatImp)
	end
	-- The joint and the second measure
	if disp == '1' then
	else
		local joinText = ''
		local closeDisp = ''
		if disp == 's' or disp == '/' then
			joinText = '/&#x200b;'
		elseif disp == 'br' then
			joinText = '')
	end
	-- Alternative name
	if args.al == 'on' or args.allk == 'on' then
		local setNowrapAltname = (nowrap == '' or nowrap == 'on') -- Logic applied to prevent nested nowrap tags
		table.insert(ret, formatAltName)
	end
	-- Closing nowrap tag
	if nowrap == 'all' then
		table.insert
	end
	
	-- Category mentionings (maintenance)
	if args.addcat or '' == 'no' then
		-- No categorization
	elseif title:inNamespaces(0) then
		-- switched off per Wikipedia:Categories_for_discussion/Log/2016_December_6#Category:Articles_that_mention_a_specific_track_gauge
		-- 2016-12-19
		-- table.insert(ret, p.catMentions(tgEntry))
	end

	-- Now sting the table together
	return table.concat
end

return p
--20161219: maintenance categorisation switched off per CfD