local p={}

function wikitabella(decl, sing, pl)
	if pl and (string.lower(pl) == "no"
		or string.lower(pl) == "n")
	then
							--SOLO SINGOLARE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f9f9f9;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."| &nbsp;".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"|''sing'']].."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''nominativo'']].."\n"
		tab = tab.."|[["..link(decl[1]).."|"..decl[1].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''genitivo'']].."\n"
		tab = tab.."|[["..link(decl[3]).."|"..decl[3].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''dativo'']].."\n"
		tab = tab.."|[["..link(decl[5]).."|"..decl[5].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''accusativo'']].."\n"
		tab = tab.."|[["..link(decl[7]).."|"..decl[7].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''vocativo'']].."\n"
		tab = tab.."|[["..link(decl[9]).."|"..decl[9].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''ablativo'']].."\n"
		tab = tab.."|[["..link(decl[11]).."|"..decl[11].."]]".."\n"
		tab = tab.."|}".."\n"
	elseif sing and (string.lower(sing) == "no"
		or string.lower(sing) == "n")
	then
							--SOLO PLURALE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f9f9f9;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."| &nbsp;".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"|''pl'']].."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''nominativo'']].."\n"
		tab = tab.."|[["..link(decl[2]).."|"..decl[2].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''genitivo'']].."\n"
		tab = tab.."|[["..link(decl[4]).."|"..decl[4].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''dativo'']].."\n"
		tab = tab.."|[["..link(decl[6]).."|"..decl[6].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''accusativo'']].."\n"
		tab = tab.."|[["..link(decl[8]).."|"..decl[8].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''vocativo'']].."\n"
		tab = tab.."|[["..link(decl[10]).."|"..decl[10].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''ablativo'']].."\n"
		tab = tab.."|[["..link(decl[12]).."|"..decl[12].."]]".."\n"
		tab = tab.."|}".."\n"
	else
							--SINGOLARE E PLURALE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f9f9f9;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."| &nbsp;".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"|''sing'']].."\n"
		tab = tab..[[!bgcolor="#FFFFE0"|''pl'']].."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''nominativo'']].."\n"
		tab = tab.."|[["..link(decl[1]).."|"..decl[1].."]]".."\n"
		tab = tab.."|[["..link(decl[2]).."|"..decl[2].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''genitivo'']].."\n"
		tab = tab.."|[["..link(decl[3]).."|"..decl[3].."]]".."\n"
		tab = tab.."|[["..link(decl[4]).."|"..decl[4].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''dativo'']].."\n"
		tab = tab.."|[["..link(decl[5]).."|"..decl[5].."]]".."\n"
		tab = tab.."|[["..link(decl[6]).."|"..decl[6].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''accusativo'']].."\n"
		tab = tab.."|[["..link(decl[7]).."|"..decl[7].."]]".."\n"
		tab = tab.."|[["..link(decl[8]).."|"..decl[8].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''vocativo'']].."\n"
		tab = tab.."|[["..link(decl[9]).."|"..decl[9].."]]".."\n"
		tab = tab.."|[["..link(decl[10]).."|"..decl[10].."]]".."\n"
		tab = tab.."|-".."\n"
		tab = tab..[[!bgcolor="#FFFFE0"| ''ablativo'']].."\n"
		tab = tab.."|[["..link(decl[11]).."|"..decl[11].."]]".."\n"
		tab = tab.."|[["..link(decl[12]).."|"..decl[12].."]]".."\n"
		tab = tab.."|}".."\n"
	end
	return tab
end

function irregolare(ns, np, gs, gp, ds, dp, acs, acp, vs, vp, as, ap)	--funzione che gestisce le forme flesse irregolari
	casoirreg = {ns, np, gs, gp, ds, dp, acs, acp, vs, vp, as, ap}		--inserite dall’utente
	for i = 1, 12
	do
		if casoirreg[i]
		and casoirreg[i] ~= "" then
			decl[i] = casoirreg[i]
		end
	end
end

function link(parola)	--rimuove i segni diacritici dalle vocali della parola
	local lun = {"Ā", "ā", "Ē", "ē", "Ī", "ī", "Ō", "ō", "Ū", "ū"}
	local bre = {"Ă", "ă", "Ĕ", "ĕ", "Ĭ", "ĭ", "Ŏ", "ŏ", "Ŭ", "ŭ"}
	local voc = {"A", "a", "E", "e", "I", "i", "O", "o", "U", "u"}
	for i= 1, 10
	do
		parola = mw.ustring.gsub(parola, lun[i], voc[i])
		parola = mw.ustring.gsub(parola, bre[i], voc[i])
	end
	return parola
