Documentation icon Moduldokumentation[opret]
local d={}
local t={}

edit_message = mw.message.new('vector-view-edit'):plain()

--Adds a pen with a link to the relevant wikidataitem 
function txtEditPen(iEntity,iProperty)
	return '<sup class="noprint Inline-Template">[[File:Arbcom_ru_editing.svg|' 
	                   	.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/' 
	                   	.. iEntity .. '#' .. iProperty .. ']]</sup>'
end

function txtaddWikiData(txtPropertyName,txtName,txtSupportText)
	return txtBeginning .. txtPropertyName .. txtSelect .. txtName .. txtSupportText .. txtSave
end

function tblProcessIndividualReference(thisref,idMainEntity,frame)
	local refparts=thisref.snaks
	table.sort(refparts)

	local isok=1 --is regarded as a source (imported from other wikipedia is not consieder a source)
	local bKeyProcessed=false
	local txtUrlLocal=''

	local templateFillArray={}
	templateFillArray['error'] = false -- No error to start with :-)
	for key, value in orderedPairs( refparts) do
		bKeyProcessed=false;
		if (key=='P1065') then
			templateFillArray[txtArchiveUrl] = value[1].datavalue.value
			bKeyProcessed=true;
		end
 		if (key=='P123') then 
			iPublisher=readQualifier(value[1],'id')
			templateFillArray[txtPublisher]='[[' ..  getLabelByEntity( iPublisher ) .. ']]'
			bKeyProcessed=true;
			end
		if (key=='P143') then 
			txt=txtFromADifferentLanguageVersion
			isok=0
			bKeyProcessed=true;
			end
		if (key=='P1476') then 
			txtTitleLocal=readQualifier(value[1],'text')
			if not (isP248) then
				templateFillArray[txtLanguage]= readQualifier(value[1],'language')
				templateFillArray[txtTitle] = string.gsub(txtTitleLocal,"|"," - ")
				end
			bKeyProcessed=true;
			end
		if (key=='P1810') then 
			txtTitleLocal=value[1].datavalue.value
			templateFillArray[txtTitle] = string.gsub(txtTitleLocal,"|"," - ")
			bKeyProcessed=true;
			end
		if (key=='P2093') then
			templateFillArray[ txtAuthor] = value[1].datavalue.value
			bKeyProcessed=true;
		end
		if (key=='P248') then 
			txtSource=readQualifier(value[1],'id')
			templateFillArray=processDatabaseSource(frame,templateFillArray,idMainEntity,txtSource)
			bKeyProcessed=true
			end
		if (key=='P2960') then
			templateFillArray[txtArchiveDate] = string.sub(readQualifier(value[1],'time'),2,11) 
			bKeyProcessed=true;
		end
		if (key=='P304') then
			templateFillArray[ txtPage] = value[1].datavalue.value
			bKeyProcessed=true;
		end
		if	(key=='P407') then
			-- Do not process (take language from P1476 instead)
			bKeyProcessed=true
			end
		if (key=='P4656') then 
--			txt="Från språkversion"
			isok=0
			bKeyProcessed=true
			end
		if (key=='P577') then 
			templateFillArray[txtDateTemplate] = string.sub(readQualifier(value[1],'time'),2,11) 
			bKeyProcessed=true
			end
		if (key=='P813') then 
			templateFillArray[txtAccessdate] = string.sub(readQualifier(value[1],'time'),2,11)
			bKeyProcessed=true
			end
		if (key=='P854') then 
			txtUrlLocal=string.gsub(value[1].datavalue.value,"|","{{!}}")
			templateFillArray[txtUrl] = txtUrlLocal
			bKeyProcessed=true
			end
		if (key=='P98') then 
			iAuthor=readQualifier(value[1],'id')
			templateFillArray[txtAuthor]='[[' ..  getLabelByEntity( iAuthor ) .. ']]'
			bKeyProcessed=true
			end
		if (not (bKeyProcessed)) then
			keyentity=mw.wikibase.getEntity( key )
			local subjectobject=keyentity:getBestStatements( 'P1629')
			if (next(subjectobject)) then
				iSubjectobject=read(subjectobject[1],'id')
				templateFillArray[txtTitle]=getLabelByEntity( iSubjectobject )
				urlsnak=keyentity:getBestStatements( 'P1630' )
				if (next(urlsnak)) then
					url=urlsnak[1].mainsnak.datavalue.value
					thisid=value[1].datavalue.value
					templateFillArray[txtUrl] = string.gsub(url,"$1",thisid)
					else
					templateFillArray[txtUrl] = 'No Url!'
					end

