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

local export = {}

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

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

local conj_data = {}

conj_data["st"] = {
	params = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		["mutstem"] = {},
		["impr"] = {},
		["class"] = {},
		},
}
setmetatable(conj_data["st"], {__call = function(self, args, data)
	if not args.class then
		error("Class parameter required for strong verbs")
	end
	data.conj_type = "strong class " .. args.class
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	data.forms["inf"] = {args.head or (args[1] .. "an")}
	
	data.forms["pres_ind_1s"] = {(args.mutstem or args[1]) .. "u", (args.mutstem or args[1]) .. "o"}
	data.forms["pres_ind_2s"] = {(args.mutstem or args[1]) .. "is", (args.mutstem or args[1]) .. "ist"}
	data.forms["pres_ind_3s"] = {(args.mutstem or args[1]) .. "it"}
	data.forms["pres_ind_1p"] = {args[1] .. "em", args[1] .. "emēs"}
	data.forms["pres_ind_2p"] = {args[1] .. "et"}
	data.forms["pres_ind_3p"] = {args[1] .. "ant"}

	data.forms["past_ind_1s"] = {args[2]}
	data.forms["past_ind_2s"] = {args[3] .. "i"}
	data.forms["past_ind_3s"] = {args[2]}
	data.forms["past_ind_1p"] = {args[3] .. "um", args[3] .. "umēs"}
	data.forms["past_ind_2p"] = {args[3] .. "ut"}
	data.forms["past_ind_3p"] = {args[3] .. "un"}

	data.forms["pres_sub_1s"] = {args[1] .. "e"}
	data.forms["pres_sub_2s"] = {args[1] .. "ēs", args[1] .. "ēst"}
	data.forms["pres_sub_3s"] = {args[1] .. "e"}
	data.forms["pres_sub_1p"] = {args[1] .. "ēm", args[1] .. "emēs"}
	data.forms["pres_sub_2p"] = {args[1] .. "ēt"}
	data.forms["pres_sub_3p"] = {args[1] .. "ēn"}
	
	data.forms["past_sub_1s"] = {args[3] .. "i"}
	data.forms["past_sub_2s"] = {args[3] .. "īs", args[3] .. "īst"}
	data.forms["past_sub_3s"] = {args[3] .. "i"}
	data.forms["past_sub_1p"] = {args[3] .. "īm", args[3] .. "īmēs"}
	data.forms["past_sub_2p"] = {args[3] .. "īt"}
	data.forms["past_sub_3p"] = {args[3] .. "īn"}
	
	data.forms["imp_s"] = {(args.impr or args.mutstem) or args[1]}
	data.forms["imp_p"] = {args[1] .. "et"}
	
	data.forms["pres_part"] = {args[1] .. "anti"}
	data.forms["past_part"] = {args[4]}
	
	table.insert(data.categories, "Old High German class " .. args.class .. " strong verbs")
end
})

