Dokumentaci tohoto modulu lze vytvořit na stránce Nápověda:Modul:Wikidata

local i18n = {
	["errors"] = {
		["param-not-provided"] = "Nezadán parametr %s",
		["entity-not-found"] = "Entita nenalezena",
		["unknown-claim-type"] = "Neznámý typ tvrzení: %s",
		["unknown-snak-type"] = "Neznámý typ snaku: %s",
		["unknown-datavalue-type"] = "Neznámý typ datové hodnoty: %s",
		["unknown-entity-type"] = "Neznámý typ entity: %s",
		["unknown-value-module"] = "Musíte nastavit oba parametry value-module i value-function",
		["value-module-not-found"] = "Modul odkazovaný parametrem value-module nenalezen",
		["value-function-not-found"] = "Funkce odkazovaná parametrem value-function nenalezena",
		["invalid-field"] = "Neplatné pole"
	},
	["somevalue"] = "''neznámá hodnota''",
	["novalue"] = "''bez hodnoty''"
}

function getEntityFromId( id )
	return mw.wikibase.getEntityObject( id )
end

function wrapWithSpan(str, param, value)
	return '<span ' .. param .. '="' .. value .. '">' .. str .. '</span>'
end

function formatError( key, ... )
	return wrapWithSpan(string.format( i18n.errors[key], ... ), 'class', 'error')
end

function getSitelink(options)
	local site = nil
	if options.site ~= nil and options.site ~= '' then
		site = options.site
	elseif options[1] ~= nil and options[1] ~= '' then
		site = options[1]
	else
		return formatError( 'param-not-provided', 'site' )
	end

	local entity = nil
	entity = getEntityFromId( options.item )

	if not entity or not entity.sitelinks then
		return ''
	end

	local sitelink = nil
	if entity.sitelinks[site] then
		sitelink = entity.sitelinks[site].title
	end

	if not sitelink then
		return ''
	elseif not options.pattern or options.pattern == '' then
		return sitelink
	else
		formatFromPattern(sitelink, options)
	end
end

function getEntityIdFromValue( value )
	local entityType = value['entity-type']
	if entityType == 'item' then
		return 'q' .. value['numeric-id']
	elseif entityType == 'property' then
		return 'p' .. value['numeric-id']
	else
		return formatError( 'unknown-entity-type', entityType )
	end
end

function formatStatements( options )
	if not options.property then
		return formatError( 'param-not-provided', 'property' )
	end

	--Get entity
	local entity = nil
	if options.entity and type( options.entity ) == "table" then
		entity = options.entity
	else
		entity = getEntityFromId( options.item )
	end

	if not entity then
		return '' --TODO error?
	end

	if not entity.claims or not entity.claims[string.upper(options.property)] then
		return '' --TODO error?
	end

	local limit
	if options.limit and options.limit ~= '' and type(options.limit) == 'number' then
		limit = tonumber(options.limit)
	else
		limit = 999
	end

	--Format statements and concat them cleanly
	local formattedStatements = {}
	for i, statement in pairs( entity.claims[options.property:upper()] ) do
		if options.rank == 'one' then
			return formatStatement( statement, options ) --Output only one value
		elseif (
				((not options.rank or options.rank == 'normal') and (statement.rank == 'normal' or statement.rank == 'preferred')) or
				(options.rank == 'preferred' and statement.rank == 'preferred') or
				(options.rank == 'all')
		) then
			table.insert( formattedStatements, formatStatement( statement, options ) )
		end
	end
	return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end

function formatStatement( statement, options )
	if not statement.type or statement.type ~= 'statement' then
		return formatError( 'unknown-claim-type', statement.type )
	end

	return formatSnak( statement.mainsnak, options )
	--TODO reference and qualifiers
end

function formatSnak( snak, options )
	if snak.snaktype == 'somevalue' then
		return i18n['somevalue']
	elseif snak.snaktype == 'novalue' then
		return i18n['novalue']
	elseif snak.snaktype == 'value' then
		return formatDatavalue( snak.datavalue, options )
	else
		return formatError( 'unknown-snak-type', snak.snaktype )
	end
end

function formatDatavalue( datavalue, options )
	--Use the customize handler if provided
	if options['value-module'] or options['value-function'] then
		if not options['value-module'] or not options['value-function'] then
			return formatError( 'unknown-value-module' )
		end
		local formatter = require ('Module:' .. options['value-module'])
		if not formatter then
			return formatError( 'value-module-not-found' )
		end
		local fun = formatter[options['value-function']]
		if not fun then
			return formatError( 'value-function-not-found' )
		end
		return fun( datavalue.value, options )
	end

	--Default formatters
	if datavalue.type == 'wikibase-entityid' then
		return formatEntityId( getEntityIdFromValue( datavalue.value ) )
	elseif datavalue.type == 'string' then
		if options.pattern and options.pattern ~= '' then
			return formatFromPattern( datavalue.value, options )
		else
			return datavalue.value
		end
	elseif datavalue.type == 'time' then
		local Time = require 'Module:Time'
		return Time.newFromWikidataValue( datavalue.value ):toString()
	elseif datavalue.type == 'globecoordinate' then
		if not options.field then
			return formatError( 'param-not-provided', 'field' )
		elseif options.field == "latitude" or options.field == "longitude" or options.field == "precision" or options.field == "globe" then
			return datavalue.value[options.field]
		else
			return formatError( 'invalid-field' )
		end
	elseif datavalue.type == 'monolingualtext' then
		return wrapWithSpan(datavalue.value.text, 'lang', datavalue.value.language)
	elseif datavalue.type == 'quantity' then
		return tonumber(datavalue.value.amount)
	else
		return formatError( 'unknown-datavalue-type', datavalue.type )
	end
end

function formatEntityId( entityId )
	local label = mw.wikibase.label( entityId )
	local link = mw.wikibase.sitelink( entityId )
	if link then
		if label then
			return '[[' .. link .. '|' .. label .. ']]'
		else
			return '[[' .. link .. ']]'
		end
	elseif label then
		return wrapWithSpan(label, 'class', 'InfoFromWikidata')
	else
		return getLinkWhenNonexistingLabel(entityId)
	end
end

function formatFromPattern( str, options )
	return mw.ustring.gsub( options.pattern, '$1', str ) .. '' --Hack to get only the first result of the function
end

function getLinkWhenNonexistingLabel( entityId )
	local title = mw.title.getCurrentTitle().text
	return '[[Soubor:Wikidata-edit.svg|27x17px|link=d:' .. entityId .. '|Položka na Wikidatech neobsahuje český štítek; můžete ho doplnit]]<code>[[d:' .. entityId .. '|' .. entityId .. ']]</code>[[Kategorie:Údržba:Doplnit štítek na Wikidatech|' .. title .. ']]'
end

local p = {}

function p.dumpWikidataEntity ( frame )
	local args = frame and frame.args or nil

	return mw.dumpObject( getEntityFromId( args and args.id or nil ) )
end

function p.getSitelink( frame )
	return getSitelink( frame.args )
end

function p.formatStatements( frame )
	local args = frame.args

	--If a value is already set, use it
	if args.value and args.value ~= '' then
		return args.value
	end
	return formatStatements( frame.args )
end

function p.formatStatementsFromLua( options )
	--If a value is already set, use it
	if options.value and options.value ~= '' then
		return options.value
	end
	return formatStatements( options )
end

return p