Mô đun:Category described in year

require('strict')
local conf = require( 'Module:Category described in year/conf' ) --configuration module
--======================================================================**
--                             Local functions                              
--======================================================================**
local function addOrd( i ) --12 -> 12th, etc.
	if tonumber(i) then
		local s = tostring(i)
		local  tens = string.match(s, '1%d$')
		local  ones = string.match(s,  '%d$')
		if     tens        then return s..
		elseif ones == '1' then return s..
		elseif ones == '2' then return s..
		elseif ones == '3' then return s..
		elseif ones ~= nil then return s..
		end
	end
	return 
end
local function isNilOrEmpty( thing )
	return (thing == nil or thing == )
end
local p = {}
--======================================================================**
--                            External function                             
--======================================================================**
function p.autodetect( frame )
	local currentTitle = mw.title.getCurrentTitle()
	local parentArg = frame:getParent().args1 --accept 1 unnamed category parameter if not in category namespace; required for testing/doc/etc. purposes
	local header = ' ' --header template(s), nav bar, and category description text; whitespace-initialized for convenience
	local nav = nil
	local portal = nil --for ...
	local commons = nil --for ...
	local wikispecies = nil --for ...
	local description = nil
	local toc = nil
	local categories = {}
	local trackingCategories = {
		1 = , --placeholder for 
		2 = , --placeholder for 
	}
	local outString = nil
	local bConfError = false
	
	--prelim namespace/title determination
	local currCat = nil
	local currQID = nil
	if currentTitle.namespace == 14 then --category namespace
		currCat = currentTitle.text --without namespace nor interwiki prefixes
		currQID = mw.wikibase.getEntityIdForCurrentPage()
	else
		if parentArg then
			currCat = mw.ustring.gsub(parentArg, 'Category:', )
			currQID = mw.wikibase.getEntityIdForTitle('Category:' .. currCat)
		else --currQID & currCat both nil
			if currentTitle.fullText ~= 'Template:Category described in year' then --ignore self...
				trackingCategories2 =  --missing a category parameter outside category namespace
			end
		end
	end
	
	--find commons & wikispecies link(s); produce  and/or  template(s)
	if currQID then
		local commonsLinks = {}
		local currEntity = mw.wikibase.getEntity(currQID)
		if currEntity then
			--check Commons category property (P373)
			local ccPropState = currEntity:getBestStatements('P373')1
			if ccPropState then
				local ccPropVal = ccPropState.mainsnak.datavalue.value
				if ccPropVal then
					commonsLinks#commonsLinks + 1 = 'Category:' .. mw.ustring.gsub(ccPropVal, 'Category:', )
				end
			end
			--check Commons gallery property (P935)
			local cgPropState = currEntity:getBestStatements('P935')1
			if cgPropState then
				local cgPropVal = cgPropState.mainsnak.datavalue.value
				if cgPropVal then
					commonsLinks#commonsLinks + 1 = cgPropVal
				end
			end
			--check "Other sites" sitelinks for Commons and/or Wikispecies
			local currSiteLinks = currEntity.sitelinks
			if currSiteLinks then
				local currCommonsWiki = currEntity.sitelinks.commonswiki
				if currCommonsWiki then
					local currCommonsWikiTitle = currEntity.sitelinks.commonswiki.title
					if currCommonsWikiTitle then
						commonsLinks#commonsLinks + 1 = currCommonsWikiTitle
					end
				end
				local currSpeciesWiki = currEntity.sitelinks.specieswiki
				if currSpeciesWiki then
					local currSpeciesWikiTitle = currSpeciesWiki.title
					if currSpeciesWikiTitle then
						wikispecies = frame:expandTemplate{ title = 'Wikispecies', args = { currSpeciesWikiTitle } }
					end
				end
			end
		end
		
		--produce  template(s) (ignore duplicates)
		if commonsLinks1 then --turn these into a loop if # of commons sources >= 4
			commons = frame:expandTemplate{ title = 'Commons', args = { commonsLinks1 } }
			if commonsLinks2 and
			   commonsLinks2 ~= commonsLinks1 then
				commons = commons .. frame:expandTemplate{ title = 'Commons', args = { commonsLinks2 } }
			end
			if commonsLinks3 and
			   commonsLinks3 ~= commonsLinks1 and 
			   commonsLinks3 ~= commonsLinks2 then
				commons = commons .. frame:expandTemplate{ title = 'Commons', args = { commonsLinks3 } }
			end
		end
	end --if currQID then
	
	--==================================================================**
	--                                 Main                                 
	--==================================================================**
	if currCat then
		
		--determine current/related/adjacent cats' properties/vars/etc.
		local currGroup = mw.ustring.match(currCat, '^(%w +) được mô tả') --Bacteria/Plants/etc.
		if isNilOrEmpty(currGroup) then currGroup = mw.ustring.match(currCat, '^(%w +) theo năm mô tả chính thức') end
		if confcurrGroup == nil then confcurrGroup = conf'Default' end --default to Default
		local currYDCF = nil --possible future values: year/decade/century/formal
		local currYear = mw.ustring.match(currCat, 'được mô tả năm (%d%d%d%d)$')
		local currDeca = mw.ustring.match(currCat, 'được mô tả thập niên (%d%d%d%d)$') --deprecated
		local currCent = mw.ustring.match(currCat, 'được mô tả thế kỷ (%d+)$')
		local currFrml = mw.ustring.match(currCat, 'theo năm mô tả (chính thức)$')
		local parentCent = nil --used with currYear
		local minYear = tonumber(confcurrGroup.minyear)
		if minYear == nil or 
		  (minYear and (minYear = 2000)) then
			minYear = 1758 --default to 1758 per ICZN Art. 5
		end
		if currYear then
			currYDCF = 'năm'
			if mw.ustring.match(currYear, '^%d%d00') then --1900 in 19th century
				parentCent = mw.ustring.match(currYear, '^%d%d')
			else --1901 in 20th century
				parentCent = 1 + mw.ustring.match(currYear, '^%d%d')
			end
		elseif currDeca then
			currYDCF = 'thập niên'
			bConfError = true
			trackingCategories2 =  --invalid decade-parent (deprecated)
		elseif currCent then
			currYDCF = 'thế kỷ'
		elseif currFrml then
			currYDCF = 'chính thức'
		else
			bConfError = true
			trackingCategories2 =  --invalid category name
		end
		
		--conf error checkng (missing keys)
		--Numeric sortkeys are unfortunately grouped together under "0-9".
		--Check phab T203355 (Magic word to force category number headings instead of 0-9).
		if bConfError == false then
			if confcurrGroup == nil then
				bConfError = true
				trackingCategories2 =  --group (Bacteria/Plants/etc.) key missing from conf
			elseif confcurrGroupcurrYDCF == nil then
				bConfError = true
				trackingCategories2 =  --year/century/formal key missing
			else
				if confcurrGroupcurrYDCF.description == nil then
					bConfError = true
					trackingCategories2 =  --description key missing
				end
				if confcurrGroupcurrYDCF.parent1 == nil then
					bConfError = true
					trackingCategories2 =  --parent key missing
				end
			end
		end
		
		if bConfError == false then
			--produce portal
			if currGroup == 'Đơn vị phân loại hóa thạch' or currGroup == 'Đơn vị bán phân loại' then
				portal = frame:expandTemplate{ title = 'Cổng thông tin', args = { 'Cổ sinh vật học' } }
			end
			
			--produce description, evaluate %variables%
			description = confcurrGroupcurrYDCF.description
			if mw.ustring.match(description, '%%year%%') then
				if currYear then description = mw.ustring.gsub(description, '%%year%%', currYear) --"2011"
				else description = mw.ustring.gsub(description, '%%year%%', 'năm này') end
			end
			if mw.ustring.match(description, '%%century%%') then
				if currCent then description = mw.ustring.gsub(description, '%%century%%', addOrd(currCent)) --"21st"
				else description = mw.ustring.gsub(description, '%%century%%', 'thế kỷ này') end
			end
			
			--produce toc