conj_data["wk1"] = {
	params = {
		[1] = {},
		[2] = {},
		["mutstem"] = {},
		["impr"] = {},
		["past_ptc"] = {},
		},
}
setmetatable(conj_data["wk1"], {__call = function(self, args, data)
	data.conj_type = "weak class 1"
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	data.forms["inf"] = {args.head or (args[1] .. "en")}
	
	data.forms["pres_ind_1s"] = {args[1] .. "u"}
	data.forms["pres_ind_2s"] = {(args.mutstem or args[1]) .. "is", (args.mutstem or args[1]) .. "ist"}
	data.forms["pres_ind_3s"] = {(args.mutstem or args[1]) .. "it"}
	data.forms["pres_ind_1p"] = {args[1] .. "em", args[1] .. "emēs"}
	data.forms["pres_ind_2p"] = {args[1] .. "et"}
	data.forms["pres_ind_3p"] = {args[1] .. "ent"}

	data.forms["past_ind_1s"] = {(args[2] or args[1]) .. "ta"}
	data.forms["past_ind_2s"] = {(args[2] or args[1]) .. "tōs", (args.mutstem or args[1]) .. "tōst"}
	data.forms["past_ind_3s"] = {(args[2] or args[1]) .. "ta"}
	data.forms["past_ind_1p"] = {(args[2] or args[1]) .. "tum", (args[2] or args[1]) .. "tumēs"}
	data.forms["past_ind_2p"] = {(args[2] or args[1]) .. "tut"}
	data.forms["past_ind_3p"] = {(args[2] or args[1]) .. "tun"}

	data.forms["pres_sub_1s"] = {args[1] .. "e"}
	data.forms["pres_sub_2s"] = {args[1] .. "ēs", args[1] .. "ēst"}
	data.forms["pres_sub_3s"] = {args[1] .. "e"}
	data.forms["pres_sub_1p"] = {args[1] .. "ēm", args[1] .. "ēn", args[1] .. "emēs"}
	data.forms["pres_sub_2p"] = {args[1] .. "ēt"}
	data.forms["pres_sub_3p"] = {args[1] .. "ēn"}
	
	data.forms["past_sub_1s"] = {(args[2] or args[1]) .. "ti"}
	data.forms["past_sub_2s"] = {(args[2] or args[1]) .. "tīs", (args[2] or args[1]) .. "tīst"}
	data.forms["past_sub_3s"] = {(args[2] or args[1]) .. "ti"}
	data.forms["past_sub_1p"] = {(args[2] or args[1]) .. "tīm", (args[2] or args[1]) .. "tīn", (args[2] or args[1]) .. "tīmēs"}
	data.forms["past_sub_2p"] = {(args[2] or args[1]) .. "tīt"}
	data.forms["past_sub_3p"] = {(args[2] or args[1]) .. "tīn"}
	
	data.forms["imp_s"] = {((args.impr or args.mutstem) or args[1]) .. "i"}
	data.forms["imp_p"] = {args[1] .. "et"}
	
	data.forms["pres_part"] = {args[1] .. "enti"}
	data.forms["past_part"] = {args.past_ptc or ("gi" .. (args[2] or args[1]) .. "t")}
	
	table.insert(data.categories, "Old High German class 1 weak verbs")
end
})

conj_data["wk2"] = {
	params = {
		[1] = {},
		["mutstem"] = {},
		["impr"] = {},
		["past_ptc"] = {},
		},
}
setmetatable(conj_data["wk2"], {__call = function(self, args, data)
	data.conj_type = "weak class 2"
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	data.forms["inf"] = {args.head or (args[1] .. "ōn")}
	
	data.forms["pres_ind_1s"] = {args[1] .. "ōm", args[1] .. "ōn"}
	data.forms["pres_ind_2s"] = {(args.mutstem or args[1]) .. "ōs", (args.mutstem or args[1]) .. "ōst"}
	data.forms["pres_ind_3s"] = {(args.mutstem or args[1]) .. "ōt"}
	data.forms["pres_ind_1p"] = {args[1] .. "ōm", args[1] .. "ōmēs"}
	data.forms["pres_ind_2p"] = {args[1] .. "ōt"}
	data.forms["pres_ind_3p"] = {args[1] .. "ōnt"}

	data.forms["past_ind_1s"] = {args[1] .. "ōta"}
	data.forms["past_ind_2s"] = {args[1] .. "ōtōs", args[1] .. "ōtōst"}
	data.forms["past_ind_3s"] = {args[1] .. "ōta"}
	data.forms["past_ind_1p"] = {args[1] .. "ōtum", args[1] .. "ōtumēs"}
	data.forms["past_ind_2p"] = {args[1] .. "ōtut"}
	data.forms["past_ind_3p"] = {args[1] .. "ōtun"}

	data.forms["pres_sub_1s"] = {args[1] .. "o"}
	data.forms["pres_sub_2s"] = {args[1] .. "ōs", args[1] .. "ōst"}
	data.forms["pres_sub_3s"] = {args[1] .. "o"}
	data.forms["pres_sub_1p"] = {args[1] .. "ōm", args[1] .. "ōmēs"}
	data.forms["pres_sub_2p"] = {args[1] .. "ōt"}
	data.forms["pres_sub_3p"] = {args[1] .. "ōn"}
	
	data.forms["past_sub_1s"] = {args[1] .. "ōti"}
	data.forms["past_sub_2s"] = {args[1] .. "ōtīs"}
	data.forms["past_sub_3s"] = {args[1] .. "ōti"}
	data.forms["past_sub_1p"] = {args[1] .. "ōtīm", args[1] .. "ōtīmēs"}
	data.forms["past_sub_2p"] = {args[1] .. "ōtīt"}
	data.forms["past_sub_3p"] = {args[1] .. "ōtīn"}
	
	data.forms["imp_s"] = {((args.impr or args.mutstem) or args[1]) .. "o"}
	data.forms["imp_p"] = {args[1] .. "ōt"}
	
	data.forms["pres_part"] = {args[1] .. "ōnti"}
	data.forms["past_part"] = {args.past_ptc or ("gi" .. args[1] .. "ōt")}
	
	table.insert(data.categories, "Old High German class 2 weak verbs")
end
})