--				templateFillArray=processDatabaseSource(frame,templateFillArray,idMainEntity,txtSource)
				else
	 			templateFillArray[txtTitle] = keyentity:getLabel()
				answers=keyentity:getBestStatements( 'P1630' )
				url=answers[1].mainsnak.datavalue.value
				templateFillArray[txtUrl] = string.gsub(url,"$1",value[1].datavalue.value)
				end
			end
	end
	txt=''
	if (templateFillArray['error'] == false) then
		if ((templateFillArray[txtTitle] ~= nil)) then
			if (templateFillArray[txtUrl] ~= nil) then
				templateFillArray['error']=nil
				txt = frame:expandTemplate{ title = txtCiteweb , args =templateFillArray}
				else
				txt=templateFillArray[txtTitle]
				end
			else
			if (templateFillArray[txtUrl] ~= nil) then
				txt=txtUrlLocal
				else 
				txt='Ingen titel eller url angiven i källan'
				end
				end
		else
			txt='<span style="color:#ff0000">' .. templateFillArray['error_text'] .. '</span>'
		end
	return isok,txt 
end

function processDatabaseSource(frame,templateFillArray,idMainEntity,txtSource)
	StatedInentity=mw.wikibase.getEntity( txtSource )
	txtLabelStatedIn=StatedInentity:getLabel()
	databaseproperty=StatedInentity:getBestStatements( 'P1687')
	local bHasDatabase=false
    local bFoundInDatabase=false
    local idDatabase=nil
    for keyDatabase, valueDatabase in pairs( databaseproperty ) do
    	bHasDatabase=true
		idDatabase=read(valueDatabase,'id')
		if not (idDatabase==nil) then
			databaseentity=mw.wikibase.getEntity( idDatabase )
			mainentity=mw.wikibase.getEntity( idMainEntity )
			mainsnak=mainentity:getBestStatements(idDatabase )
			if (next(mainsnak)) then
				bFoundInDatabase=true
				thisid=mainsnak[1].mainsnak.datavalue.value
				
				urlsnak=databaseentity:getBestStatements( 'P1630' )
				url=urlsnak[1].mainsnak.datavalue.value
				templateFillArray[txtUrl] = string.gsub(url,"$1",thisid)

				if (templateFillArray[txtTitle]~=nil) then
					templateFillArray[txtTitle] = txtLabelStatedIn .. ': ' .. templateFillArray[txtTitle]
					else
					templateFillArray[txtTitle] = txtLabelStatedIn
					end
--				else
				break
				end
			end
    end
    if ((bHasDatabase==true) and (bFoundInDatabase==false)) then
		templateFillArray['error'] = true
		templateFillArray['error_text']=txtNoDataBaseId .. frame:expandTemplate{title="P", args={idDatabase}}
    end
	if (bHasDatabase==false) then
		templateFillArray[txtTitle] = txtLabelStatedIn 
		end
	return templateFillArray
end

