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 m_translit = require("Module:Goth-translit")

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

local export = {}


local function postprocess(args, data)
	-- Check if the lemma form matches the page name
	if (data.forms["m_nom_sg"] or data.forms["strong_m_nom_sg"]) and (lang:makeEntryName(m_translit.tr_reverse((data.forms["m_nom_sg"] or data.forms["strong_m_nom_sg"])[1]))) ~= mw.title.getCurrentTitle().text then
		table.insert(data.categories, lang:getCanonicalName() .. " entries with inflection not matching pagename")
	end
end


local function make_Latn(args, names)
	for _, name in ipairs(names) do
		if args[name] then
			if type(args[name]) == "table" then
				for i, _ in ipairs(args[name]) do
					args[name][i] = m_translit.tr(args[name][i])
				end
			else
				args[name] = m_translit.tr(args[name])
			end
		end
	end
end


local function weak(data, stem, prefix)
	if prefix then
		data.weak = true
		
		for key, forms in pairs(data.forms) do
			if not mw.ustring.find(key, "^strong_") then
				data.forms["strong_" .. key] = forms
			end
		end
		
		for key, forms in pairs(data.forms) do
			if not mw.ustring.find(key, "^strong_") then
				data.forms[key] = nil
			end
		end
	end
	
	data.forms[(prefix and "weak_" or "") .. "m_nom_sg"] = {stem .. "a"}
	data.forms[(prefix and "weak_" or "") .. "m_acc_sg"] = {stem .. "an"}
	data.forms[(prefix and "weak_" or "") .. "m_gen_sg"] = {stem .. "ins"}
	data.forms[(prefix and "weak_" or "") .. "m_dat_sg"] = {stem .. "in"}
	
	data.forms[(prefix and "weak_" or "") .. "m_nom_pl"] = {stem .. "ans"}
	data.forms[(prefix and "weak_" or "") .. "m_acc_pl"] = {stem .. "ans"}
	data.forms[(prefix and "weak_" or "") .. "m_gen_pl"] = {stem .. "anē"}
	data.forms[(prefix and "weak_" or "") .. "m_dat_pl"] = {stem .. "am"}
	
	data.forms[(prefix and "weak_" or "") .. "f_nom_sg"] = {stem .. "ō"}
	data.forms[(prefix and "weak_" or "") .. "f_acc_sg"] = {stem .. "ōn"}
	data.forms[(prefix and "weak_" or "") .. "f_gen_sg"] = {stem .. "ōns"}
	data.forms[(prefix and "weak_" or "") .. "f_dat_sg"] = {stem .. "ōn"}
	
	data.forms[(prefix and "weak_" or "") .. "f_nom_pl"] = {stem .. "ōns"}
	data.forms[(prefix and "weak_" or "") .. "f_acc_pl"] = {stem .. "ōns"}
	data.forms[(prefix and "weak_" or "") .. "f_gen_pl"] = {stem .. "ōnō"}
	data.forms[(prefix and "weak_" or "") .. "f_dat_pl"] = {stem .. "ōm"}
	
	data.forms[(prefix and "weak_" or "") .. "n_nom_sg"] = {stem .. "ō"}
	data.forms[(prefix and "weak_" or "") .. "n_acc_sg"] = {stem .. "ō"}
	data.forms[(prefix and "weak_" or "") .. "n_gen_sg"] = {stem .. "ins"}
	data.forms[(prefix and "weak_" or "") .. "n_dat_sg"] = {stem .. "in"}
	
	data.forms[(prefix and "weak_" or "") .. "n_nom_pl"] = {stem .. "ōna"}
	data.forms[(prefix and "weak_" or "") .. "n_acc_pl"] = {stem .. "ōna"}
	data.forms[(prefix and "weak_" or "") .. "n_gen_pl"] = {stem .. "anē"}
	data.forms[(prefix and "weak_" or "") .. "n_dat_pl"] = {stem .. "am"}
end


-- Inflection functions

