Module:Sandbox/AB-me/Racing table

local p = {}
local getArgs = require('Module:Arguments').getArgs

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	local eventsArg = mw.text.split(args['events'], ',')
	local participantsArg = mw.text.split(args['participants'], ',')
	local pointPositionsArg = mw.text.split(args['points'], ',') or {}
	local notesArg = mw.text.split(args['notes'], ',') or {}
	
	local events = {} -- contains event information (code, name)
	local participants = {} -- contains participant information (code, name, results, resultNotes, points, pointsTotal)
	local pointPositions = {} -- contains the distribution of points based on position
	local notes = {} -- contains information about distribution of points not based on position (code, adj, num)
    
    local stack = {}

	for i,v in ipairs(eventsArg) do events[i] = {code = v, name = args['event_' .. v]} end
	for i,v in ipairs(participantsArg) do participants[i] = {code = v, name = args['participant_' .. v], results = {}, resultNotes = {}, points = {}, pointsTotal = nil} end
	for i,v in ipairs(pointPositionsArg) do pointPositions[i] = tonumber(v) or 0 end
	for i,v in ipairs(notesArg) do
		local adj = true
		local num = 0
		local arg = args['notesPoints_' .. v]
		
		if (arg ~= null) then
			local startsWith = mw.ustring.sub(arg, 1, 1)
			if (startsWith ~= ' ' and startsWith ~= '-') then
				adj = false
			end
			
			num = tonumber(arg)
		end
		
        notes[i] = {code = v, adj = adj, num = tonumber(args['notesPoints_' .. v] or 0)}
	end
	
	-- Point handling and calculations
	for iEvents,vEvents in ipairs(events) do
		if (args['result_' .. vEvents['code']] ~= nil) then
			local resultSplit = mw.text.split(args['result_' .. vEvents['code']], ',') or nil
			
			local res = {}
			for i,v in ipairs(resultSplit) do res[v] = i end
			
			for iParticipants,vParticipants in ipairs(participants) do
                vParticipants['results'][iEvents] = res[vParticipants['code']]
                if (vParticipants['results'][iEvents] ~= nil) then
                    vParticipants['points'][iEvents] = pointPositions[res[vParticipants['code']]] or 0
                else
                    vParticipants['points'][iEvents] = nil
                end
            end
            
		end
    
        local spec = {}
        
        for iNotes,vNotes in ipairs(notes) do
            
            
            if (args['notes_' .. vEvents['code'] .. '_' .. vNotes['code']]) then
                local notesSplit = mw.text.split(args['notes_' .. vEvents['code'] .. '_' .. vNotes['code']], ',')
                
                for i,v in ipairs(notesSplit) do
                    if (spec[v] == nil) then spec[v] = {} end
                    table.insert(spec[v], vNotes)
                end
            end
        end

		for iParticipants,vParticipants in ipairs(participants) do
            vParticipants['resultNotes'][iEvents] = spec[vParticipants['code']]
        end

	end
	
	--Summation of points
	for iParticipants,vParticipants in ipairs(participants) do
        local tot = nil
        for i,v in pairs(vParticipants['points']) do
            if (v ~= nil) then
                tot = (tot or 0)   v
            end
        end
        vParticipants['pointsTotal'] = tot
	end
	
	--Writing table
	--local stack = {}
	
	table.insert(stack, '{| class="wikitable" style="font-size: 85%; vertical-align:top; text-align:center""\n')
	table.insert(stack, '!style="vertical-align:middle;"|<abbr title="Position">Pos</abbr>\n')
	table.insert(stack, '!style="vertical-align:middle;"|'.. (args['text_participant'] or 'Participant') .. '\n')
	
	for i,v in ipairs(events) do
		table.insert(stack, '!' .. (v['name'] or v['code'] or i) .. '\n')
	end
	
	table.insert(stack, '!style="vertical-align:middle"|Points\n')
	
	for i,v in ipairs(participants) do
        table.insert(stack, '|-\n')
        
        table.insert(stack, '!')
        
        if (v['pointsTotal'] ~= nil) then
            table.insert(stack, i)
        else
            table.insert(stack, '&ndash;')
        end
        
        table.insert(stack, '\n')

        
		table.insert(stack, '|style="text-align:left;"|' .. (v['name'] or v['code']) .. '\n')
		
		for j,w in ipairs(events) do
			table.insert(stack, '|')
            table.insert(stack, v['results'][j])

            if (v['resultNotes'] ~= nil and v['resultNotes'][j] ~= nil) then
            	local firstNote = true
                for k,x in ipairs(v['resultNotes'][j]) do
                	if (firstNote and v['results'][j] == nil) then
                		table.insert(stack, x['code'])
            		else
            			table.insert(stack, '<span style="margin:0 0.1em 0 0.1em;"><sup>' .. x['code'] .. '</sup></span>')
                	end
                    firstNote = false
                end
            end

			table.insert(stack, '\n')
		end
		
		table.insert(stack, '!' .. (v['pointsTotal'] or '&ndash;') .. '\n')
	end
	
	table.insert(stack, '|}')
	
	return table.concat(stack)
end

	
return p;