Documentation for this module may be created at Module:Databox/doc

local property_blacklist = {
    'P360', --is a list of
    'P4224', --category contains
    'P935', -- Commons gallery
    'P1472', -- Commons Creator page
    'P1612', -- Commons Institution page
    'P373', -- Commons category
    'P3722', -- Commons maps category
    'P1151', -- topic's main Wikimedia portal
    'P1424', -- topic's main template
    'P910', -- topic's main category
    'P1200', -- bodies of water basin category
    'P1792', -- category of associated people
    'P1464', -- category for people born here
    'P1465', -- category for people who died here
    'P1791', -- category of people buried here
    'P1740', -- category for films shot at this location
    'P2033', -- Category for pictures taken with camera
    'P2517', -- category for recipients of this award
    'P4195', -- category for employees of the organization
    'P1754', -- category related to list
    'P301', -- category's main topic
    'P971', -- category combines topics
    'P3876', -- category for alumni of educational institution
    'P8933', --category for the view from the item
	'P8989', --category for the view of the item
    'P1753', -- list related to category
    'P3921', -- Wikidata SPARQL query equivalent
    'P1204', -- Wikimedia portal's main topic
    'P1423', -- template's main topic
    'P1709', -- equivalent class
    'P3950', -- narrower external class
    'P2888', -- exact match
    'P1382', -- coincident with
    'P527', -- has part
    'P2670', -- has parts of the class
    'P3113', -- does not have part
    'P2737', -- union of
    'P2738', -- disjoint union of
    'P2445', -- metasubclass of
    'P1963', -- properties for this type
    'P3176', -- uses property
    'P1889', -- different from
    'P460', -- said to be the same as
    'P2959', -- permanent duplicated item
    'P2860', -- cites
    'P5125', -- wikimedia outline
    'P5008', -- on focus list of Wikimedia project
    'P2559', -- Wikidata usage instructions
    'P1343', -- described by source
    'P972', --  catalogu
    'P1282', -- OSM tag or key
    'P625', 'P276', 'P159', 'P3896', -- geo props
    'P31', 
    'P6104',
    'P487',
    'P8744', --economy of topic
	'P2633', --geography of topic
	'P7867', --category for maps
	'P8625', --bibliography
	'P1687', --Wikidata property
	'P131', --located in the administrative territorial entity
	'P1482', --Stack Exchange tag
	'P6186', --category for eponymous categories
	'P4316', --kinship equivalent in SPARQL at Wikidata
}

local web_properties = {
    'P856', --official website
    'P953', --full work available at URL
    'P973', --described at URL
    'P5282', --ground level 360 degree view Turanci
}

local infobox = require("Module:Infobox").infobox
local claim = require("Module:Wikidata").claim
local getLabel = require("Module:Wikidata").getLabel
local getParentValues = require("Module:Wikidata").getParentValues

function valuesToKeys(array)
	local result = {}
	for _, v in pairs(array) do
		result[v] = true
	end
	return result
end

function getDataProperties(item, properties)
	local property_blacklist_hash = valuesToKeys(property_blacklist)
	
    local data_properties = {}
    for _, property in pairs(properties) do
    	local datatype = item.claims[property][1].mainsnak.datatype
        if datatype ~= 'commonsMedia' and datatype ~= 'external-id' and datatype ~= 'quantity' and not property_blacklist_hash[property] and #item:getBestStatements(property) <= 5 then
            table.insert(data_properties, property)
		end
    end
    
    return data_properties
end

local function has_value(tab, val)
    for index, value in ipairs(tab) do
        if value == val then
            return true
        end
    end

    return false
end

local function isSet(var)
	return not (var == nil or (type(var) == 'string' and mw.text.trim(var) == ''))
end

local p = {}

function p.databox(frame)
    local args = frame:getParent().args
    local itemId = nil
    if args.item then
        itemId = args.item
    end
    local item = mw.wikibase.getEntity(itemId)
    
    if item == nil then
        mw.addWarning("Wikidata item not found")
        return ""
    end
    
    local dico = 
    {
		['abovestyle'] = 'background-color: #DADADA;',
		['headerstyle'] = 'background-color: #DADADA;',
		['above'] = "<span style=\"float:left;\">[[image:Wikidata.svg|20px|link=]]</span>"..(item:getLabel() or mw.title.getCurrentTitle().text),
		['image'] = claim({item=itemId, property='P18', formatting='[[File:$1|frameless|300px]]', list='false'}),
		['subheader'] = claim({item=itemId, property='P31'}),
	}
	
	local properties = mw.wikibase.orderProperties(item:getProperties());
    local data_properties = getDataProperties(item, properties)
    
    if #data_properties > 0 then
    	dico["header1"] = getLabel({'Q42848'})
    end
	
    for i, property in pairs(data_properties) do
    	local formatting = nil
    	if has_value(web_properties, property) then
    		formatting = "weblink"
    	end
    	
        dico["label"..i+1] = getLabel({property})
        dico["data"..i+1] = claim({item=itemId, property=property, formatting = formatting})
    end
    
    local lat_lon = frame:preprocess("{{GetLatLon|P625|P276|P159|item="..(itemId or '').."}}")
    
    local layer = nil
    if has_value(properties, 'P3896') then 
    	layer = claim({item=itemId, formatting="table", property="P3896", qualifier="P518", blacklist1= "Q94979808", rowformat = "$0", separator="###", editicon="no"})
    end
    
    local loc_map_image = nil
    if has_value(properties, 'P242') then 
    	loc_map_image = claim({item=itemId, formatting="table", property="P242", rowformat = "$0", editicon="no", list='false'})
    end
    
    local loc_maps = nil
    if isSet(lat_lon) or isSet(loc_map_image) then
    	loc_maps = frame:preprocess("{{Location maps|lat_lon="..(lat_lon or '').."|layer="..(layer or '').."|locator_map="..(loc_map_image or '').."}}")
    end
    
    local parents = nil
	if has_value(properties, 'P131') then 
    	parents = getParentValues({item=itemId, sorting="-1", separator="</tr>", rowformat = "<tr><td>'''$0'''</td><td>$1</td>"})
	end
    
    if isSet(loc_maps) or isSet(parents) then 
    	dico["header"..(#data_properties+2)] = getLabel({'Q17334923'})
    end
    
    dico["data"..(#data_properties+3)] = loc_maps
    dico["data"..(#data_properties+4)] = parents
    
    return infobox(dico)
end


return p