function tblProcessAllRefsForItemWD(frame,tblReferences,idEntity,idProperty)
local tmpResult={}
iHasSource=0;
if (tblReferences) then
	for keyRef, valueRef in pairs(tblReferences) do
		local isok,refparts=tblProcessIndividualReference(valueRef,idEntity,frame)
		if (isok==1) then
			iHasSource=1;
			p.iRefcounter=p.iRefcounter+1
			bNotInTable=true
			iIdInTable=k
			if (frame['id']) then
				txtFrameIdentifier=frame['id'] .. frame:getTitle()
				else
				txtFrameIdentifier=frame:getTitle()
				end
		    if d[refparts]~=nil then
		    	bNotInTable=false
		    	result={name='wikidatabox'..txtFrameIdentifier .. '_' .. d[refparts], content=refparts}
			    else
		    	result={name='wikidatabox'..txtFrameIdentifier .. '_' .. p.iRefcounter, content=refparts}
				d[refparts]=p.iRefcounter
			    end
		    table.insert(tmpResult,result)
		    end
		end
		if (iHasSource==0) then
			tmpResult=frame:expandTemplate{ title = txtSourceNeededWDTemplate,args = {objektid=idEntity,egenskapsid=idProperty}}
			end
		else
		tmpResult=frame:expandTemplate{ title = txtSourceNeededWDTemplate,args = {objektid=idEntity,egenskapsid=idProperty}}
		end
	return iHasSource,tmpResult
end

function txtUnpackReference(frame,iHasSource,tbl)
	if (iHasSource==1) then
		local txt=''
	    for key, tblrow in pairs( tbl ) do
	    	txt=txt..frame:extensionTag("ref", tblrow.content,{ name = tblrow.name}) 
	    	end
		return  txt
		else
		return tbl
		end
end

--Returns a wikilink to the connect page if there is one. Otherwise create to the a page with the name of the label
function txtWikilink(id,year)
	-- Get entity
--	local entityThis=mw.wikibase.getEntity(id) 	
	-- Read label (for specific year if relevant)
	local txtLabel
	local txtLabelThis=mw.wikibase.getLabel( id )
	if (year==nil) then
		txtLabel=txtLabelThis
		else
		local entityThis=mw.wikibase.getEntity(id) 	
		txtLabel=getLabelFromEntity(entityThis,year)
	end
	-- Get site link
	txtSitelink=mw.wikibase.getSitelink(id)
	-- If site link exists - use it
	if (txtSitelink) then
		return '[[' .. txtSitelink .. '|' .. txtLabel .. ']]'
		else
		-- if there is no site link, check if the item (organisation) is part of another one (either as 'part of' or 'mother organisation')
		-- if so use it
		local entityThis=mw.wikibase.getEntity(id) 	
		local claimsPartOf = entityThis:getAllStatements( 'P361' ) -- part of
	    if (claimsPartOf[1]) then	
			local iPartof=read(claimsPartOf[1],'id')
			return txtWikilink(iPartof,year)
		else
			local claimsPartOf2 = entityThis:getAllStatements( 'P749' ) -- mother organisation
		    if (claimsPartOf2[1]) then	
				local iPartof2=read(claimsPartOf2[1],'id')
				return txtWikilink(iPartof2,year)
			else
			-- If no site link at the item or any parent, consider using the label				
			if (txtLabel) then
				idThatLabel=mw.wikibase.getEntityIdForTitle(txtLabel)
				if (idThatLabel) then
					return txtLabel
					else
					if (txtLabelThis==nil) then
							return '[[' .. txtLabel .. ']]'
						else
							return '[[' .. txtLabelThis .. '|' .. txtLabel .. ']]'
						end
					end
				else
				return '('..txtMissing..')<!--'..id..'-->'					-- The commented id can be used by functions to, for example provide informatation on the entity that misses a label
				end
		    end
	    end
	end
end

