Modulo che implementa il template {{Codice statistico}}.


--[[
* Modulo che implementa il template Codice statistico.
]]--

require('strict')

local getArgs = require('Modulo:Arguments').getArgs
local mWikidata = require('Modulo:Wikidata')

-- Funzione di formattazione del codice municipale austriaco (Statistik Austria).
--
-- @param {string} id
-- @return {string}
local function formatP964(id)
	local formatted_id = string.gsub(id, '(%d)(%d%d)(%d%d)', '%1 %2 %3')
	return string.format('[http://www.statistik.at/blickgem/gemDetail.do?gemnr=%s %s]', id, formatted_id)
end

-- Funzione di formattazione del codice municipale tedesco (Statistisches Bundesamt).
--
-- @param {string} id
-- @return {string}
local function formatP439(id)
	local formatted_id = string.gsub(id, '(%d%d)(%d)(%d%d)(%d%d%d)', '%1 %2 %3 %4')
	return string.format('[http://www.statistik-portal.de/Statistik-Portal/gemeindeverz.asp?G=%s %s]', id, formatted_id)
end

-- Funzione di formattazione del codice dei distretti tedesco (Statistisches Bundesamt).
--
-- @param {string} id
-- @return {string}
local function formatP440(id)
	return string.gsub(id, '(%d%d)(%d)(%d%d)', '%1 %2 %3')
end

-- Funzione di formattazione del codice INSEE
-- (Institut national de la statistique et des études économiques).
--
-- @param {string} id
-- @return {string}
local function formatP374(id)
	return string.format('[http://www.insee.fr/fr/themes/dossier_complet.asp?codgeo=COM-%s %s]', id, id)
end

-- Funzione di formattazione del codice municipale IBGE
-- (Instituto Brasileiro de Geografia e Estatística).
--
-- @param {string} id
-- @return {string}
local function formatP1585(id)
	return string.format('[http://cidades.ibge.gov.br/xtras/perfil.php?codmun=%s %s]', id, id)
end

-- Funzione di formattazione del codice KSH (Központi Statisztikai Hivatal).
--
-- @param {string} id
-- @return {string}
local function formatP939(id)
	return string.format('[http://www.ksh.hu/apps/hntr.telepules?p_id=%s %s]', id, id)
end

-- Funzione di confronto predefinita per le categorie Wikidata.
--
-- @param {string} wdval
-- @param {string} userval
-- @return {boolean}
local function compareDefault(wdval, userval)
	return string.gsub(wdval, ' ', '') == string.gsub(userval, ' ', '')
end

-- Funzione di confronto del codice OFS per le categorie Wikidata.
--
-- @param {string} wdval
-- @param {string} userval
-- @return {boolean}
local function compareP771(wdval, userval)
	wdval = string.gsub(wdval, ' ', '')
	userval = string.gsub(userval, ' ', '')
	return wdval == userval or (tonumber(userval) and wdval == string.format('%04d', userval))
end

-- Codici statistici configurati
local statCodes = {
	AUT = {
		default = { prop = 'P964', format = formatP964 }
	},
	BEL = {
		default = { prop = 'P1567' }
	},
	BRA = {
		default = { prop = 'P1585', format = formatP1585 }
	},
	CHE = {
		default = { prop = 'P771', compare = compareP771 }
	},
	CHN = {
		default = { prop = 'P442' }
	},
	CZE = {
		default = { prop = 'P782' }
	},
	DEU = {
		['1'] = {}, -- disabilitato
		['3'] = { prop = 'P440', format = formatP440 },
		default = { prop = 'P439', format = formatP439 }
	},
	DNK = {
		default = { prop = 'P1168' }
	},
	ESP = {
		default = { prop = 'P772' }
	},
	FRA = {
		['1'] = { prop = 'P2585' },
		['2'] = { prop = 'P2586' },
		['3'] = { prop = 'P3423' },
		['4'] = { prop = 'P2506' },
		default = { prop = 'P374', format = formatP374 }
	},
	HUN = {
		default = { prop = 'P939', format = formatP939 }
	},
	ITA = {
		default = { prop = 'P635' }
	},
	NLD = {
		default = { prop = 'P382' }
	},
	NOR = {
		default = { prop = 'P2504' }
	},
	UKR = {
		default = { prop = 'P1077' }
	}
}