--  now provided via Template:Category described in year
--
			if mw.site.stats.pagesInCategory(currCat, 'pages') >= conf'tocmin' then --expensive
				local args = { numerals = 'no' }
				toc = frame:expandTemplate{ title = 'Category TOC', args = args }
			end
--
			--produce cats & navs
			local iparent = 1
			local parenti = 'parent' .. iparent
			local sortkeyi = 'sortkey' .. iparent
			while confcurrGroupcurrYDCFparenti do
				local parent = confcurrGroupcurrYDCFparenti
				local sortkey = confcurrGroupcurrYDCFsortkeyi
				
				--========================== Year ======================**
				if currYDCF == 'năm' then
					if nav == nil then
						local args = { min = minYear }
						if parentArg and currentTitle.namespace ~= 14 then
							args'testcase' = parentArg
						end
						nav = frame:expandTemplate{ title = 'Category series navigation', args = args }
					end
					if parent == 'thế kỷ' then
						if isNilOrEmpty(sortkey) then sortkey = currYear end --default to currYear
						categoriesiparent = 
					elseif parent == 'sinh học' then
						if isNilOrEmpty(sortkey) then sortkey =  --default to none
						else sortkey = '|'..sortkey end
						if tonumber(currYear) ', )
	end
	if toc then header = header ..  .. toc end
	header = mw.text.trim(header)
	header = mw.ustring.gsub(header, '^', )
	header = mw.ustring.gsub(header, '$', )
	
	--append header to outString
	if outString then outString = outString .. header
	else outString = header end
	
	--append cats to outString
	if currentTitle.namespace == 14 then --category namespace
		if table.maxn(categories) > 0 then outString = outString .. table.concat(categories) end
		outString = outString .. table.concat(trackingCategories)
	else
		if table.maxn(categories) > 0 then --might be 0 if there's an error before setting cats
			outString = outString ..  .. mw.ustring.gsub(table.concat(categories, ), '%%', ':')
		end
		outString = outString ..  .. mw.ustring.gsub(table.concat(trackingCategories, ), '%%', ':')
		outString = mw.ustring.gsub(outString, , ) --produced by empty () first/consecutive tracking cat/s
		outString = mw.ustring.gsub(outString, , ) --jic (use while loop if #trackingCategories >= 3 or 4)
	end
	
	return outString
end
return p