local cfg = mw.loadData( 'Modulo:Partiti/Configurazione');
local getArgs = require('Module:Arguments').getArgs

-- ====================================================
-- corregge un valore di ritorno se questo inizia per '#'
-- vedi bug https://phabricator.wikimedia.org/T14974
-- sostituendo l'entità html al carattere #
-- =====================================================
local function fix_return(colore)
	if string.sub(colore,1,1) == '#' then
		colore = "#" .. string.sub(colore, 2, 7)
	end
	return colore
end

-- ==========================================================
-- Estrae il nome del partito in caso di wikilink.
-- ==========================================================
local function estrai(partito)
	local a = partito
	local x1 = mw.ustring.find(a,'%[%[')
	if (x1) then
		local b = mw.ustring.sub(a,x1+2)
		local x2 = mw.ustring.find(b,'%|')
		local x3 = mw.ustring.find(b,'%]%]')
		local x4 = mw.ustring.find(b,'%<s')
		local x5 = mw.ustring.find(b,'%–')
		if (x3) then
			if (x4) then
				a=mw.ustring.sub(a,x1,x3+x1)
			end
			if (x5) then
				a=mw.ustring.sub(a,x1,x3+x1)
			end	
			if (x2) then
				a = mw.ustring.sub(a,x1+2,x2+x1)
			else
				a = mw.ustring.sub(a,x1+2,x3+x1)
			end
		end
	end
	a = mw.text.decode(a)
	return a
end

-- ==========================================================
-- Consulta la tabella di configurazione e ritorna il colore
-- associato a partito. Se questo non è definito o non viene
-- trovato ritorna il valore di default.
-- Se l'opzione ombra è vera ritorna invece il colore ombra
-- associato (generalmente un colore più chiaro da usare
-- quando sul colore del partito va messo uno sfondo), se i colore
-- ombra non esiste ritorna il colore normale.
-- ==========================================================
local function _colore(partito, default, ombra) 
	default = default or '#DABAD0'
	if partito == nil then return fix_return(default) end
	local partito_indice = estrai(partito)
	partito_indice = cfg.alias[partito_indice] or partito_indice
	local color
	if ombra then
		color =  cfg.colore_ombra[partito_indice] or cfg.colore[partito_indice] or default
	else
		color = cfg.colore[partito_indice] or default
	end
	return  fix_return(color)
end

-- ==========================================================
-- Funzione specializzata per il template elezioni
-- Calcola il colore in base al fatto che siano valorizzati i
-- seguenti parametri in ordine di precedenza:
-- - colore
-- - coalizione
-- - partito
-- ==========================================================
local function colore_elezioni(frame)
	local args = getArgs(frame)
	local colore = args.colore
	if colore then return fix_return(colore) end
	if args.coalizione then
		local try_colore_coalizione =_colore(args.coalizione)
		if try_colore_coalizione and try_colore_coalizione ~='' then return try_colore_coalizione end
	end
	if args.partito then return _colore(args.partito) end
	if args.gruppo then return _colore(args.gruppo) end	
	if args.coll then return _colore(args.coll) end	
	return ''
end

-- ==========================================================
-- Funzione di interfaccia con il codice wiki, ritorna il 
-- colore associato al partito passato con il primo parametro
-- o in caso non viene trovato quello di default
-- ==========================================================
local function colore(frame)
	local args = getArgs(frame, {frameOnly = true})
	return _colore(args[1], args[2])
end

-- ==========================================================
-- Funzione di interfaccia con il codice wiki, ritorna il 
-- colore associato al partito passato con il primo parametro
-- o in caso non viene trovato quello di default; il colore
-- è mostrato con opacità passata tramite terzo parametro
-- ==========================================================
local function sfondo(frame)
	local args = getArgs(frame, {frameOnly = true})
	local col = _colore(args[1], args[2])
	local opac = tonumber(args[3] or 0.5)
	local rgb = col:sub(6)
	local cls = {}
	if (rgb:len() == 6) then
		cls[1] = tonumber(rgb:sub(1,2),16) or 255
		cls[2] = tonumber(rgb:sub(3,4),16) or 255
		cls[3] = tonumber(rgb:sub(5,6),16) or 255
	elseif (rgb:len() == 3) then
		cls[1] = 17*(tonumber(rgb:sub(1,1),16) or 15)
		cls[2] = 17*(tonumber(rgb:sub(2,2),16) or 15)
		cls[3] = 17*(tonumber(rgb:sub(3,3),16) or 15)
	else
		return '&#35;CCC'
	end
	cls[1] = 255 - math.floor((255-cls[1])*opac)
	cls[2] = 255 - math.floor((255-cls[2])*opac)
	cls[3] = 255 - math.floor((255-cls[3])*opac)
	return string.format('&#35;%02x%02x%02x',cls[1],cls[2],cls[3])