conj_data["wk3"] = {
	params = {
		[1] = {},
		["mutstem"] = {},
		["impr"] = {},
		["past_ptc"] = {},
		},
}
setmetatable(conj_data["wk3"], {__call = function(self, args, data)
	data.conj_type = "weak class 3"
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	data.forms["inf"] = {args.head or (args[1] .. "ēn")}
	
	data.forms["pres_ind_1s"] = {args[1] .. "ēm", args[1] .. "ēn"}
	data.forms["pres_ind_2s"] = {(args.mutstem or args[1]) .. "ēs", (args.mutstem or args[1]) .. "ēst"}
	data.forms["pres_ind_3s"] = {(args.mutstem or args[1]) .. "ēt"}
	data.forms["pres_ind_1p"] = {args[1] .. "ēm", args[1] .. "ēmēs"}
	data.forms["pres_ind_2p"] = {args[1] .. "ēt"}
	data.forms["pres_ind_3p"] = {args[1] .. "ēnt"}

	data.forms["past_ind_1s"] = {args[1] .. "ēta"}
	data.forms["past_ind_2s"] = {args[1] .. "ētōs", args[1] .. "ētōst"}
	data.forms["past_ind_3s"] = {args[1] .. "ēta"}
	data.forms["past_ind_1p"] = {args[1] .. "ētum", args[1] .. "ētumēs"}
	data.forms["past_ind_2p"] = {args[1] .. "ētut"}
	data.forms["past_ind_3p"] = {args[1] .. "ētun"}

	data.forms["pres_sub_1s"] = {args[1] .. "e"}
	data.forms["pres_sub_2s"] = {args[1] .. "ēs", args[1] .. "ēst"}
	data.forms["pres_sub_3s"] = {args[1] .. "e"}
	data.forms["pres_sub_1p"] = {args[1] .. "ēm", args[1] .. "ēmēs"}
	data.forms["pres_sub_2p"] = {args[1] .. "ēt"}
	data.forms["pres_sub_3p"] = {args[1] .. "ēn"}
	
	data.forms["past_sub_1s"] = {args[1] .. "ēti"}
	data.forms["past_sub_2s"] = {args[1] .. "ētīs", args[1] .. "ētīst"}
	data.forms["past_sub_3s"] = {args[1] .. "ēti"}
	data.forms["past_sub_1p"] = {args[1] .. "ētīm", args[1] .. "ētīmēs"}
	data.forms["past_sub_2p"] = {args[1] .. "ētīt"}
	data.forms["past_sub_3p"] = {args[1] .. "ētīn"}
	
	data.forms["imp_s"] = {((args.impr or args.mutstem) or args[1]) .. "e"}
	data.forms["imp_p"] = {args[1] .. "ēt"}
	
	data.forms["pres_part"] = {args[1] .. "ēnti"}
	data.forms["past_part"] = {args.past_ptc or ("gi" .. args[1] .. "ēt")}
	
	table.insert(data.categories, "Old High German class 3 weak verbs")
end
})