export["a"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		[2] = {},
		["nomsg"] = {},
		
		["j"] = {},
		["noweak"] = {type = "boolean"},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1, 2, "nomsg"})
	
	if args["j"] and not (args["j"] == "ji" or args["j"] == "ei") then
		error("Invalid value for parameter j=, must be \"ji\", \"ei\" or empty.")
	end
	
	local data = {forms = {}, info = (args["j"] and "j" or "") .. "a-stem" .. (args["noweak"] and ", strong forms only" or ""), categories = {lang:getCanonicalName() .. " a-stem adjectives"}}
	data.sg = true
	data.pl = true
	
	data.forms["m_nom_sg"] = {args["nomsg"] or (args[2] or args[1]) .. (args["j"] or "") .. "s"}
	data.forms["m_acc_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ana"}
	data.forms["m_gen_sg"] = {args[1] .. (args["j"] or "i") .. "s"}
	data.forms["m_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "amma"}
	
	data.forms["m_nom_pl"] = {args[1] .. (args["j"] and "j" or "") .. "ai"}
	data.forms["m_acc_pl"] = {args[1] .. (args["j"] and "j" or "") .. "ans"}
	data.forms["m_gen_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aizē"}
	data.forms["m_dat_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aim"}
	
	data.forms["f_nom_sg"] = {args[1] .. (args["j"] == "ei" and "i" or args["j"] and "ja" or "a")}
	data.forms["f_acc_sg"] = {args[1] .. (args["j"] and "j" or "") .. "a"}
	data.forms["f_gen_sg"] = {args[1] .. (args["j"] and "j" or "") .. "aizōs"}
	data.forms["f_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ai"}
	
	data.forms["f_nom_pl"] = {args[1] .. (args["j"] and "j" or "") .. "ōs"}
	data.forms["f_acc_pl"] = {args[1] .. (args["j"] and "j" or "") .. "ōs"}
	data.forms["f_gen_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aizō"}
	data.forms["f_dat_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aim"}
	
	data.forms["n_nom_sg"] = {(args[2] or args[1]) .. (args["j"] and "i" or ""), args[1] .. (args["j"] and "j" or "") .. "ata"}
	data.forms["n_acc_sg"] = {(args[2] or args[1]) .. (args["j"] and "i" or ""), args[1] .. (args["j"] and "j" or "") .. "ata"}
	data.forms["n_gen_sg"] = {args[1] .. (args["j"] or "i") .. "s"}
	data.forms["n_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "amma"}
	
	data.forms["n_nom_pl"] = {args[1] .. (args["j"] and "j" or "") .. "a"}
	data.forms["n_acc_pl"] = {args[1] .. (args["j"] and "j" or "") .. "a"}
	data.forms["n_gen_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aizē"}
	data.forms["n_dat_pl"] = {args[1] .. (args["j"] and "j" or "") .. "aim"}
	
	if not args["noweak"] then
		weak(data, args[1] .. (args["j"] and "j" or ""), true)
	end
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["a-uh"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		[2] = {},
		["nomsg"] = {},
		
		["j"] = {},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1, 2, "nomsg"})
	
	if args["j"] and not (args["j"] == "ji" or args["j"] == "ei") then
		error("Invalid value for parameter j=, must be \"ji\", \"ei\" or empty.")
	end
	
	local data = {forms = {}, info = (args["j"] and "j" or "") .. "a-stem, strong singular forms only", categories = {lang:getCanonicalName() .. " a-stem adjectives"}}
	data.sg = true
	
	data.forms["m_nom_sg"] = {args["nomsg"] or (args[2] or args[1]) .. (args["j"] or "") .. "zuh"}
	data.forms["m_acc_sg"] = {args[1] .. (args["j"] and "j" or "") .. "anōh"}
	data.forms["m_gen_sg"] = {args[1] .. (args["j"] or "i") .. "zuh"}
	data.forms["m_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ammēh"}
	
	data.forms["f_nom_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ōh"}
	data.forms["f_acc_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ōh"}
	data.forms["f_gen_sg"] = {args[1] .. (args["j"] and "j" or "") .. "aizōzuh"}
	data.forms["f_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "aih"}
	
	data.forms["n_nom_sg"] = {args[1] .. (args["j"] and "j" or "") .. "atōh"}
	data.forms["n_acc_sg"] = {args[1] .. (args["j"] and "j" or "") .. "atōh"}
	data.forms["n_gen_sg"] = {args[1] .. (args["j"] or "i") .. "zuh"}
	data.forms["n_dat_sg"] = {args[1] .. (args["j"] and "j" or "") .. "ammēh"}
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["i"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		[2] = {},
		["nomsg"] = {},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1, 2, "nomsg"})
	
	local data = {forms = {}, info = "i-stem", categories = {lang:getCanonicalName() .. " i-stem adjectives"}}
	data.sg = true
	data.pl = true
	
	data.forms["m_nom_sg"] = {args["nomsg"] or (args[2] or args[1]) .. "s"}
	data.forms["m_acc_sg"] = {args[1] .. "jana"}
	data.forms["m_gen_sg"] = {args[1] .. "is"}
	data.forms["m_dat_sg"] = {args[1] .. "jamma"}
	
	data.forms["m_nom_pl"] = {args[1] .. "jai"}
	data.forms["m_acc_pl"] = {args[1] .. "jans"}
	data.forms["m_gen_pl"] = {args[1] .. "jaizē"}
	data.forms["m_dat_pl"] = {args[1] .. "jaim"}
	
	data.forms["f_nom_sg"] = {args["nomsg"] or (args[2] or args[1]) .. "s"}
	data.forms["f_acc_sg"] = {args[1] .. "ja"}
	data.forms["f_gen_sg"] = {args[1] .. "jaizōs"}
	data.forms["f_dat_sg"] = {args[1] .. "jai"}
	
	data.forms["f_nom_pl"] = {args[1] .. "jōs"}
	data.forms["f_acc_pl"] = {args[1] .. "jōs"}
	data.forms["f_gen_pl"] = {args[1] .. "jaizō"}
	data.forms["f_dat_pl"] = {args[1] .. "jaim"}
	
	data.forms["n_nom_sg"] = {args[2] or args[1], args[1] .. "jata"}
	data.forms["n_acc_sg"] = {args[2] or args[1], args[1] .. "jata"}
	data.forms["n_gen_sg"] = {args[1] .. "is"}
	data.forms["n_dat_sg"] = {args[1] .. "jamma"}
	
	data.forms["n_nom_pl"] = {args[1] .. "ja"}
	data.forms["n_acc_pl"] = {args[1] .. "ja"}
	data.forms["n_gen_pl"] = {args[1] .. "jaizē"}
	data.forms["n_dat_pl"] = {args[1] .. "jaim"}
	
	weak(data, args[1] .. "j", true)
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["n"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1})
	
	local data = {forms = {}, info = "n-stem, weak forms only", categories = {lang:getCanonicalName() .. " n-stem adjectives"}}
	data.sg = true
	data.pl = true
	
	weak(data, args[1], false)
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["in"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1})
	
	local data = {forms = {}, info = "an/īn-stem, weak forms only", categories = {lang:getCanonicalName() .. " an/īn-stem adjectives", lang:getCanonicalName() .. " comparative adjectives"}}
	data.sg = true
	data.pl = true
	
	weak(data, args[1], false)
	
	data.forms["f_nom_sg"] = {args[1] .. "ei"}
	data.forms["f_acc_sg"] = {args[1] .. "ein"}
	data.forms["f_gen_sg"] = {args[1] .. "eins"}
	data.forms["f_dat_sg"] = {args[1] .. "ein"}
	
	data.forms["f_nom_pl"] = {args[1] .. "eins"}
	data.forms["f_acc_pl"] = {args[1] .. "eins"}
	data.forms["f_gen_pl"] = {args[1] .. "einō"}
	data.forms["f_dat_pl"] = {args[1] .. "eim"}
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["pp"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1})
	
	local data = {forms = {}, info = "an/īn-stem, strong in m. nom. sg.", categories = {lang:getCanonicalName() .. " an/īn-stem adjectives"}}
	data.sg = true
	data.pl = true
	
	weak(data, args[1], false)
	
	table.insert(data.forms["m_nom_sg"], 1, args[1] .. "s")
	
	data.forms["f_nom_sg"] = {args[1] .. "ei"}
	data.forms["f_acc_sg"] = {args[1] .. "ein"}
	data.forms["f_gen_sg"] = {args[1] .. "eins"}
	data.forms["f_dat_sg"] = {args[1] .. "ein"}
	
	data.forms["f_nom_pl"] = {args[1] .. "eins"}
	data.forms["f_acc_pl"] = {args[1] .. "eins"}
	data.forms["f_gen_pl"] = {args[1] .. "einō"}
	data.forms["f_dat_pl"] = {args[1] .. "eim"}
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


