local export = {}

local notneeded = {
	["und"] = true,
	["cmn"] = true,
	["ja"] = true,
	["zu"] = true,
	["nan"] = true,
	["yue"] = true,
	["ko"] = true,
}

local neededhassubpage = {
	["ga"] = true,
	["gv"] = true,
	["nv"] = true,
	["roa-jer"] = true,
	["fr"] = true,
	["rm"] = true,
	["prg"] = true,
	["gd"] = true,
	["twf"] = true,
	["en"] = true,
	["ro"] = true,
	["egl"] = true,
	["roa-tar"] = true,
	["gl"] = true,
	["ast"] = true,
	["br"] = true,
}

-- A helper function to escape magic characters in a string
-- Magic characters: ^$()%.[]*+-?
function export.pattern_escape(text)
	text = (type(text) == "table" and text.args[1] or text)
	text = mw.ustring.gsub(text, "([%^$()%%.%[%]*+%-?|])", "%%%1")
	return text
end

--[[
Format the categories with the appropriate sort key. CATEGORIES is a list of
categories.
	-- LANG is an object encapsulating a language; if nil, the object for
	   language code 'und' (undetermined) will be used.
	-- SORT_KEY is placed in the category invocation, and indicates how the
	   page will sort in the respective category. Normally this should be nil,
	   and a default sort key based on the subpage name (the part after the
	   colon) will be used.
	-- SORT_BASE lets you override the default sort key used when SORT_KEY is
	   nil. Normally, this should be nil, and a language-specific default sort
	   key is computed from the subpage name (e.g. for Russian this converts
	   Cyrillic ё to a string consisting of Cyrillic е followed by U+10FFFF,
	   so that effectively ё sorts after е instead of the default Wikimedia
	   sort, which (I think) is based on Unicode sort order and puts ё after я,
	   the last letter of the Cyrillic alphabet.
	-- FORCE_OUTPUT forces normal output in all namespaces. Normally, nothing
	   is output if the page isn't in the main, Appendix:, Reconstruction: or
	   Citations: namespaces.
]]
function export.format_categories(categories, lang, sort_key, sort_base, force_output)
	NAMESPACE = NAMESPACE or mw.title.getCurrentTitle().nsText
	
	if force_output or NAMESPACE == "" or NAMESPACE == "Appendix" or NAMESPACE == "Reconstruction" or NAMESPACE == "Citations" then
		PAGENAME = PAGENAME or mw.title.getCurrentTitle().text
		SUBPAGENAME = SUBPAGENAME or mw.title.getCurrentTitle().subpageText
		
		if not lang then
			lang = require("Modulo:languages").getByCode("und")
		end
		
		-- Generate a default sort key
		sort_base = lang:makeSortKey(sort_base or SUBPAGENAME)
		
		if sort_key and sort_key ~= "" then
			-- Gather some statistics regarding sort keys
			if mw.ustring.upper(sort_key) == sort_base then
				table.insert(categories, "Sort key tracking/redundant")
			end
		else
			sort_key = sort_base
		end
		
		-- If the resulting key is the same as the wiki software's default, remove it
		if sort_key == PAGENAME then
			sort_key = nil
		end
		
		for key, cat in ipairs(categories) do
			categories[key] = "[[Category:" .. cat .. (sort_key and "|" .. sort_key or "") .. "]]"
		end
		
		return table.concat(categories, "")
	else
		return ""
	end
end

-- Used by {{categorize}}
function export.template_categorize(frame)
	NAMESPACE = NAMESPACE or mw.title.getCurrentTitle().nsText
	local format = frame.args["format"]
	local args = frame:getParent().args
	
	local langcode = args[1]; if langcode == "" then langcode = nil end
	local sort_key = args["sort"]; if sort_key == "" then sort_key = nil end
	local categories = {}
	
	if not langcode then
		if NAMESPACE == "Template" then return "" end
		error("Language code has not been specified. Please pass parameter 1 to the template.")
	end
	
	local lang = require("Modulo:languages").getByCode(langcode)
	
	if not lang then
		if NAMESPACE == "Template" then return "" end
		error("The language code \"" .. langcode .. "\" is not valid.")
	end
	
	local prefix = ""
	
	if format == "pos" then
		prefix = lang:getCanonicalName() .. " "
	elseif format == "topic" then
		prefix = lang:getCode() .. ":"
	end
	
	local i = 2
	local cat = args[i]
	
	while cat do
		if cat ~= "" then
			table.insert(categories, prefix .. cat)
		end
		
		i = i + 1
		cat = args[i]
	end
	
	return export.format_categories(categories, lang, sort_key)
end

function export.catfix(lang, sc)
	local canonicalName = lang:getCanonicalName() or error('The first argument to the function "catfix" should be a language object from Modulo:languages.')
	
	if sc and not sc.getCode then
		error('The second argument to the function "catfix" should be a script object from Modulo:scripts.')
	end
	
	return "<span id=\"catfix\" style=\"display:none;\" class=\"CATFIX-" .. mw.uri.anchorEncode(canonicalName) .. "\">" ..
		require("Modulo:script utilities").tag_text("&nbsp;", lang, sc, nil) ..
		"</span>"
end

function export.catfix_template(frame)
	local params = {
		[1] = {},
		[2] = {},
	}
	
	local args = require("Modulo:parameters").process(frame:getParent().args, params)
	
	local lang = require("Modulo:languages").getByCode(args[1]) or require("Modulo:languages").err(args[1], 1)
	
	local sc
	if args[2] then
		sc = require("Modulo:languages").getByCode(args[2]) or error('The script code "' .. args[2] .. '", provided in the second parameter, is not valid.')
	else
		error("Supply a script code in the second parameter.")
	end
	
	return export.catfix(lang, sc)
end

function
	--export. --not exporting because it is not used yet.
	getDateTense(frame) 
	local name_num_mapping = {["January"] = 1, ["February"] = 2, ["March"] = 3, ["April"] = 4, ["May"] = 5, ["June"] = 6, 
		["July"] = 7, ["August"] = 8, ["September"] = 9, ["October"] = 10, ["November"] = 11, ["December"] = 12, 
		[1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12}
	local month = name_num_mapping[frame.args[2]]
	local date = os.time({year = frame.args[1], day = frame.args[3], month = month})
	local today = os.time() -- 12 AM/PM
	local diff = os.difftime(date, today)
	local daylength = 24 * 3600
	
	if diff < -daylength / 2 then return "past"
	else 
		if diff > daylength / 2  then return "future"
		else return "present" end
	end
end

return export