local getArgs= require("Modulo:Arguments").getArgs
local iconaArgomento= require("Modulo:Sandbox/ppong/Icona").iconaArgomento

require("Modulo:No globals")

-- TABELLA DI CONFIGURAZIONE
--------------------------------------------------------------------------------

local config= {
	progetti={ -- Inserire solo le occorrenze più insolite: il modulo già rende maiuscolo il nome del progetto
		["Acquariofilia"]= "Forme di vita/Pesci/Acquariofilia",
		["anime"]= "Anime e manga",
		["animanga"]= "Anime e manga",
		["Anno"]= "Cronologia/Anno",
		["areeprotette"]= "Aree protette",
		["Armi da fuoco"]= "Guerra/Armi da fuoco",
		["Atletica leggera"]= "Sport/Atletica leggera",
		["Atletica"]= "Sport/Atletica leggera",

		["biologia"]= "Bio",
		["biochimica"]= "Bio",
		["Burma"]= "Birmania",

		["Calcio"]= "Sport/Calcio",
		["cartoni animati"]= "Cartoons",
		["Comuni"]= "Geografia/Antropica/Comuni",

		["Decade"]= "Cronologia/Decade",
		["Dialetti"]= "Dialetti d'Italia",
		["Wikilex"]= "Diritto",
		["minori"]= "Diritti dei minori",
		["disturbipsichici"]= "Disturbi psichici",
		["Documenta ecclesiae"]= "Documenta Ecclesiae",

		["aziende"]= "Economia",
		["Elicotteri"]= "Aviazione/Elicotteri",
		["Emilia"]= "Emilia e Romagna",
		["Romagna"]= "Emilia e Romagna",
		["emilia romagna"]= "Emilia e Romagna",
		["Emilia Romagna"]= "Emilia e Romagna",
		["Emilia-Romagna"]= "Emilia e Romagna",
		["ER"]= "Emilia e Romagna",
		["emilia-romagna"]= "Emilia e Romagna",

		["Fiction tv"]= "Fiction TV",
		["Film Horror"]= "Film horror",
		["horror"]= "Film horror",
		["formedivita"]= "Forme di vita",
		["Formula uno"]= "F1",
		["Formula 1"]= "F1",

		["Guerra elettronica"]= "Guerra/Guerra elettronica",
		["guerrestellari"]= "Guerre stellari",
		["GuerreStellari"]= "Guerre stellari",

		["Controlli automatici"]= "Ingegneria/Controlli automatici",

		["Musica classica"]= "Musica/Classica",
		["classica"]= "Musica/Classica",
		["metal"]= "Musica/Heavy metal",
		["Heavy Metal"]= "Musica/Heavy metal",
		["Heavy metal"]= "Musica/Heavy metal",
		["Hip Hop"]= "Musica/Hip hop",
		["hip hop"]= "Musica/Hip hop",
		["hiphop"]= "Musica/Hip hop",
		["Jazz"]= "Musica/Jazz",
		["Punk"]= "Musica/Punk",
		["Rock"]= "Musica/Rock",

		["Nobel"]= "Premi Nobel",
		["Premi nobel"]= "Premi Nobel",

		["Pallacanestro"]= "Sport/Pallacanestro",
		["Basket"]= "Sport/Pallacanestro",
		["Pk"]= "Fumetti/PK",
		["PK"]= "Fumetti/PK",
		["pokèmon"]= "Pokémon",
		["Pokemon"]= "Pokémon",
		["portorico"]= "Porto Rico",

		["Reggio calabria"]= "Reggio Calabria",
		["Rugby"]= "Sport/Rugby",

		["San marino"]= "San Marino",
		["Scienze della terra"]= "Scienze della Terra",
		["stati africa"]= "Stati",
		["stati america"]= "Stati",
		["stati asia"]= "Stati",
		["stati europa"]= "Stati",
		["stati oceania"]= "Stati",

		["tao"]= "Taoismo",
		["tv"]= "Televisione",
		["TV"]= "Televisione",

		["Venezia"]= "Venezia e Laguna",
		["venezia e laguna"]= "Venezia e Laguna",
		["Vibo valentia"]= "Vibo Valentia",
		["vibo"]= "Vibo Valentia",
		["videogames"]= "Videogiochi",

		["Disney"]= "Walt Disney",

		["q"]= "Qualità",
		["Qualita"]= "Qualità"},
	var= { -- questa tabella serve per gestire i voti
		A=		 "A",
		["A+"]=	 "A",
		VETRINA= "A",
		B= "B",
		C= "C",
		D= "D",
		E= "E",
		X= "E",
		STUB= "E",
		NC= "NC"},
	colore_voti= {
		A= "#6699ff",
		B= "#53e04c",
		C= "#fff31e",
		D= "#ff831E",
		E= "#ff1e29",
		NC= "white"},
	livelli= {
		A= "livello completo",
		B= "livello buono",
		C= "livello sufficiente",
		D= "livello minimo",
		E= "livello bozza",
		NC= "nessun livello",
		["livello completo"]= "A",
		["livello buono"]= "B",
		["livello sufficiente"]= "C",
		["livello minimo"]= "D",
		["livello bozza"]= "E",
		["nessun livello"]= "NC",
		["non compilate"]= "NC"},
	descrizione_stato= {
		livello= {
			["livello completo"]= "La voce ha ottenuto il massimo livello di valutazione in base a quanto raccomandato nel '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello buono"]= "La voce ha raggiunto un buon livello di valutazione in base a quanto raccomandato nel  '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello sufficiente"]= "La voce è stata considerata di livello sufficiente in base a quanto raccomandato nel  '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello minimo"]= "La voce è stata considerata di livello minimo in base a quanto raccomandato nel  '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello bozza"]= "", -- da chiarire meglio come funziona
			["nessun livello"]= "",
			["non compilate"]= "La voce non è stata ancora monitorata, <span class=\"plainlinks\">[http://it.wikipedia.org/w/title="..mw.title.getCurrentTitle().fullText.."&action=edit&section=0 fallo ora]!</span>"},
		accuratezza= {
			A= "Voce adeguatamente '''accurata'''. Tutti gli aspetti principali del tema sono affrontati con la dovuta profondità. Il tema è stabile e non dovrebbe necessitare di aggiornamenti futuri.",
			B= "Lievi problemi relativi all''''accuratezza''' dei contenuti. Informazioni esaustive nella gran parte dei casi, ma alcuni aspetti non sono del tutto approfonditi o altri non sono direttamente attinenti. Il tema non è stabile e potrebbe in breve necessitare di aggiornamenti.",
			C= "Seri problemi relativi all''''accuratezza''' dei contenuti. Importanti aspetti del tema non sono trattati o solo superficialmente. Altri aspetti non sono direttamente attinenti. Alcune informazioni importanti risultano controverse. Potrebbero essere presenti uno o più avvisi.",
			D= "Gravi problemi relativi all''''accuratezza''' o alla neutralità dei contenuti. Molti aspetti del tema non sono trattati o solo superficialmente. È assai probabile che siano presenti uno o più avvisi o che vadano inseriti.",
			E= "Gravissimi problemi relativi all''''accuratezza''' dei contenuti, segnalati da avvisi. Informazioni limitate o da controllare.",
			NC= "Nessuna informazione sull'<b>accuratezza</b> dei contenuti."},
		scrittura= {
			A= "Voce '''scritta''' in buon italiano e con buono [[aiuto:manuale di stile|stile]]. Sintassi e lessico adeguati, linguaggio chiaro e scorrevole, con uso attento di termini specifici. Strutturazione in paragrafi soddisfacente.",
			B= "Lievi problemi di '''scrittura'''. Qualche inciampo nello [[aiuto:manuale di stile|stile]]. Linguaggio non sempre scorrevole. Strutturazione in paragrafi adeguata, ma ancora migliorabile sotto alcuni aspetti.",
			C= "Seri problemi di '''scrittura'''. Linguaggio comprensibile, ma con [[aiuto:manuale di stile|stile]] poco scorrevole. Strutturazione in paragrafi carente.",
			D= "Gravi problemi di '''scrittura'''. Stile scadente. Strutturazione in paragrafi assente o molto carente.",
			E= "Gravissimi problemi di '''scrittura'''. Lo [[aiuto:manuale di stile|stile]] va completamente rivisto ed è auspicabile una integrale riscrittura.",
			NC= "Nessuna informazione sulla '''scrittura'''."},
		fonti= {
			A= "I contenuti della voce sono interamente verificabili tramite '''fonti''' autorevoli e [[Wikipedia:Fonti attendibili|attendibili]]. Il tema è stabile e non dovrebbe necessitare di aggiornamenti futuri.",
			B= "Lievi problemi relativi alla verificabilità della voce. Un aspetto del tema non è adeguatamente supportato da '''fonti''' [[Wikipedia:Fonti attendibili|attendibili]]. Alcune fonti andrebbero sostituite con altre più autorevoli. Il tema non è stabile e potrebbe in breve necessitare di aggiornamenti.",
			C= "Seri problemi relativi alla verificabilità della voce. Carenza di '''fonti''' [[Wikipedia:Fonti attendibili|attendibili]]. Alcuni aspetti del tema sono completamente privi di fonti a supporto. Presenza o necessità del template {{[[template:cn|cn]]}}. La delicatezza del tema richiede una speciale attenzione alle fonti.",
			D= "Gravi problemi relativi alla verificabilità della voce. Molti aspetti del tema sono completamente privi di '''fonti''' [[Wikipedia:Fonti attendibili|attendibili]] a supporto. Presenza o necessità del template {{[[template:F|F]]}}.",
			E= "Gravissimi problemi relativi alla verificabilità della voce. '''Fonti''' assenti o [[Wikipedia:Fonti attendibili|del tutto inadeguate]]. Presenza o necessità del template {{[[template:F|F]]}}.",
			NC= "Nessuna informazione sulla [[Wikipedia:Fonti attendibili|attendibilità]] delle '''fonti'''."},
		immagini= {
			A= "La voce è corredata da un adeguato numero di '''[[aiuto:immagini|immagini]]''' e altri supporti grafici, in tema con il contenuto della voce, oppure non ne necessita alcuno.",
			B= "Lievi problemi relativi alla dotazione di '''[[aiuto:immagini|immagini]]''' e altri supporti grafici nella voce. Mancano alcuni file o altri sono inadeguati.",
			C= "Seri problemi relativi alla dotazione di '''[[aiuto:immagini|immagini]]''' e altri supporti grafici nella voce. Mancano alcuni file importanti per la comprensione del tema.",
			D= "Gravi problemi relativi alla dotazione di '''[[aiuto:immagini|immagini]]''' e altri supporti grafici nella voce. Mancano molti file importanti per la comprensione del tema, alcuni essenziali.",
			E= "Gravissimi problemi relativi alla dotazione di '''[[aiuto:immagini|immagini]]''' e altri supporti grafici nella voce. La voce necessiterebbe di file importanti per la comprensione del tema, ma ne è assolutamente priva.",
			NC= "Nessuna informazione sulla presenza di '''[[aiuto:immagini|immagini]]''' o altri supporti grafici."} },
	}

