Genshin Impact Wiki
Genshin Impact Wiki
Documentation icon Module documentation

This module implements {{Talent Table}}.

local p = {}
local lib = require('Module:Feature')
local Parse = require('Module:Parser').getTemplateArgs
local Exists = require('Module:Exists').checkExists
local section_order = {
	'Gameplay Notes',
	'Advanced Properties',
	'Attribute Scaling',
	'Preview'
}

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		parentOnly = false,
	})
	if args.pages then
		local data = p.parsePages(args.pages)
		return p._main(data, frame)
	else
		return 'No data available on this character\'s talents.'
	end
end

function p._main(ALLdata, frame)
	local category = mw.html.create()
	local outContainer = mw.html.create('div')
		:addClass('talent-table-container')
	local out = outContainer:tag('table')
		:addClass('wikitable talent-table')
		:css{ ['text-align'] = 'center' }
			
	-- table headers
	local tr = out:tag('tr')
	tr:tag('th'):attr('width', '45px'):wikitext('Icon')
	tr:tag('th'):attr('width', '50%'):wikitext('Name')
	tr:tag('th'):attr('width', '50%'):wikitext('Type')
	
	--table body
	for _, data in ipairs(ALLdata) do
		if next(data) ~= nil then
			-- type data row
			local infobox = data.INFOBOX
			local tr = out:tag('tr')
				-- talent image
				local td = tr:tag('td')
				local filename = lib.ternary( lib.isNotEmpty(infobox.image), infobox.image, 'Talent ' .. data.PAGENAME .. '.png')
				if not Exists('File:' .. filename) then filename = 'Unknown.png' end
				td:wikitext('[[File:', filename,'|link=', data.PAGENAME,'|x45px]]')
				
				--talent name
				tr:tag('td'):wikitext('[[', data.PAGENAME, '|', lib.ternary(lib.isNotEmpty(infobox.title), infobox.title, data.PAGENAME), ']]')
				
				--talent type
				local td = tr:tag('td')
				if infobox['type'] == 'Passive' then
					td:wikitext('[[Passive_Talent#Miscellaneous|Passive]]')
				elseif lib.isNotEmpty(infobox['type']) then
					td:wikitext('[[', infobox['type'], ']]')
				end
			
			-- data row
			local td = out:tag('tr'):tag('td'):attr('colspan', 3):css{ ['text-align'] = 'left' }
			if lib.isNotEmpty(infobox.info) then
				td:wikitext(frame:preprocess(infobox.info))
			end
			local function Collapsible(content, display)
				local coll = 
				mw.html.create('div')
			end
			
			--add collapsible for wanted sections
			for _, section in ipairs(section_order) do
				if data[section] then
					td:newline()
					td
					:tag('div')
						:addClass('giw-collapsible mw-collapsible mw-collapsed')
						:attr('data-expandtext', 'â–¼' .. section .. 'â–¼')
						:attr('data-collapsetext', 'â–²' .. section .. 'â–²')
						:tag('div')
							:addClass('mw-collapsible-content')
							:css{ ['display'] = 'none' }
							:newline()
							:wikitext(frame:preprocess(data[section]))
							:newline()
				end
			end
			
			-- add scaling categories
			local i = '1'
			while lib.isNotEmpty(infobox['scale_att' .. i]) do
				category:wikitext('[[Category:', infobox['scale_att' .. i], ' Scaling Talent Characters]]')
				i = tostring(tonumber(i)+1)
			end
		end
	end
	
	--add categories
	outContainer:node(require('Module:Namespace detect').main{main=category})
	
	return outContainer
end

function p.parsePages(PAGES, frame)
	local data = {}
	for page in lib.gsplit(PAGES, ';;;') do
		local page_data = Parse(page, { pageContent=true })
		if page_data['Talent Infobox'] and page_data['Talent Infobox']['type'] then
			local ret = {
				TALENT_TYPE = page_data['Talent Infobox']['type'],
				INFOBOX = page_data['Talent Infobox'],
				PAGENAME = page
			}
			-- mw.logObject(page_data, 'Page data for "' .. page .. '": ') --debug
			local toSplit = page_data.PAGECONTENT
			if lib.isNotEmpty(toSplit) then
				local intro, post_intro = string.match(toSplit, '^(.-)\s*\n(==[^=].-)$')
				toSplit = post_intro
				while lib.isNotEmpty(toSplit) do
					local header, value, rest = string.match(toSplit, '^==%s*(.-)%s*==\n\s*(.-)\s*\n(==[^=].-)$')
					if header then
						toSplit = rest
						if lib.inArray(section_order, header) and not ret[header] then
							ret[header] = value
						end
					else
						local header, value = string.match(toSplit, '^==%s*(.-)%s*==\n\s*(.-)$')
						if header then
							if lib.inArray(section_order, header) and not ret[header] then
								ret[header] = value
							end
						end
						toSplit = nil
					end
				end
				-- mw.logObject(page_sections, page .. '\'s sections: ')
			end
			table.insert(data, ret)
		end
	end
	
	-- mw.logObject(data, 'Parsed data: ') --debug
	
	return data
end

return p