end

function test_voc(lettera)		--restituisce ‘true’ se la lettera che riceve è una vocale
	local voc = {
					"Ā", "ā", "Ē", "ē", "Ī", "ī", "Ō", "ō", "Ū", "ū",
					"Ă", "ă", "Ĕ", "ĕ", "Ĭ", "ĭ", "Ŏ", "ŏ", "Ŭ", "ŭ",
					"A", "a", "E", "e", "I", "i", "O", "o", "U", "u"
																		}
	test = false
	local i=0
	repeat
		i = i+1
		if lettera == voc[i] then test = true  end
	until voc[i] == nil
	return test
end

function test_cons(lettera)	--restituisce ‘true’ se la lettera che riceve non è una vocale
	return not test_voc(lettera)
end

-- La seguente funzione suddivide in sillabe la parola che riceve
-- principali limitazioni:
--  • non vengono sillabati i nomi composti

function sillabe(parola)
	if sillaba == nil	--inizializza la tabella ‘sillaba’, che conterrà le sillabe della parola
	then n = 1 i = 1
		sillaba={}
	end
	local lettera = mw.ustring.sub(parola, i, i)	--lettera da analizzare
	if sillaba[n]==nil then sillaba[n]="" end	--inizializza la nuova sillaba
	sillaba[n]=sillaba[n]..lettera
	if test_voc(lettera)	--se la lettera analizzata è una vocale, allora passa alla nuova sillaba
	then
		n=n+1
	end
	min = mw.ustring.lower	--rende il testo minuscolo, quando, in una condizione, non importano le maiuscole
	if mw.ustring.len(parola)>1 then
		if mw.ustring.sub(min(link(parola)), 1, 2) == "ae" or mw.ustring.sub(min(link(parola)), 1, 2) == "oe" then n=n-1 end	--mantiene uniti i dittonghi
		if min(link(lettera)) == "u" and (mw.ustring.sub(min(sillaba[n-1]), mw.ustring.len(sillaba[n-1])-1, mw.ustring.len(sillaba[n-1])-1) == "q"	--non divide la sillaba quando ‘q’ precede ‘u’
			or mw.ustring.sub(min(sillaba[n-1]), mw.ustring.len(sillaba[n-1])-1, mw.ustring.len(sillaba[n-1])-1) == "g")	--lo stesso fa anche quando ‘g’ precede ‘u’
		and test_voc(mw.ustring.sub(parola, 2, 2))
		then n=n-1 end
		if test_cons(lettera) and sillaba[n-1] ~= nil and test_cons(mw.ustring.sub(parola, 2, 2)) and test_voc(mw.ustring.sub(sillaba[n-1], mw.ustring.len(sillaba[n-1])))
		then						--quando si susseguono più consonanti, riporta la prima consonante alla sillaba precedente…
			m = {"b", "d", "c", "f", "g", "p", "t", "v"}
			for k = 1, #m
			do
				if mw.ustring.find(mw.ustring.lower(lettera), m[k]) ~= nil
				then contiene_m = true end
			end
			if not contiene_m or	-- …a meno di casi particolari
			mw.ustring.sub(min(parola), 2, 2) ~= "l" and mw.ustring.sub(min(parola), 2, 2) ~= "r"
			then
				sillaba[n-1] = sillaba[n-1]..lettera
				sillaba[n]=nil
			end
		end
		sillabe(mw.ustring.sub(parola, i+1))
	end
	ultimalettera = mw.ustring.sub(sillaba[#sillaba], mw.ustring.len(sillaba[#sillaba]))
	if test_cons(ultimalettera) and mw.ustring.len(parola) == 1 and sillaba[n-1] ~= nil	--evita che la sillaba finale sia priva di vocali
	then
		tuttec = true	--variabile che indica se l’ultima sillaba ha solo consonanti
		for j=1, mw.ustring.len(sillaba[n])
		do if not test_cons(mw.ustring.sub(mw.ustring.len(sillaba[n]), j, j)) then tuttec = false end
	end
	if tuttec then	--se l’ultima variabile del vettore ‘sillaba’ ha solo consonanti
		sillaba[n-1] = sillaba[n-1]..sillaba[n]	--allora viene concatenata alla variabile che la precede
		sillaba[n]=nil
	end
	end
	return sillaba
end

function radicepiusuffisso()
	for i = 1, 12
	do
		decl[i] = radice..suff[i]
	end
end

function test_plur(sing)
	solopl = false
	if sing and (string.lower(sing) == "no"
		or string.lower(sing) == "n")
	then solopl = true
		return solopl
	end
end

function p.prima( frame )
	nom = frame.args[1]
	decl = {}	-- tabella atta a contenere la declinazione del nome
	suff = {"ă", "ae", "ae", "ārŭm", "ae", "īs", "ăm", "ās", "ă", "ae", "ā", "īs"}
	radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
			--Solo per i pluralia tantum
			solopl= test_plur(frame.args.sing)
			if solopl and link(mw.ustring.sub(nom, -2)) == "ae"
			then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
			end
			--Fine
	radicepiusuffisso()
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	return wikitabella(decl, f.sing, f.pl)
end

function p.seconda( frame )
	nom = frame.args[1]
	gen = frame.args[2]
	decl = {}
	if link(mw.ustring.sub(nom, -2)) == "us"
	then
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
		suff = {"ŭs", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "ĕ", "ī", "ō", "īs"}
		radicepiusuffisso()
	elseif link(mw.ustring.sub(nom, -2)) == "um"
		then
			radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
			suff = {"ŭm", "ă", "ī", "ōrŭm", "ō", "īs", "ŭm", "ă", "ŭm", "ă", "ō", "īs"}
			radicepiusuffisso()
	elseif link(mw.ustring.sub(nom, -2)) == "er" and gen
		then
			radice = mw.ustring.sub(gen, 1, mw.ustring.len(gen)-1)
			suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
			radicepiusuffisso()
			decl[1] = nom
			decl[9] = nom
	elseif link(mw.ustring.sub(nom, -2)) == "er"
		then
			eccz = {"b", "c", "d", "f", "g", "p", "t", "v"} ri = false
			for i=1, #eccz
			do
				if mw.ustring.sub(nom, mw.ustring.len(nom)-2, mw.ustring.len(nom)-2) == eccz[i]
				then
					ri = true
				end
			end
			if ri == false
			then
				radice = nom
				suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
				radicepiusuffisso()
			else
				radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2).."r"
				suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
				radicepiusuffisso()
				decl[1] = nom
				decl[9] = nom
			end
	end
						--Solo per i pluralia tantum
						solopl= test_plur(frame.args.sing)
						if solopl and link(mw.ustring.sub(nom, -1)) == "i"
						then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
							suff = {"", "ī", "", "ōrŭm", "", "īs", "", "ōs", "", "ī", "", "īs"}
							radicepiusuffisso()
						elseif solopl and link(mw.ustring.sub(nom, -1)) == "a"
						then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
							suff = {"", "ă", "", "ōrŭm", "", "īs", "", "ă", "", "ă", "", "īs"}
							radicepiusuffisso()
						end
						--Fine
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	return wikitabella(decl, f.sing, f.pl)
end

function p.terza( frame )
	nom = frame.args[1]
	gen = frame.args[2]
	neut = frame.args.n
	decl = {}
	parisillabo = false
	local numsillabe_nom= #sillabe(nom)						--la funzione ‘sillabe’ usa una variabile globale
	local numsillabe_gen= #sillabe(gen) - numsillabe_nom	--è quindi necessario fare la differenza tra la dimensione finale e quella iniziale
	if numsillabe_nom == numsillabe_gen
	then
		parisillabo = true
	end
	if neut ~= nil
	then
		if mw.ustring.lower(neut) == "sì"
		or mw.ustring.lower(neut) == "si"
		or mw.ustring.lower(neut) == "s"
		or mw.ustring.lower(neut) == "yes"
		then
			neut = true
		end
	end
	radice = mw.ustring.sub(gen, 1, mw.ustring.len(gen)-2)
	if not parisillabo and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)))		-- I gruppo
	and not test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)-1, mw.ustring.len(radice)-1))
	then
		if neut == true
		then
			suff = {"", "ă", "ĭs", "ŭm", "ī", "ĭbŭs", "", "ă", "", "ă", "ĕ", "ĭbŭs"}
		else
			suff = {"", "ēs", "ĭs", "ŭm", "ī", "ĭbŭs", "ĕm", "ēs", "", "ēs", "ĕ", "ĭbŭs"}
		end
	end
	if parisillabo or																		-- II gruppo
	(not parisillabo and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)))
		and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)-1, mw.ustring.len(radice)-1)))
	then
		if neut == true
		then
			suff = {"", "ă", "ĭs", "ĭŭm", "ī", "ĭbŭs", "", "ă", "", "ă", "ĕ", "ĭbŭs"}
		else
			suff = {"", "ēs", "ĭs", "ĭŭm", "ī", "ĭbŭs", "ĕm", "ēs", "", "ēs", "ĕ", "ĭbŭs"}
		end
	end
	if neut == true and (link(mw.ustring.sub(nom, mw.ustring.len(nom)))== "e"				-- III gruppo
		or (link(mw.ustring.sub(nom, mw.ustring.len(nom)-1)) == "al" and link(mw.ustring.sub(gen, mw.ustring.len(gen)-3)) == "alis")
		or (link(mw.ustring.sub(nom, mw.ustring.len(nom)-1)) == "ar" and link(mw.ustring.sub(gen, mw.ustring.len(gen)-3)) == "aris"))
	then
		suff = {"", "ĭă", "ĭs", "ĭŭm", "ī", "ĭbŭs", "", "ĭă", "", "ĭă", "ī", "ĭbŭs"}
	end
	if suff ~= nil then
		radicepiusuffisso()
	end
	decl[1] = nom
	decl[9] = nom
	if neut == true
	then
		decl[7] = nom
	end
				--Solo per i pluralia tantum
				solopl= test_plur(frame.args.sing)
				if solopl
				then
					if neut == true and link(mw.ustring.sub(nom, -2)) == "ia" then
					radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
					suff = {"", "ĭă", "", "ĭŭm", "", "ĭbŭs", "", "ĭă", "", "ĭă", "", "ĭbŭs"}
					radicepiusuffisso()
				elseif neut == true and link(mw.ustring.sub(nom, -1)) == "a" then
					radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
					suff = {"", "ă", "", "ŭm", "", "ĭbŭs", "", "ă", "", "ă", "", "ĭbŭs"}
					if link(mw.ustring.sub(gen, -3)) == "ium" then
						suff[4] = "ĭŭm" end
						radicepiusuffisso()
					elseif link(mw.ustring.sub(gen, -2)) == "um" then
						radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
						suff = {"", "ēs", "", "ŭm", "", "ĭbŭs", "", "ēs", "", "ēs", "", "ĭbŭs"}
						if link(mw.ustring.sub(gen, -3)) == "ium" then
							suff[4] = "ĭŭm" end
						radicepiusuffisso()
					end
				end
				--Fine
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	return wikitabella(decl, f.sing, f.pl)
end