--Returns a wikilink to the connect page if there is one. Otherwise create to the a page with the name of the label
--Does not try to use the label as a sitelink if there is no sitelink
function txtWikilinkWOsitelink(id,year)
	-- Get entity
	entityThis=mw.wikibase.getEntity(id) 	
	-- Read label (for specific year if relevant)
	local txtLabel
	local txtLabelThis=getLabelByEntity(id)
	if (year==nil) then
		txtLabel=txtLabelThis
		else
		txtLabel=getLabelFromEntity(entityThis,year)
	end
	-- Get site link
	txtSitelink=mw.wikibase.getSitelink(id)
	-- If site link exists - use it
	if (txtSitelink) then
		return '[[' .. txtSitelink .. '|' .. txtLabel .. ']]'
		else
		-- if there is no site link, check if the item (organisation) is part of another one (either as 'part of' or 'mother organisation')
		-- if so use it
		local claimsPartOf = entityThis:getAllStatements( 'P361' ) -- part of
	    if (claimsPartOf[1]) then	
			local iPartof=read(claimsPartOf[1],'id')
			return txtWikilink(iPartof,year)
		else
			local claimsPartOf2 = entityThis:getAllStatements( 'P749' ) -- mother organisation
		    if (claimsPartOf2[1]) then	
				local iPartof2=read(claimsPartOf2[1],'id')
				return txtWikilink(iPartof2,year)
			else
			-- If no site link at the item or any parent, consider using the label				
			if (txtLabel) then
--				idThatLabel=mw.wikibase.getEntityIdForTitle(txtLabel)
--				if (idThatLabel) then
					return txtLabel
--					else
--					if (txtLabelThis==nil) then
--							return '[[' .. txtLabel .. ']]'
--						else
--							return '[[' .. txtLabelThis .. '|' .. txtLabel .. ']]'
--						end
--					end
				else
				return '('..txtMissing..')<!--'..id..'-->'					-- The commented id can be used by functions to, for example provide informatation on the entity that misses a label
				end
		    end
	    end
	end
end

function emptyifNil(data)
	if (data) then
		return data
		else
		return ''
	end
end

function getLabelByEntity( id)
	return mw.wikibase.getLabel(id, txtLanguageCode )
end

function getLabelFromEntity( entity, year )
	if (year==nil) then
		return entity:getLabel( txtLanguageCode ) 
		else 
		--If available use P1448 (official name)
		local bFoundName,txtName=getLabelFromNameProperty(entity,'P1448',year )
		if (not(bFoundName)) then
			--If P1448 not available try P2561 (name)
			bFoundName,txtName=getLabelFromNameProperty(entity,'P2561',year )
		end
		if (bFoundName) then
			return txtName
			else
				return entity:getLabel( txtLanguageCode )
			end	
		end
end

function getLabelFromNameProperty(entity, iProperty,year )
	local claims = entity:getBestStatements(iProperty) -- If the club have had many names, loop through to find the one that was used when the player played at the club
	if (next(claims)) then
		-- Use label as default (if nothing is found that match year-wise)
		txtName=entity:getLabel( txtLanguageCode )
		-- Loop through names
	    for key, value in pairs( claims ) do
			yearfrom,yearto,datefrom,dateto =  years(value) 
    		lng=read(value,'language')
	    	if ((year >= yearfrom and year <= yearto) or (yearto=='' and year >= yearfrom)) and (not(lang_denylist[lng]==true)) then
	    		if (lng==txtLocalLanguage) then
		    		txtName=read(value,'text')
		    		if (txtName==nil) then
		    			txtName=txtNotLocalLanguage
		    			else --If name exists in local language return straight away, do not continue looping
		    			return true,txtName
			    		end
		    		else --set name for possible later return, but keep looping
		    		txtName=read(value,'text') 
	    			end
	    		end
	    	end
	--if name property (P1448 or P2561) is set then set name if one was found, otherwise write an error message
	return true,txtName
	else
	--if property was not set just use usual name
	return false,nil
	end
end
	

function readFirstStatement(entityid,txtProperty)
	statements=mw.wikibase.getBestStatements(entityid,txtProperty)
	if not(next(statements)==nil) then
		if not(statements[1]==nil) then
			qid=read(statements[1],'id')
			if not (qid==nil) then
				return mw.wikibase.getLabel(qid)
				end
			end
		end
	return nil
	end

--Plocka bort när ersatt av readFirstStatement
function getOneValue(entity,txtProperty)
	statements=entity:getBestStatements( txtProperty)
	if not(next(statements)==nil) then
		if not(statements[1]==nil) then
			qid=read(statements[1],'id')
			if not (qid==nil) then
				return mw.wikibase.getLabel(qid)
				end
			end
		end
	return nil
	end

