Module:Shop availability

From Coral Island Wiki
Jump to navigation Jump to search

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

local p = {}
local Parse = require('Module:Parser').getTemplateArgs
local Slib = require('Module:Shop')
local lib = require('Module:Feature')
local Icon = require('Module:Icon')._main

local Pages = {}
local display = {}

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		parentFirst=true,
		wrappers = {'Template:Shop availability'}
	})
	local item = args[1] or mw.title.getCurrentTitle().rootText
	if lib.isNotEmpty(frame.args.pages) then
		for page in string.gmatch(frame.args.pages, '(.-)%$%$%$') do
			local data = Parse(page, { only='Shop' } )
			local Pdata
			if type(data[1]) == 'table' then
				for num, call in pairs(data) do
					Pdata = p.ParseCall(call, item)
					if Pdata then
						break
					end
				end
			else
				Pdata = p.ParseCall(data, item)
			end
			if Pdata then
				Pdata.PAGENAME = page
				table.insert(Pages, Pdata)
			end
		end
		if args.itemcol then display['ITEM_NAME'] = true end
		return p._main(args, frame)
	else
		return 'No shop sells this item.'
	end
end

function p._main(args, frame)
	local temp_cols = { 'Price range', 'Season', 'Town rank', 'Requirement' }
	local cols = {}
	local _table = mw.html.create('table'):addClass('fandom-table article-table sortable')
	
	-- header row
	local tr = _table:tag('tr')
	tr:tag('th'):wikitext('Location')
	if display['ITEM_NAME'] then tr:tag('th'):wikitext('Item') end
	tr:tag('th'):wikitext('Price')
	for _, col in ipairs(temp_cols) do
		if display[col] then
			table.insert(cols, col)
			tr:tag('th'):wikitext(col)
		end
	end
	
	-- rest of table
	for _, page in ipairs(Pages) do
		local tr = _table:tag('tr')
		tr:tag('td'):attr('rowspan', #page):wikitext('[[', page.PAGENAME, ']]')
		for i, call in pairs(page) do
			if tonumber(i) ~= nil then
				-- mw.logObject(call) --debug
				if i>1 then tr = _table:tag('tr') end
				if display['ITEM_NAME'] then tr:tag('td'):node(Icon{call.ITEM_NAME}) end
				local td = tr:tag('td')
				if call.Price and tonumber(call.Price) ~= nil then
					td
						:node(Icon{
								'Coin',
								call.Price,
								size = '16',
								notext = 1,
								nolink = 1
							})
						:attr('data-sort-value', call.Price)
				elseif call.Price and call.Price:find('%*%d') then
					local items = lib.split(call.Price, ',')
					list = td:tag('span'):addClass('icon-list')
					for _, item in ipairs(items) do
						local name, amount = string.match(item, '^(.-)*(.-)$')
						if name == 'Coin' then td:attr('data-sort-value', amount) end
						list:node(Icon{
							name,
							amount,
							size = (name=='Coin' and '16' or '20'),
							notext = (name=='Coin' and '1' or nil),
							nolink = (name=='Coin' and '1' or nil)
						})
					end
				end
				for _, col in ipairs(cols) do
					local td = tr:tag('td')
					if call[col] then
						td:wikitext(call[col])
					end
				end
			end
		end
	end
	-- mw.logObject(_table) --debug
	return frame:preprocess(tostring(_table))
end

function p.ParseCall(call_data, items)
	local delim = call_data.delim or ';'
	local default = {}
	table.insert(default, (call_data.firstcol or 'Item'))
	table.insert(default, (call_data.secondcol or 'Price'))
	local types = Slib.HashTypes(nil, call_data.cols, default)
	local ret = {}
	local targets = {}
	local list = lib.split(items, ';')
	if #list > 1 then display['ITEM_NAME'] = true end
	for _, item in ipairs(list) do
		targets[string.lower(item)] = true
	end

	for row_num, row in lib.spairs(call_data, function(tVal, a, b) return tostring(a)<tostring(b) end) do
		if tonumber(row_num) ~= nil then
			local row_cols = lib.split(row, delim)
			local row_data = Slib.splitParams(row_cols[1], '$')
			local item = row_data.item or row_data[1]
			if targets[string.lower(item)] then
				local cols_data = lib.split(row, delim)
				local params = {['ITEM_NAME'] = item}
				for col_num, col_value in ipairs(cols_data) do
					if col_num > 1 and types[col_num] and lib.isNotEmpty(col_value) then
						display[types[col_num]] = true
						params[types[col_num]] = col_value
					end
				end
				table.insert(ret, params)
			end
		end
	end
	if next(ret) then
		return ret
	end
end

return p