local item = mw.wikibase.getEntityObject()

function getId( id )	
	if id then
		return id
	end
	if item then
		return item.id
	end
	return nil
end

-- Restituisce il collegamento corrispondente al codice fornito.
function sitelink(dbname)
	if (dbname or '') == '' then
		return ''
	end
	if item and item:getSitelink(dbname) then
		return item:getSitelink(dbname)
	end
	return ''
end

-- Restituisce le coordinate geografiche corrispondenti all'elemento
function coords(typ, fallback)
	if (fallback or '') ~= '' and string.match(fallback, '^<%!%-%-.*%-%->$') == nil then
		return fallback
	end
	if item and item.claims then
		local coords = item.claims.P625
		if coords and #coords == 1 and coords[1].mainsnak and coords[1].mainsnak.datavalue and coords[1].mainsnak.datavalue.value then
			return coords[1].mainsnak.datavalue.value[typ]
		end
	end
	return ''
end

function normalize_timezone(tz)
	local k = string.gsub(tz, '%+0(%d)$', '+%1')
	k = string.gsub(k, '%+0(%d:%d%d)$', '+%1')
	return string.gsub(k, '(%+%d%d?):00$', '%1')
end

function normalize_timezone_list(list)
	--alphaindexline
	return mw.text.listToText(list)
end

-- Restituisce l'elemento più aggiornato tra una serie di asserzioni
-- TODO: ranks
function aggiornato(item, prop, frame)
	if item and item.claims and item.claims[prop] then
		for index, claim in pairs(item.claims[prop]) do
			local qual = claim.qualifiers
			if qual == nil or qual.P582 == nil then
				-- P582 è la data di fine, significa che non è il valore attuale
				if claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then
					local val = claim.mainsnak.datavalue.value
					if val['numeric-id'] then
						local id = 'Q'..val['numeric-id']
						local sl = mw.wikibase.sitelink(id)
						local lb = mw.wikibase.label(id)
						if sl and sl ~= '' then
							return frame:preprocess('[['..sl..'|'..lb..']]')
						end
						return lb
					end
					return val
				end
			end
		end
	end
	return ''
end

local p = {}
--
-- Restituisce l'ID dell'elemento collegato alla pagina corrente.
function p.id(frame)
	id = getId(frame.args[1])
	if id then
		   return id
	end
	return '(nessun elemento trovato)'
end


-- Restituisce l'ID dell'elemento collegato alla pagina corrente sotto forma di link a Wikidata.
function p.idLink(frame)
	local id = getId(frame.args[1])
	if id then
		return '[[d:' .. id .. '|' .. id .. ']]'
	end
	return '(nessun elemento trovato)'
end


-- Restituisce l'etichetta di un elemento.
function p.label(frame)
	local id = getId(frame.args[1])
	if id then
		   return mw.wikibase.label( id )
	end
	return '(nessun elemento trovato)'
end

