local p = {}

function toTable(metatable, removeempty)
	-- função não perfomática, apenas use quando
	-- for essencial acessar TODOS os parâmetros
	ret = {}
	for key, value in pairs(metatable) do
		if not ( removeempty and value == "" ) then
			ret[key] = value
		end
	end
	return ret
end

function pop(t,x)
	-- retorna t[x] da tabela
	-- e remove o elemento "x" da tabela
	ret = t[x]
	t[x] = nil
	return ret
end

function p.calltemplate(frame)
	
	tableargs = toTable(frame.args)
	
	template = pop(tableargs, 'template') or ""
	sep      = pop(tableargs, 'csv-sep') or ","
	args     = pop(tableargs, 'csv-args') or ""
	csvfirst = pop(tableargs, 'csv-args-primeiro') ~= "sim"
		--"true" é default, ou seja, os argumentos CSV são inclusos antes dos argumentos normais
	
	if csvfirst then
		pos = 1
	end
	-- else pos = nil
	
	split(args, sep, tableargs, pos)
	
	return frame:expandTemplate{ title = template, args = tableargs }
end

function p.join(frame)
	-- algo parecido com o string.join do Python
	tableargs = toTable(frame.args)
	
	sep  = pop(tableargs, 'sep') or mw.message.new( 'comma-separator' ):plain()
	last = pop(tableargs, 'último') or sep
	
	return mw.text.listToText(tableargs, sep, last)
end

function p.length(frame)
	return length(true,frame)
end

function p.lengthNum(frame)
	return length(false,frame)
end

function length(allparams, frame)
	local count = 0
	
	if allparams then
		-- itera usando next()
		-- considera todos os parâmetros
		iter, t, null = pairs(frame.args)
	else
		-- itera usando o índice até encontrar o primeiro "nil"
		-- considera apenas parâmetros numéricos em sequência
		iter, t, null = ipairs(frame.args)
	end
	
	for key in iter, t, null do
		count = count + 1
	end
	return count
end

function p.preprocess(frame)
	return frame:preprocess(frame.args[1] or "")	
end

function split(str, sep, t, pos)
	t = t or {}
	for x in str:gmatch("([^"..sep.."]+)") do
		table.insert(t, pos or #x+1, x)
		if pos then
			pos = pos + 1
		end
	end
	return t
end

return p