export["u"] = function(frame)
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	make_Latn(args, {1})
	
	local data = {forms = {}, info = "u-stem", categories = {lang:getCanonicalName() .. " u-stem adjectives"}}
	data.sg = true
	data.pl = true
	
	data.forms["m_nom_sg"] = {args[1] .. "us"}
	data.forms["m_acc_sg"] = {args[1] .. "jana"}
	data.forms["m_gen_sg"] = {"*" .. args[1] .. "aus"}
	data.forms["m_dat_sg"] = {"*" .. args[1] .. "jamma"}
	
	data.forms["m_nom_pl"] = {args[1] .. "jai"}
	data.forms["m_acc_pl"] = {args[1] .. "jans"}
	data.forms["m_gen_pl"] = {args[1] .. "jaizē"}
	data.forms["m_dat_pl"] = {args[1] .. "jaim"}
	
	data.forms["f_nom_sg"] = {args[1] .. "us"}
	data.forms["f_acc_sg"] = {args[1] .. "ja"}
	data.forms["f_gen_sg"] = {"*" .. args[1] .. "jaizōs"}
	data.forms["f_dat_sg"] = {"*" .. args[1] .. "jai"}
	
	data.forms["f_nom_pl"] = {args[1] .. "jōs"}
	data.forms["f_acc_pl"] = {args[1] .. "jōs"}
	data.forms["f_gen_pl"] = {args[1] .. "jaizō"}
	data.forms["f_dat_pl"] = {args[1] .. "jaim"}
	
	data.forms["n_nom_sg"] = {(args[2] or args[1]) .. "u", args[1] .. "jata"}
	data.forms["n_acc_sg"] = {(args[2] or args[1]) .. "u", args[1] .. "jata"}
	data.forms["n_gen_sg"] = {"*" .. args[1] .. "aus"}
	data.forms["n_dat_sg"] = {"*" .. args[1] .. "jamma"}
	
	data.forms["n_nom_pl"] = {"*" .. args[1] .. "ja"}
	data.forms["n_acc_pl"] = {"*" .. args[1] .. "ja"}
	data.forms["n_gen_pl"] = {args[1] .. "jaizē"}
	data.forms["n_dat_pl"] = {args[1] .. "jaim"}
	
	weak(data, args[1] .. "j", true)
	
	postprocess(args, data)
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


