-- This module implements {{WritingCredits}}.

--------------------------------------------------------------------------------
-- WritingCredits class
-- The main class.
--------------------------------------------------------------------------------

local WritingCredits = {}

function WritingCredits.splitTable(tab)
	-- Split comma-separated values by letter/number
	local t = {}
	for v in string.gmatch(tab, "[%w%d]+") do
		t[#t+1] = v
	end
	return t
end

function WritingCredits.hasValue(tab, val)
    -- Check for value within table
	for k, v in ipairs(tab) do
        if v == val then
            return true
        end
    end
    return false
end

function WritingCredits.new(frame, args)
	args = args or {}
	local categories = ""
	
	-- Default order: writer, story, teleplay, storyboard, extras
	local defaultOrder = "w,s,t,sb,ex1,ex2,ex3"
	if args.tfirst then
		-- Teleplay before story (legacy support, will deprecate)
		defaultOrder = "t,w,s,sb,ex1,ex2,ex3"
	end
	local defaultOrder_split = WritingCredits.splitTable(defaultOrder)
	local givenOrder = args.order or ""
	local givenOrder_split = WritingCredits.splitTable(givenOrder)
	
	-- Order of parameters: any provided by template call in their order, then any undeclared in their default order
	for k, v in ipairs(defaultOrder_split) do
		if WritingCredits.hasValue(givenOrder_split, v) == false then
			table.insert(givenOrder_split, v)
		end
	end
	
	-- Default or custom labels
	local labels = {}
	local extraDefault = "Additional credits"
	labels['w'] = args['wlabel'] or "Written by"
	labels['s'] = args['slabel'] or "Story by"
	labels['t'] = args['tlabel'] or "Teleplay by"
	labels['sb'] = args['sblabel'] or "Storyboarded by"
	labels['ex1'] = args['ex1label'] or extraDefault
	labels['ex2'] = args['ex2label'] or extraDefault
	labels['ex3'] = args['ex3label'] or extraDefault
	
	-- Format labels and values
	local redundantLabel = false
	local writingCredits = args[1] or ""
	
	for _num, para in ipairs(givenOrder_split) do
		if args[para] then
			writingCredits = writingCredits .. (writingCredits ~= "" and "<br />" or "") .. ("<i>" .. labels[para] .. "</i>&hairsp;: " .. args[para])
			
			-- Redundant label check; e.g. |slabel=Written by |s=John Doe (this should just be |w=John Doe)
			for l_para, l_label in pairs(labels) do
				-- e.g.: sb ~= t (and) labels[sb] == labels[t] (and) labels[sb] ~= extraDefault
				if l_para ~= para and labels[l_para] == labels[para] and l_label ~= extraDefault then
					redundantLabel = true
				end
			end
		end
	end
	
	local title = mw.title.getCurrentTitle()
	if title.namespace == 0 and redundantLabel then
		categories = categories .. "[[Category:Pages using Template:WritingCredits with redundant labels]]"
	end
	
	return writingCredits .. categories
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
		wrappers = 'Template:WritingCredits'
	})
	return WritingCredits.new(frame, args)
end

return p