function p.quarta( frame )
	nom = frame.args[1]
	decl = {}
	if link(mw.ustring.sub(nom, -1)) == "u"
	then
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
		suff = {"ū", "ŭă", "ūs", "ŭŭm", "ū", "ĭbŭs", "ū", "ŭă", "ū", "ŭă", "ū", "ĭbŭs"}
	else
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
		suff = {"ŭs", "ūs", "ūs", "ŭŭm", "ŭī", "ĭbŭs", "ŭm", "ūs", "ŭs", "ūs", "ū", "ĭbŭs"}
	end
				--Solo per i pluralia tantum
				solopl= test_plur(frame.args.sing)
				if solopl and link(mw.ustring.sub(nom, -2)) == "ua"
				then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
				suff = {"", "ŭă", "", "ŭŭm", "", "ĭbŭs", "", "ŭă", "", "ŭă", "", "ĭbŭs"}
				end
				--Fine
	radicepiusuffisso()
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	return wikitabella(decl, f.sing, f.pl)
end

function p.quinta( frame )
	nom = frame.args[1]
	decl = {}
	radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
	if test_voc(mw.ustring.sub(radice, -1))
	then
		suff = {"ēs", "ēs", "ēī", "ērŭm", "ēī", "ēbŭs", "ĕm", "ēs", "ēs", "ēs", "ē", "ēbŭs"}
	else
		suff = {"ēs", "ēs", "ĕī", "ērŭm", "ĕī", "ēbŭs", "ĕm", "ēs", "ēs", "ēs", "ē", "ēbŭs"}
	end
	radicepiusuffisso()
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	return wikitabella(decl, f.sing, f.pl)
end

return p