end

-- ==========================================================
-- Converte codice hex in rgb percentuale 
-- ==========================================================
local function codice(frame)
	local args = getArgs(frame, {frameOnly = true})
	local col = _colore(args[1], args[2])
	local rgb = col:sub(6)
	return (rgb:sub(1,6))
end

local function cod(frame)
	local args = getArgs(frame, {frameOnly = true})
	local col = _colore(args[1], args[2])
	local rgb = col:sub(6)
	local cls = {}
	if (rgb:len() == 6) then
		cls[1] = tonumber(rgb:sub(1,2),16) or 255
		cls[2] = tonumber(rgb:sub(3,4),16) or 255
		cls[3] = tonumber(rgb:sub(5,6),16) or 255
	end
	cls[1] = math.floor(cls[1]/255)
	cls[2] = math.floor(cls[2]/255)
	cls[3] = math.floor(cls[3]/255)
	return string.format('%02x%02x%02x',cls[1],cls[2],cls[3])
end

-- ==========================================================
-- Funzione di interfaccia con il codice wiki, ritorna il 
-- colore ombra associato al partito passato con il primo parametro
-- o in caso non viene trovato un eventuale default
-- ==========================================================
local function colore_ombra(frame)
	local args = getArgs(frame, {frameOnly = true})
	return _colore(args[1], args[2] or '', true)
end

local function _nome_corto(partito)
	if partito == nil then return '' end
	partito_indice = cfg.alias[partito] or partito 
	return cfg.nome_corto[partito_indice] or partito_indice
end

local function nome_corto(frame)
	local args = getArgs(frame, {frameOnly = true})
	return _nome_corto(args[1])
end

-- ==========================================================
-- Ritorna la tabella di configurazione dei codici colore
-- ==========================================================
local function color_table(frame)

	local color_t = mw.html.create('table'):addClass('wikitable sortable')
	color_t:tag('tr')
		:tag('th'):attr('colspan', '2'):wikitext('Colore'):done()
		:tag('th'):attr('colspan', '2'):wikitext('Ombra'):done()
			:tag('th'):attr('rowspan', '2'):wikitext('Partito'):done()
	color_t:tag('tr')
		:tag('th'):wikitext('Esempio'):done()
		:tag('th'):wikitext('Codice'):done()
		:tag('th'):wikitext('Esempio'):done()
		:tag('th'):wikitext('Codice'):done()
	local names = {}
	for k,v in pairs(cfg.colore) do
		names[#names+1] = k
	end
	table.sort(names)
	for _,name in ipairs(names) do
		local tr = color_t :tag('tr')
		tr:tag('td'):wikitext('&nbsp;'):css('background-color', cfg.colore[name]):done()
		tr:tag('td'):wikitext(cfg.colore[name]):done()
		if cfg.colore_ombra[name] then
			tr:tag('td'):wikitext('&nbsp;'):css('background-color', cfg.colore_ombra[name]):done()
			tr:tag('td'):wikitext(cfg.colore_ombra[name]):done()
		else
			tr:tag('td'):wikitext('&nbsp;'):done()	
			tr:tag('td'):wikitext('&nbsp;'):done()	
		end
		tr:tag('td'):wikitext('[[' .. name .. ']]'):done()
	end
	return color_t
end

return {
	colore = colore,
	_colore = _colore,
	colore_elezioni = colore_elezioni,
	nome_corto = nome_corto,
	_nome_corto = _nome_corto,
	color_table = color_table,
	colore_ombra = colore_ombra,
	sfondo = sfondo,
	codice = codice,
	cod = cod
}