local export = {}

export.override = function( frame )
	local title = frame.args[1]
	local args = {}
	for v, k in pairs( frame:getParent().args ) do
		args[v] = k
	end
	for v, k in pairs( frame.args ) do
		if type( v ) == "number" then
			if v ~= 1 then
				args[ v - 1 ] = k
			end
		else
			args[v] = k
		end
	end
	return frame:expandTemplate{ title = title, args = args }
end

export.prepend = function( frame )
	local title = frame.args[1]
	local args = {}
	local displace = 0;
	for v, k in pairs( frame.args ) do
		if (type( v ) == "number") and (v ~= 1) then
			args[ v - 1 ] = k
			displace = math.max( displace, (v - 1) )
		end
	end
	for v, k in pairs( frame:getParent().args ) do
		if type( v ) == "number" then
			args[ displace + v ] = k
		else
			args[v] = k
		end
	end
	for v, k in pairs( frame.args ) do
		if type( v ) ~= "number" then
			args[v] = k
		end
	end
	return frame:expandTemplate{ title = title, args = args }
end

export.append = function( frame )
	local title = frame.args[1]
	local args = {}
	local displace = 0;
	for v, k in pairs( frame:getParent().args ) do
		if type( v ) == "number" then
			displace = math.max( displace, v )
		end
		args[v] = k
	end
	for v, k in pairs( frame.args ) do
		if type( v ) == "number" then
			if v ~= 1 then
				args[ displace + v - 1 ] = k
			end
		else
			args[v] = k
		end
	end
	return frame:expandTemplate{ title = title, args = args }
end

export.drop = function( frame )
	local title = frame.args[1]
	local args = {}
	for v, k in pairs( frame:getParent().args ) do
		if type( v ) ~= "number" then
			args[v] = k
		end
	end
	for v, k in pairs( frame.args ) do
		if type( v ) == "number" then
			if v ~= 1 then
				args[ v - 1 ] = k
			end
		else
			args[v] = k
		end
	end
	return frame:expandTemplate{ title = title, args = args }
end

export.shiftLeft = function( frame )
	local title = frame.args[1]
	local args = {}
	local displace = tonumber( frame.args[2] )
	if displace == nil then displace = 0 end
	for v, k in pairs( frame:getParent().args ) do
		if type( v ) == "number" then
			if v >= displace then
				args[ v - displace ] = k
			end
		else
			args[v] = k
		end
	end
	for v, k in pairs( frame.args ) do
		if type( v ) == "number" then
			if v > 2 then
				args[ v - 2 ] = k
			end
		else
			args[v] = k
		end
	end
	return frame:expandTemplate{ title = title, args = args }
end

export.map = function( frame )
	local title = frame.args[1]
	local displace = frame.args[2]
	if displace == nil then
		displace = 0
	else
		displace = tonumber( displace )
	end
	local args = {}
	local data = {}
	local maxv = 0
	for v, k in pairs( frame:getParent().args ) do
		if (type( v ) ~= "number") then
			args[v] = k
		elseif v <= displace then
			args[v + 1] = k
		else
			data[v] = k
			maxv = math.max( v, maxv )
		end
	end
	for v, k in pairs( frame.args ) do
		if type( v ) ~= "number" then
			args[v] = k
		elseif v > 2 then
			args[v - 1] = k
		end
	end
	local result = ""
	for v = 1, maxv do
		if data[v] ~= nil then
			args[1] = data[v]
			result = result .. frame:expandTemplate{ title = title, args = args }
		end
	end
	return result
end

export.static = function( frame )
	return frame:getParent():getTitle()
end

local function tabulate( args )
	local s = ''
	for k, v in pairs( args ) do
		s = s .. '|-\n| ' .. k .. '\n| <code>' .. v .. '</code>\n'
	end
	if s ~= '' then
		s = '{| class="wikitable"\n|-\n! key\n! value\n' .. s .. '|}'
	end
	return s
end

export.echo = function( frame )
	local mp = tabulate( frame.args )
	local cp = tabulate( frame:getParent().args )
	if mp ~= '' then
		mp = 'module parameters:\n' .. mp .. '\n'
	end
	if cp ~= '' then
		cp = 'context parameters:\n' .. cp .. '\n'
	else
		cp = 'no context parameters.\n'
	end
	return mp .. cp
end

return export