function getOneEntityId(entity,txtProperty)
	statements=entity:getBestStatements( txtProperty)
	if next(statements)==nil then
		return nil
		else
		return read(statements[1],'id')
		end
	end

function getProperty(value,txtPropertyId)
	if value['qualifiers'] and  value['qualifiers'][txtPropertyId] then
			txtValue=emptyifNil(mw.wikibase.renderSnak(value['qualifiers'][txtPropertyId][1]))
		else
			txtValue=nil
		end
	return txtValue
end

function getPropertyId(value,txtPropertyId)
	if value then
		if value['qualifiers'] then
			if value['qualifiers'][txtPropertyId] then
				txtSnaktype=value['qualifiers'][txtPropertyId][1].snaktype
				if (txtSnaktype=="value") then
					txtValue=value['qualifiers'][txtPropertyId][1].datavalue.value.id
					else
					txtValue="Not Implemented"
					end
				else
				txtValue=nil
			end
			else
				txtValue=nil
		end	
	else 
		return nil
		end
	return txtValue
end


--Read a value of a property
function read(data,type)
	if (data) then
		if (data['mainsnak']) then
			return readQualifier(data['mainsnak'],type)
			else
			return nil
		end
		else
		return nil
		end
end

--Read a value of a qualifier
function readQualifier(data,type)
	if (data['datavalue']) then
		return data['datavalue']['value'][type]
		else
		return nil
		end
end

-- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field
-- use these as the second parameter and this function instead of the built-in "pairs" function
-- to iterate over all qualifiers and snaks in the intended order.
local function orderedpairs(array, order)
	if not order then return pairs(array) end

	-- return iterator function
	local i = 0
	return function()
		i = i + 1
		if order[i] then
			return order[i], array[order[i]]
		end
	end
end

function __genOrderedIndex( t )
    local orderedIndex = {}
    for key in pairs(t) do
        table.insert( orderedIndex, key )
    end
    table.sort( orderedIndex )
    return orderedIndex
end

function orderedNext(t, state)
    -- Equivalent of the next function, but returns the keys in the alphabetic
    -- order. We use a temporary ordered key table that is stored in the
    -- table being iterated.

    local key = nil
    --print("orderedNext: state = "..tostring(state) )
    if state == nil then
        -- the first time, generate the index
        t.__orderedIndex = __genOrderedIndex( t )
        key = t.__orderedIndex[1]
    else
        -- fetch the next value
        for i = 1,table.getn(t.__orderedIndex) do
            if t.__orderedIndex[i] == state then
                key = t.__orderedIndex[i+1]
            end
        end
    end

    if key then
        return key, t[key]
    end

    -- no more value to return, cleanup
    t.__orderedIndex = nil
    return
end

function orderedPairs(t)
    -- Equivalent of the pairs() function on tables. Allows to iterate
    -- in order
    return orderedNext, t, nil
end

-- Funktion från https://stackoverflow.com/questions/41942289/display-contents-of-tables-in-lua
function tprint (tbl, indent)
  if not indent then indent = 0 end
  local toprint = string.rep(" ", indent) .. "{\r\n"
  indent = indent + 2 
  for k, v in pairs(tbl) do
    toprint = toprint .. string.rep(" ", indent)
    if (type(k) == "number") then
      toprint = toprint .. "[" .. k .. "] = "
    elseif (type(k) == "string") then
      toprint = toprint  .. k ..  "= "   
    end
    if (type(v) == "number") then
      toprint = toprint .. v .. ",\r\n"
    elseif (type(v) == "string") then
      toprint = toprint .. "\"" .. v .. "\",\r\n"
    elseif (type(v) == "table") then
      toprint = toprint .. tprint(v, indent + 2) .. ",\r\n"
    else
      toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n"
    end
  end
  toprint = toprint .. string.rep(" ", indent-2) .. "}"
  return toprint
end