-- Restituisce la categoria Wikidata appropriata in base
-- al valore utente, a quello su Wikidata e al tipo di codice.
--
-- @param {string} userval
-- @param {string} wdval
-- @param {table} code
-- @return {string}
local function getWikidataCategory(userval, wdval, code)
	local cat
	-- consente di definire funzioni di confronto per proprietà specifiche
	local comparefunc = code.compare or compareDefault

	if userval then
		if not wdval then
			cat = string.format('%s assente su Wikidata', code.prop)
		elseif comparefunc(wdval, userval) then
			cat = string.format('%s uguale su Wikidata', code.prop)
		else
			cat = string.format('%s differente su Wikidata', code.prop)
		end
	elseif wdval then
		cat = string.format('%s letta da Wikidata', code.prop)
	end

	return cat and string.format('[[Categoria:%s]]', cat) or ''
end

-- =============================================================================
--                            Funzioni esportate
-- =============================================================================

local p = {}

-- Funzione di utilità per il manuale, restituisce una tabella HTML
-- con i codici statistici configurati.
function p.report()
	local tableNode
	local sortedCodes = {}

	for key, _ in pairs(statCodes) do
		table.insert(sortedCodes, key)
	end
	table.sort(sortedCodes)

	tableNode = mw.html.create('table')
	tableNode
		:addClass('wikitable')
		:addClass('sortable')
		:tag('tr')
			:tag('th')
				:wikitext('Codice')
				:done()
			:tag('th')
				:wikitext('Paese')
				:done()
			:tag('th')
				:wikitext('Grado amministrativo')
				:done()
			:tag('th')
				:wikitext('Proprietà Wikidata')
				:done()
			:tag('th')
				:wikitext('Dati letti')
				:done()

	for _, iso3166 in ipairs(sortedCodes) do
		local codes = statCodes[iso3166]
		for key, value in pairs(codes) do
			if value.prop then
				local catLetto = value.prop .. ' letta da Wikidata'
				local pagesInCat = mw.site.stats.pagesInCategory(catLetto, 'pages')
				tableNode
					:tag('tr')
						:tag('td')
							:wikitext(mw.wikibase.getLabel(value.prop))
							:done()
						:tag('td')
							:wikitext(iso3166)
							:done()
						:tag('td')
							:wikitext(key == 'default' and 'predefinito' or key)
							:done()
						:tag('td')
							:wikitext(string.format('[[d:p:%s|%s (%s)]]',
								value.prop, mWikidata._getLabel({ value.prop }), value.prop))
							:done()
						:tag('td')
							:css('text-align', 'right')
							:wikitext(string.format('[[:Categoria:%s|%s]]', catLetto, pagesInCat))
							:done()
			end
		end
	end

	return tostring(tableNode)
end

-- Funzione per l'utilizzo da un altro modulo.
function p._main(args)
	local code, userval, wdval, formatted_userval, formatted_wdval
	local cat = ''

	-- valore utente
	userval = args[1]
	formatted_userval = userval

	-- ricerca paese
	if args.iso3166 then
		code = statCodes[args.iso3166]
	end
	if not code then
		local iso3166 = mWikidata._getProperty({ 'P17', showprop = 'P298', from = args.from, n = 1 })
		code = statCodes[iso3166]
	end
	-- ricerca grado amministrativo
	if code then
		code = code[args.grado] or code.default
	end

	-- codice presente e abilitato
	if code and code.prop then
		-- valore letto da Wikidata
		wdval = mWikidata._getProperty({ code.prop, from = args.from, n = 1 })
		formatted_wdval = (wdval and code.format) and code.format(wdval) or wdval
		formatted_userval = (userval and code.format) and code.format(string.gsub(userval, ' ', '')) or userval

		-- categoria di servizio
		if mw.title.getCurrentTitle().namespace == 0 and (userval or wdval) then
			cat = getWikidataCategory(userval, wdval, code)
		end
	end

	return (formatted_userval or formatted_wdval or '') .. cat
end

-- Funzione per il template {{Codice statistico}}.
function p.main(frame)
	return p._main(getArgs(frame, { parentOnly = true }))
end

return p