conj_data.irregular = {}

conj_data.irregular["wesan"] = function(data)
	data.conj_type = "irregular, [[suppletive]]"
	
	data.forms["inf"] = {"wesan"}
	
	data.forms["pres_ind_1s"] = {"bim", "bin"}
	data.forms["pres_ind_2s"] = {"bist", "bis"}
	data.forms["pres_ind_3s"] = {"ist"}
	data.forms["pres_ind_1p"] = {"birum", "birun"}
	data.forms["pres_ind_2p"] = {"birut"}
	data.forms["pres_ind_3p"] = {"sint"}

	data.forms["past_ind_1s"] = {"was"}
	data.forms["past_ind_2s"] = {"wāri"}
	data.forms["past_ind_3s"] = {"was"}
	data.forms["past_ind_1p"] = {"wārum", "wārumēs"}
	data.forms["past_ind_2p"] = {"wārut"}
	data.forms["past_ind_3p"] = {"wārun"}
	
	data.forms["pres_sub_1s"] = {"sī"}
	data.forms["pres_sub_2s"] = {"sīs", "sīst"}
	data.forms["pres_sub_3s"] = {"sī"}
	data.forms["pres_sub_1p"] = {"sīn"}
	data.forms["pres_sub_2p"] = {"sīt"}
	data.forms["pres_sub_3p"] = {"sīn"}

	data.forms["past_sub_1s"] = {"wāri"}
	data.forms["past_sub_2s"] = {"wārīs", "wārīst"}
	data.forms["past_sub_3s"] = {"wāri"}
	data.forms["past_sub_1p"] = {"wārīm", "wārīmēs"}
	data.forms["past_sub_2p"] = {"wārīt"}
	data.forms["past_sub_3p"] = {"wārīn"}
	
	data.forms["imp_s"] = {"wis"}
	data.forms["imp_p"] = {"wesit"}
	
	data.forms["pres_part"] = {"wesanti"}
	data.forms["past_part"] = {"giwesan"}
	
	table.insert(data.categories, "Old High German suppletive verbs")
end

local function add_asterisks(forms, data)
	for _, form in ipairs(forms) do
		for i, subform in ipairs(data.forms[form]) do
			data.forms[form][i] = "*" .. subform
		end
	end
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)

	local parent_args = frame:getParent().args
	local conj_type = (frame.args["conj"] or parent_args["conj"]) or "st"

	if not conj_data[conj_type] then
		error("Unknown conjugation '" .. conj_type .. "'")
	end
	
	local data = {forms = {}, categories = {}}
	
	data.head = parent_args["head"] or nil

	local args = require("Module:parameters").process(parent_args, conj_data[conj_type].params, true)
	
	-- Override for templates
	if not args[1] then
		setmetatable(args, {__index = function(self, key)
			return "{{{" .. key .. "}}}"
		end
		})
	end
	
	-- Generate the forms
	if parent_args.irr then
		table.insert(data.categories, "Old High German irregular verbs")
		if conj_data.irregular[parent_args.irr] then
			conj_data.irregular[parent_args.irr](data)
		else
			conj_data[conj_type](args, data)
		end
	else
		conj_data[conj_type](args, data)
	end

	-- Make the table
	return make_table(data)
end