-- Make the table
function make_table(data)
	local function repl(param)
		if param == "info" then
			return mw.getContentLanguage():ucfirst(data.info or "")
		end
		
		local form = data.forms[param]
		
		if not form or #form == 0 then
			return "—"
		end
		
		local ret_Goth = {}
		local ret_Latn = {}
		
		for key, subform in ipairs(form) do
			table.insert(ret_Latn, m_links.full_link({lang = lang, term = subform, tr = "-"}))
			table.insert(ret_Goth, m_links.full_link({lang = lang, term = m_translit.tr_reverse(subform), tr = "-"}))
		end
		
		return table.concat(ret_Goth, ", ") .. "<br/>" ..  table.concat(ret_Latn, ", ")
	end
	
	local names = {
		["nom"] = "nominative",
		["acc"] = "accusative",
		["gen"] = "genitive",
		["dat"] = "dative",
		
		["sg"] = "singular",
		["pl"] = "plural",
		
		["m"] = "masculine",
		["f"] = "feminine",
		["n"] = "neuter",
		
		["strong_"] = "strong (indefinite) inflection",
		["weak_"] = "weak (definite) inflection",
	}
	
	local genders = {"m", "f", "n"}
	local numbers = {}
	local cases = {"nom", "acc", "gen", "dat"}
	local prefixes = {""}
	
	if data.weak then
		prefixes = {"strong_", "weak_"}
	end
	
	if data.sg then
		table.insert(numbers, "sg")
	end
	
	if data.pl then
		table.insert(numbers, "pl")
	end
	
	local wikicode = {}
	
	table.insert(wikicode, "{| class=\"wikitable inflection-table vsSwitcher\" style=\"border-style: double; border-width: 3px;\" cellspacing=\"1\"")
	table.insert(wikicode, "|-")
	table.insert(wikicode, "! class=\"vsToggleElement\" style=\"background: #CCC; min-width: " .. (8 + #genders * 12) .. "em; text-align: left;\" colspan=\"" .. (#genders + 1) .. "\" | {{{info}}}")
	
	for _, prefix in ipairs(prefixes) do
		if prefix ~= "" then
			table.insert(wikicode, "|- class=\"vsHide\"")
			table.insert(wikicode, "! style=\"background: #DDD;\" colspan=\"" .. (#genders + 1) .. "\" | " .. mw.getContentLanguage():ucfirst(names[prefix]))
		end
		
		for _, number in ipairs(numbers) do
			table.insert(wikicode, "|- class=\"vsHide\"")
			table.insert(wikicode, "! style=\"min-width: 8em;\" | " .. mw.getContentLanguage():ucfirst(names[number]))
			
			for _, gender in ipairs(genders) do
				table.insert(wikicode, "! style=\"min-width: 12em;\" | " .. mw.getContentLanguage():ucfirst(names[gender]))
			end
			
			for _, case in ipairs(cases) do
				table.insert(wikicode, "|- class=\"vsHide\"")
				table.insert(wikicode, "! " .. mw.getContentLanguage():ucfirst(names[case]))
				
				for _, gender in ipairs(genders) do
					table.insert(wikicode, "| {{{" .. prefix .. gender .. "_" .. case .. "_" .. number .. "}}}")
				end
			end
		end
	end
	
	table.insert(wikicode, "|}")
	
	wikicode = table.concat(wikicode, "\n")
	
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)
end

return export