-- Restituisce il primo valore non nullo (nell'ordine) tra il: parametro passato in ingresso, etichetta dell'entità Wikidata, nome della pagina.
function p.pagename(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local id = getId()
	if id then
		   return mw.wikibase.label( id )
	end
	return mw.title.getCurrentTitle().text
end

-- Restituisce la pagina locale dell'elemento di Wikidata fornito.
function p.page(frame)
	local id = getId(frame.args[1])
	if id then
		   return mw.wikibase.sitelink( id )
	end
	return '(nessun elemento trovato)'
end

-- Restituisce il collegamento corrispondente al codice fornito.
function p.sitelink(frame)
	return sitelink(frame.args.dbname or frame.args[1])
end

-- Restituisce il collegamento corrispondente a Wikipedia in italiano.
function p.itwikilink(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local sl = sitelink('itwiki')
	if sl and sl ~= '' then
		return sl
	end
--[[	local t = mw.title.getCurrentTitle().text
	if t and t ~= '' then
		return t
	end
	]]
	return ''
end

-- Restituisce il collegamento corrispondente a Wikiquote in italiano.
function p.itwikiquotelink(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local sl = sitelink('itwikiquote')
	if sl and sl ~= '' then
		return sl
	end
	return ''
end

-- Restituisce il collegamento corrispondente a Wikisource in italiano.
function p.itwikisourcelink(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local sl = sitelink('itwikisource')
	if sl and sl ~= '' then
		return sl
	end
	return ''
end

-- Restituisce il collegamento corrispondente a Wikinotizie in italiano.
function p.itwikinewslink(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local sl = sitelink('itwikinews')
	if sl and sl ~= '' then
		return sl
	end
	return ''
end

-- Restituisce il nome della categoria di Commons collegata all'articolo attraverso Wikidata.
function p.commonslink(frame)
	if (frame.args[1] or '') ~= '' then
		return 'Category:'..frame.args[1]
	end
	if item and item.claims then
		local cat = item.claims.P373
		if cat and #cat == 1 and cat[1].mainsnak and cat[1].mainsnak.datavalue and cat[1].mainsnak.datavalue.value then
			return 'Category:'..(cat[1].mainsnak.datavalue.value)
		end
	end
--[[	local t = mw.title.getCurrentTitle().text
	if t and t ~= '' then
		return 'Category:'..t
	end
]]
	return ''
end

-- Restituisce il nome della capitale o del capoluogo attuale dell'elemento.
function p.capitale(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Capitale or '') ~= '' then
		return parent.args.Capitale
	end
	return aggiornato(item,'P36',frame)
end

function p.capoluogo(frame)
	return p.capitale(frame)
end

function p.valuta(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Valuta or '') ~= '' then
		return parent.args.Valuta
	end
	return aggiornato(item,'P38',frame)
end

function p.sito(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent then
		local args = parent.args
		if (args.Sito or '') ~= '' then
			return args.Sito
		end
		if (args['Sito ufficiale'] or '') ~= '' then
			return args['Sito ufficiale']
		end
	end
	return aggiornato(item,'P856',frame)
end

function p.banner(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Banner or '') ~= '' then
		return parent.args.Banner
	end
	return aggiornato(item,'P948',frame)
end

function p.stemma(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Stemma or '') ~= '' then
		return parent.args.Stemma
	end
	return aggiornato(item,'P94',frame)
end

function p.bandiera(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Bandiera or '') ~= '' then
		return parent.args.Bandiera
	end
	return aggiornato(item,'P41',frame)
end

function p.abitanti(frame)
	if (frame.args[1] or '') ~= '' then
		return frame.args[1]
	end
	local parent = frame:getParent()
	if parent and (parent.args.Abitanti or '') ~= '' then
		return parent.args.Abitanti
	end
	return aggiornato(item,'P1082',frame)
end

-- Restituisce l'etichetta dell'elemento rappresentante la bandiera relativa all'elemento dell'articolo
function p.bandiera_titolo(frame)
	if item then
		local claims = item.claims
		if claims and claims.P163 and claims.P163[0] and claims.P163[1] == nil then
			return mw.wikibase.label('Q'..claims.P163[0].mainsnak.datavalue.value['numeric-id'])
		end
	end
	return mw.title.getCurrentTitle().text..' - Bandiera'
end

-- Restituisce l'etichetta dell'elemento rappresentante lo stemma relativo all'elemento dell'articolo
function p.stemma_titolo(frame)
	if item then
		local claims = item.claims
		if claims and claims.P237 and claims.P237[0] and claims.P237[1] == nil then
			return mw.wikibase.label('Q'..claims.P237[0].mainsnak.datavalue.value['numeric-id'])
		end
	end
	return mw.title.getCurrentTitle().text..' - Stemma'
end

-- Restituisce la latitudine corrispondente all'articolo.
function p.latitudine(frame)
	return coords('latitude',frame.args[1])
end

-- Restituisce la longitudine corrispondente all'articolo.
function p.longitudine(frame)
	return coords('longitude',frame.args[1])
end

function p.fuso_orario(frame)
	local link = false
	for i, e in pairs(frame.args) do
		if e == 'link' then
			link = true
			break
		end
	end
	if item and item.claims and item.claims.P421 then
		local claims = item.claims.P421
		local zone = {}
		for i, e in pairs(claims) do
			local id = e.mainsnak.datavalue.value['numeric-id']
			local z = normalize_timezone(mw.wikibase.label('Q'..id))
			if link then
				z = frame:preprocess('[[d:Q'..id..'|'..z..']]')
			end
			table.insert(zone, z)
		end
		return normalize_timezone_list(zone)
	end
	return ''
end

function p.disambig(frame)
	if p.instanceof(4167410) then
		return true
	end
	return false
end

function p.instanceof(arg)
--	arg = tonumber(arg.args[1] or arg)
	if item and item.claims and item.claims.P31 then
		local claims = item.claims.P31
		for index, claim in pairs(claims) do
			if claim.mainsnak and claim.mainsnak.datavalue then
				local val = claim.mainsnak.datavalue.value
				if val and val['numeric-id'] and arg == val['numeric-id'] then
					return true
				end
			end
		end
	end
	return false
end

return p