This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local m_utilities = require("Module:utilities")
local m_links = require("Module:links")

local export = {}

local lang = require("Module:languages").getByCode("sga")


-- Inflection functions

export["manual"] = function(frame)
	local wikicode = frame:expandTemplate{title = frame.args["template"], args = {}}
	
	local params = {
		["present_class"] = {list = true},
		["preterite_class"] = {list = true},
		["future_class"] = {list = true},
		["subjunctive_class"] = {list = true},
		["class"] = {},
		}
	
	local form_params = {}
	
	for match in mw.ustring.gmatch(wikicode, "{{{([a-z0-9_]+)}}}") do
		if match ~= "info" then
			params[match] = {list = true, default = mw.title.getCurrentTitle().nsText == "Template" and "{{{" .. match .. "}}}" or nil}
			params[match .. "_q"] = {list = match .. "\1_q", allow_holes = true},
			table.insert(form_params, match)
		end
	end
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local data = {info = {frame.args["cat"]}, categories = {lang:getCanonicalName() .. " " .. frame.args["cat"] .. " verbs"}}

	for _, tense in ipairs({"present", "preterite", "future", "subjunctive"}) do
		if #args[tense .. "_class"] > 0 then
			local classtext = tense == "present" and "class " or ""
			table.insert(data.info, classtext .. mw.text.listToText(args[tense .. "_class"]) .. " " .. tense)
			
			for _, class in ipairs(args[tense .. "_class"]) do
				table.insert(data.categories, lang:getCanonicalName() .. " " .. classtext .. class .. " " .. tense .. " verbs")
			end
		end
	end
	
	if args["class"] then
		require("Module:debug").track("sga-verbs/class")
		table.insert(data.info, args["class"])
	end
	
	data.info = table.concat(data.info, ", ")

	data.args = args

	return make_table(data, wikicode)
end


-- Expand something like "as·ruba(i)rtat(ar)" into "as·rubartat, as·rubairtat, as·rubartatar, as·rubairtatar".
local function expand_parens(form)
	local parts = require("Module:string utilities").capturing_split(form, "%((.-)%)")
	local so_far = {parts[1]}
	for i=2, #parts - 1, 2 do
		local new = {}
		for _, sf in ipairs(so_far) do
			table.insert(new, sf .. parts[i + 1])
		end
		for _, sf in ipairs(so_far) do
			table.insert(new, sf .. parts[i] .. parts[i + 1])
		end
		so_far = new
	end
	return so_far
end


local function link(form)
	return m_links.full_link { lang = lang, term = form }
end


-- Make the table
function make_table(data, wikicode)
	local function repl(param)
		if param == "info" then
			return mw.getContentLanguage():ucfirst(data.info or "")
		end
		
		local form = data.args[param]
		
		if not form or #form == 0 then
			return ""
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			local qtext
			if not data.args[param .. "_q"] or not data.args[param .. "_q"][key] then
				qtext = ""
			else
				qtext = ' <span style="font-size:85%;">' .. require("Module:qualifier").format_qualifier({data.args[param .. "_q"][key]}) .. "</span>"
			end
			if subform:find("<") then
				-- already linked
			else
				local indiv_forms = mw.text.split(subform, "%s*,%s*")
				for i, indiv_form in ipairs(indiv_forms) do
					if indiv_form:find("%(") then
						local new_subforms = expand_parens(indiv_form)
						for j, subform in ipairs(new_subforms) do
							new_subforms[j] = link(new_subforms[j])
						end
						indiv_form = table.concat(new_subforms, ", ")
					else
						indiv_form = link(indiv_form)
					end
					indiv_forms[i] = indiv_form
				end
				subform = table.concat(indiv_forms, ", ")
			end

			table.insert(ret, subform .. qtext)
		end
		
		return table.concat(ret, "; ")
	end
	
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl) .. m_utilities.format_categories(data.categories, lang)
end

return export