function make_table(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
				subform = "*" .. subform
			end
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
			
		return table.concat(ret, ", ")
	end
	
	local function repl(param)
		if param == "conj_type" then
			return data.conj_type
		else
			return show_form(data.forms[param])
		end
	end
	
	local wikicode = [=[
<div class="NavFrame" style="width: 42em">
<div class="NavHead" style="background-color:#93C572;">Conjugation of ''{{{inf}}}'' ({{{conj_type}}})</div>
<div class="NavContent">
{| style="width: 100%; border:1px solid #93C572; line-height: 125%; background-color:#F9F9F9; text-align:center; border: 1px solid #CCCCFF;" cellspacing="1" cellpadding="3" cellspacing="1" class="inflection-table"
|- style="background-color:#F2F2FF;"
|-
! style="background-color:#90EE90;" | infinitive
| colspan="2" style="background-color:#EFEFEF;" | {{{inf}}}
|-
! style="background-color:#93C572;" | [[indicative mood|indicative]]
! style="background-color:#DEDEEE;" | [[present tense|present]]
! style="background-color:#DEDEEE;" | [[past tense|past]]
|-
! style="background-color:#90EE90;" | 1st&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_1s}}}
| style="background-color:#efefff;" | {{{past_ind_1s}}}
|-
! style="background-color:#90EE90;" | 2nd&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_2s}}}
| style="background-color:#efefff;" | {{{past_ind_2s}}}
|-
! style="background-color:#90EE90;" | 3rd&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_3s}}}
| style="background-color:#efefff;" | {{{past_ind_3s}}}
|-
! style="background-color:#90EE90;" | 1st&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_1p}}}
| style="background-color:#efefff;" | {{{past_ind_1p}}}
|-
! style="background-color:#90EE90;" | 2nd&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_2p}}}
| style="background-color:#efefff;" | {{{past_ind_2p}}}
|-
! style="background-color:#90EE90;" | 3rd&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_3p}}}
| style="background-color:#efefff;" | {{{past_ind_3p}}}
|-
! style="background-color:#93C572;" | [[subjunctive mood|subjunctive]]
! style="background-color:#eeeede;" | present
! style="background-color:#eeeede;" | past
|-
! style="background-color:#90EE90;" | 1st&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_1s}}}
| style="background-color:#ffffef;" | {{{past_sub_1s}}}
|-
! style="background-color:#90EE90;" | 2nd&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_2s}}}
| style="background-color:#ffffef;" | {{{past_sub_2s}}}
|-
! style="background-color:#90EE90;" | 3rd&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_3s}}}
| style="background-color:#ffffef;" | {{{past_sub_3s}}}
|-
! style="background-color:#90EE90;" | 1st&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_1p}}}
| style="background-color:#ffffef;" | {{{past_sub_1p}}}
|-
! style="background-color:#90EE90;" | 2nd&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_2p}}}
| style="background-color:#ffffef;" | {{{past_sub_2p}}}
|-
! style="background-color:#90EE90;" | 3rd&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_3p}}}
| style="background-color:#ffffef;" | {{{past_sub_3p}}}
|-
! style="background-color:#93C572;" | [[imperative mood|imperative]]
! style="background-color:#eedede;" | present
! rowspan="3" style="background-color:#e0e0e0;" |
|-
! style="background-color:#90EE90;" | singular
| style="background-color:#ffefef;" | {{{imp_s}}}
|-
! style="background-color:#90EE90;" | plural
| style="background-color:#ffefef;" | {{{imp_p}}}
|-
! style="background-color:#93C572; font-weight:bold;" | [[participle]]
! style="background-color:#deeede; font-weight:bold;" | [[present tense|present]]
! style="background-color:#deeede; font-weight:bold;" | [[past tense|past]]
|-
! style="background-color:#90EE90; font-weight:bold;" |
| style="background-color:#efffef;" | {{{pres_part}}} 
| style="background-color:#efffef;" | {{{past_part}}}
|}</div></div>]=]

	return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end

return export