-- FUNZIONE DI UTILITA'
--------------------------------------------------------------------------------

local function riordinaTabella(t) -- ovvero come complicarsi la vita inutilmente
	local n= 0
	for _, _ in pairs(t) do
		n= n + 1 end
	local i= 0
	for ii= 1, n do
		while true do
			i= i +1
			if t[i] then
				break end end
		t[ii]= t[i] end end

-- CLASSE MONITORAGGIO
--------------------------------------------------------------------------------

local monitoraggio= {}

function monitoraggio:newError(err, cat) -- funzione di utilità per gli errori
	if not self.errori then
		self.errori= {} end
	self.errori[#self.errori + 1]= err
--	if cat then
--		if not self.categorie_errore then -- per gestire varie categorie di errore
--			self.categorie_errore= {} end
--		self.categorie_errore[cat]= cat end
	end
		
function monitoraggio:organizzaArgomenti(args)
	for k, v in pairs(args) do -- minuscolizza tutti i parametri
		if type(k) == "string" then
			local kk= mw.ustring.lower(k)
			if kk ~= k and args[kk] then
				self:newError("parametro <tt>"..kk.."</tt> inserito più volte con un diverso uno della maiuscola")
				args[k]= nil
			elseif kk ~= k then
				args[kk]= v
				args[k]= nil end end end
	self.voti= {}
	for _, s in ipairs({"accuratezza", "scrittura", "fonti", "immagini"}) do
		local voto= args[s] or "NC"
		voto= string.upper(voto)
		if config.var[voto] then
			self.voti[s]= config.var[voto]
		else
			self:newError("valore \""..voto.."\" non riconosciuto per il campo <tt>"..s.."</tt>")
			self.voti[s]= "NC" end
		args[s]= nil end
	for _, s in ipairs{"note", "utente", "data"} do
		self[s]= args[s]
		args[s]= nil end
	if args.progetto and args.progetto1 then
		self:newError("<tt>progetto</tt> e <tt>progetto1</tt> entrambi specificati, sono due donominazioni alternative per il primo progetto, i seguenti vanno numerati a partire da 2")
		args.progetto= nil
	elseif args.progetto then
		args.progetto1= args.progetto
		args.progetto= nil end
	self.progetti= {}
	for k, v in pairs(args) do
		if string.find(k, "^progetto%d+$") then
			local i= tonumber(k:match("^progetto(%d+)$"))
			local uv= mw.language.new("it"):ucfirst(v)
			if config.progetti[v] then -- questo lavoro azzoppa l'iconaArgomento
				v= config.progetti[v]
			elseif config.progetti[uv] then
				v= config.progetti[uv]
			else
				v= uv end
			self.progetti[i]= v
			args.k= nil
		else
			self:newError("parametro <tt>"..k.."</tt> non riconosciuto")
			args[k]= nil end end
	riordinaTabella(self.progetti)
	if #self.progetti == 0 then
		self:newError("nessun progetto specificato")
	elseif #self.progetti > 4 then
		self:newError("più di quattro progetti specificati")
		for i= 5, #self.progetti do
			self.progetti[i]= nil end end end

function monitoraggio:assegnaLivello() -- la funzione attuale non è proprio così banale
	local out= "non compilate"
	for _, v in pairs(self.voti) do
		if v ~= "NC" then
			for _, vv in ipairs({"NC", "E", "D", "C", "B", "A"}) do	-- cerca un valore alla volta in tutti i parametri, partendo dal basso, quindi assegna in generale
				for k, vvv in pairs(self.voti) do					-- un livello corrispondente al più basso valore tra i voti che sono stati dati alla voce
					if vv == vvv then
						out= config.livelli[v]
						self.valore_minimo= k		-- serve a scrivere: "non è possibile dare un voto maggiore con tale parametro che ha un voto tanto basso"
						do break end break
						end end end
			break end end
	self.livello= out end

function monitoraggio:creaCategorie()
	local out= self.categorie or {}
	out[#out + 1]= "[[Categoria:Voci monitorate - "..self.livello.."]]"
	for _, prg in ipairs(self.progetti) do
		local indirizzo= "Voci monitorate Progetto "..prg.." - "..self.livello
		if mw.title.makeTitle(Categoria, indirizzo):esist() then
			out[#out + 1]= "[[Categoria:"..indirizzo.."]]" end end
	for k, v in pairs(self.voti) do
		out[#out + 1]= "[[Categoria:Voci monitorate - "..k.." "..v.."]]"
		for _, prg in ipairs(self.progetti) do
			local indirizzo= "Progetto:"..prg.."/Tabella monitoraggio automatico - "..self.livello
			if mw.title.makeTitle(Categoria, indirizzo):esist() then
				out[#out + 1]= "[[Categoria:"..indirizzo.."]]" end end end
	if not self.data then
		self:newError("data non specificata")
	else
		local indirizzo= "Voci monitorate - "..self.data
		if mw.title.makeTitle(Categoria, indirizzo):esist() then
			out[#out + 1]= "[[Categoria:"..indirizzo.."]]"
		else
			self:newError("data non riconosciuta, inserire: <code>data = "..mw.language.new("it"):formatDate("F Y").."</code>") end end
	self.categorie= out end

function monitoraggio:impostaRigaProgetti()
	local out= { icone= {}, testo= {} }
	for i, prg in ipairs(self.progetti) do
		out.icone[i]= "[[File:"..iconaArgomento({prg, "Crystal Clear app ksirtet.png"}).."|35x50px]]" -- il template sarebbe da trasformare in una tabella lua
		if i == 1 then
			out.testo= {"[[Progetto:"..prg.."/Monitoraggio voci|Monitoraggio "..prg.."]]"}
		else
			out.testo[i]= "[[Progetto:"..prg.."/Monitoraggio voci|"..prg.."]]" end end
	return out end

function monitoraggio:impostaRigaLivello()
	local out= {}
	local liv= self.livello
	if config.livelli[liv] == "NC" then
		out.icona= "[[File:Symbol stub class.svg|25px|center]]" -- credo che toglierò quel "center"
	else
		out.icona= "<span style=\"font-weight: bold; font-size: 145%; border: 1px solid lightsteelblue; background:"..
		           config.colore_voti[config.livelli[liv]].."; color:blue; \">&nbsp;'''<tt>&nbsp;[[:Categoria:Voci monitorate - "..liv.."|"..
		           string.gsub(liv, "livello ", "").."]]'''</tt>&nbsp;</span>" end
	out.testo= config.descrizione_stato.livello[liv]
	-- da raffinare sia per gli stub che per i monitoraggi incompleti
	if self.data then
		out.data= "Voce monitorata nel mese di "..self.data end
	return out end

function monitoraggio:impostaRigheVoti()
	local out= {}
	for i, s in ipairs({"accuratezza", "scrittura", "fonti", "immagini"}) do
		local voto= self.voti[s]
--		if voto ~= "NC" then -- le righe non valutate non compaiono, perché dovrebbero?
			local outi= {}
			outi.icona= "<span style=\"font-weight: bold; font-size: 155%; border: 1px solid lightsteelblue; background:"..
			            config.colore_voti[voto]..";\">&thinsp;'''<tt>"..voto.."</tt>'''&thinsp;</span>"
			outi.testo= config.descrizione_stato[s][voto]
			out[i]= outi end -- end
	return out end
	
function monitoraggio:creaContenitore()
	local prg= self:impostaRigaProgetti()
	local liv= self:impostaRigaLivello()
	local out= mw.html.create("div")
		:addClass("mw-collapsible") -- per rendere i voti particolari a scomparsa
		:cssText("border: 1px solid silver; margin-bottom: 0.2em; margin-left: auto; margin-right: auto; background-color: white; padding: 2px;")
	-- il box è diviso in tre tabelle
	local out_prg= out:tag("div")
		:cssText("background-color: #B5D9D3;")
		:tag("table")
			:cssText("border: none; margin-right:"..(#prg.icone * 35).."px;") -- border-collapse: collapse;
			:tag("tr")
	for i, icona in ipairs(prg.icone) do
		out_prg:tag("td")
			:cssText("width: 35px;")
			:wikitext(prg.icone[i]) end
	out_prg:tag("th")
		:cssText("width: 100%; text-align: center;")
		:wikitext(table.concat(prg.testo, ", "))
	-----
	out:tag("table")
		:cssText("width: 100%; border: none;") -- border-collapse: collapse;
		:tag("tr")
			:tag("td")
				:wikitext(liv.icona)
				:done()
			:tag("td")
				:cssText("font-size: 107%;") -- lo toglierei
				:wikitext(liv.testo)
				:done()
			:tag("td")
				:cssText("color: grey; text-align: right; padding-right: 6px; font-size: 95%;")
				:wikitext(liv.data)
	-----
	local out_voti= out:tag("table")
		:addClass("mw-collapsible-content")
		:cssText("border-collapse: collapse; width: 100%;")
	for _, t in ipairs(self:impostaRigheVoti()) do
		out_voti:tag("tr")
			:cssText("border: 1px solid #B5D9D3;")
			:tag("td")
				:wikitext(t.icona)
				:done()
			:tag("td")
				:wikitext(t.testo) end
	return out end

function monitoraggio:__tostring()
--	for _, s in self.categorie_errore do
--		self.categorie[#self.categorie + 1]= s end
	local out= tostring(self:creaContenitore())
	local err= self.errori
	local cat= self.categorie
	if err then
		out= out.."<div class=\"error\">"..table.concat(err, "<br />").."</div>" end
	if cat then
		if err then
			cat[#cat + 1]= "[[Categoria:Errori di compilazione del template Monitoraggio]]" end
		out= out..table.concat(cat, "\n") end
	return out end

function monitoraggio:new(o)
	o= {} or o
	setmetatable(o, self)
	self.__index= self
	return o end

-- FUNZIONE DI INVOKE
--------------------------------------------------------------------------------

local p= {}

function p.main(frame)
	local args= getArgs(frame)
	local out=monitoraggio:new()
	out:organizzaArgomenti(args)
	out:assegnaLivello()
	if mw.title.getCurrentTitle().namespace == 1 then
		out:creaCategorie() end
	return tostring(out) end

return p