Module:Progress bar

require('strict')

local p = {} --p stands for package

local getArgs = require('Module:Arguments').getArgs
local make_style_string = require('Module:Optional style').make_style_string
local yesno = require('Module:Yesno')
local error_message = require('Module:Error')['error']

--[=[
Construct a progress bar
]=]
function p._progress_bar(args)
	-- args
	local statuses = {
		['total'] = args.total or 0,
		['validated'] = args.validated or 0,
		['proofread'] = args.proofread or 0,
		['problematic'] = args.problematic or 0,
		['not_proofread'] = args.not_proofread or args['not proofread'] or args['not-proofread'] or 0,
		['notext'] = args.notext or 0
	}
	
	for k, v in pairs(statuses) do
		if v and not tonumber(v) then
			return error_message({['message'] = 'Expression error: ' .. k .. ' = ' .. v .. ' is not a number.'})
		end
		statuses[k] = tonumber(v) or 0
		if statuses[k] < 0 then
			return error_message({['message'] = 'Expression error: ' .. k .. ' = ' .. statuses[k] .. ' < 0.'})
		end
		if statuses[k] > statuses.total then
			return error_message({['message'] = 'Expression error: ' .. k .. ' = ' .. statuses[k] .. ' > total = ' .. statuses.total .. '.'})
		end
	end
	if statuses.total == 0 then
		return error_message({['message'] = 'Expression error: total is 0.'})
	end
	
	local status_sum = statuses.validated + statuses.proofread + statuses.not_proofread + statuses.problematic + statuses.notext
	if status_sum > statuses.total then
		return error_message({['message'] = 'Expression error: page sum = ' .. status_sum .. ' > total = ' .. statuses.total .. '.'})
	end
	if yesno(args.existing_only or 'no') then
		statuses.total = status_sum
		statuses.missing = 0
	else
		statuses.missing = statuses.total - status_sum
	end
	
	-- status info
	local status_info = {
		{['n'] = statuses.validated, ['id'] = 'q4'},
		{['n'] = statuses.proofread, ['id'] = 'q3'},
		{['n'] = statuses.problematic, ['id'] = 'q2'},
		{['n'] = statuses.not_proofread, ['id'] = 'q1'},
		{['n'] = statuses.notext, ['id'] = 'q0'},
		{['n'] = statuses.missing, ['id'] = 'missing'}
	}
	
	-- construct table params
	local title = "title = '" .. statuses.validated .. "個已核對頁面," .. statuses.proofread .. "個僅校對頁面," .. statuses.problematic .. "個有問題頁面," .. statuses.not_proofread .. "個未校對頁面,以及" .. statuses.notext .. "個沒有文字的頁面(共" .. statuses.total .. "頁)'"
	
	local data_table = {"data-total='" .. statuses.total .. "'"}
	for k, v in pairs(status_info) do
		table.insert(data_table, "data-" .. v['id'] .. "='" .. v['n'] .. "'")
	end
	local datas = table.concat(data_table, " ")
	
	local style = make_style_string({['height'] = args.height, ['max-width'] = args.width})
	
	-- construct table rows
	local row_table = {}
	for k, v in pairs(status_info) do
		if v['n'] > 0 then
			table.insert(row_table, "<td class='wst-progress-bar-" .. v['id'] .. "' style='width:" .. 100 * v['n'] / statuses.total .. "%;'></td>")
		end
	end
	local rows = table.concat(row_table)
	
	return "<table class='wst-progress-bar' " .. title .. " " .. datas .. " " .. style .. ">" .. "<tr>" .. rows .. "</tr></table>"
end

--[=[
For calling from template
]=]
function p.progress_bar(frame)
	return p._progress_bar(getArgs(frame))
end

return p