Creates boxes using <div> tags rather than tables.


local getArgs = require('Module:Arguments').getArgs

local p = {}

local themes = {
	["0"] = {
		"border: thin solid #a2a9b1;",
		"background-color: #e1e6ea; border-bottom: thin solid #a2a9b1;", 
		"background-color: #f8f9fa;"},
	["1"] = {
		"border: thin solid #e39c79;",
		"background-color: #f5deb3; border-bottom: thin solid #e39c79;", 
		"background-color: #fffcf1;"},
	["2"] = {
		"border: thin solid #228b22;",
		"background-color: #90ee90; border-bottom: thin solid #228b22;", 
		"background-color: #f5fffa;"},
	["3"] = {
		"border: thin solid #4682b4;",
		"background-color: #b0c4de; border-bottom: thin solid #4682b4;", 
		"background-color: #f0f8ff;"},
	["4"] = {
		"border: thin solid #cd5c5c;",
		"background-color: #f08080; border-bottom: thin solid #cd5c5c;", 
		"background-color: #ffe4e1;"},
	["5"] = {
		"border: thin solid #9370db;",
		"background-color: #d8bfd8; border-bottom: thin solid #9370db;", 
		"background-color: #fff0f5;"},
	["6"] = {
		"border: thin solid #ffd700;",
		"background-color: #ffff99; border-bottom: thin solid #ffd700;", 
		"background-color: #fffff0;"},
	["7"] = {
		"border: thin solid #4169e1;",
		"background-color: #87cefa; border-bottom: thin solid #4169e1;", 
		"background-color: #f0ffff;"},
	["8"] = {
		"border: thin solid #e78a69;",
		"background-color: #ffdab9; border-bottom: thin solid #e78a69;", 
		"background-color: #fff5ee;"},
	["9"] = {
		"border: thin solid #71be3f;",
		"background-color: #c0eaa6; border-bottom: thin solid #71be3f;", 
		"background-color: #f6fff1;"},
	["10"] = {
		"border: thin solid #4290bc;",
		"background-color: #9ad4f6; border-bottom: thin solid #4290bc;", 
		"background-color: #f4faff;"},
	["11"] = {
		"border: thin solid #c289c3;",
		"background-color: #e6c6e6; border-bottom: thin solid #c289c3;", 
		"background-color: #fff8ff;"},
	["12"] = {
		"border: thin solid #c56b74;",
		"background-color: #f4b8bf; border-bottom: thin solid #c56b74;", 
		"background-color: #fff6f8;"},
	["13"] = {
		"border: thin solid #8488dc;",
		"background-color: #ced1fa; border-bottom: thin solid #8488dc;", 
		"background-color: #f5f5ff;"},
	["14"] = {
		"border: thin solid #aaaaaa;",
		"background-color: #e4e4e4; border-bottom: thin solid #aaaaaa;", 
		"background-color: #ffffff;"}
}

local colors = {
	["aliceblue"] = "#f0f8ff",
	["antiquewhite"] = "#faebd7",
	["aqua"] = "#00ffff",
	["aquamarine"] = "#7fffd4",
	["azure"] = "#f0ffff",
	["beige"] = "#f5f5dc",
	["bisque"] = "#ffe4c4",
	["black"] = "#000000",
	["blanchedalmond"] = "#ffebcd",
	["blue"] = "#0000ff",
	["blueviolet"] = "#8a2be2",
	["brown"] = "#a52a2a",
	["burlywood"] = "#deb887",
	["cadetblue"] = "#5f9ea0",
	["chartreuse"] = "#7fff00",
	["chocolate"] = "#d2691e",
	["coral"] = "#ff7f50",
	["cornflowerblue"] = "#6495ed",
	["cornsilk"] = "#fff8dc",
	["crimson"] = "#dc143c",
	["cyan"] = "#00ffff",
	["darkblue"] = "#00008b",
	["darkcyan"] = "#008b8b",
	["darkgoldenrod"] = "#b8860b",
	["darkgray"] = "#a9a9a9",
	["darkgrey"] = "#a9a9a9",
	["darkgreen"] = "#006400",
	["darkkhaki"] = "#bdb76b",
	["darkmagenta"] = "#8b008b",
	["darkolivegreen"] = "#556b2f",
	["darkorange"] = "#ff8c00",
	["darkorchid"] = "#9932cc",
	["darkred"] = "#8b0000",
	["darksalmon"] = "#e9967a",
	["darkseagreen"] = "#8fbc8f",
	["darkslateblue"] = "#483d8b",
	["darkslategray"] = "#2f4f4f",
	["darkslategrey"] = "#2f4f4f",
	["darkturquoise"] = "#00ced1",
	["darkviolet"] = "#9400d3",
	["deeppink"] = "#ff1493",
	["deepskyblue"] = "#00bfff",
	["dimgray"] = "#696969",
	["dimgrey"] = "#696969",
	["dodgerblue"] = "#1e90ff",
	["firebrick"] = "#b22222",
	["floralwhite"] = "#fffaf0",
	["forestgreen"] = "#228b22",
	["fuchsia"] = "#ff00ff",
	["gainsboro"] = "#dcdcdc",
	["ghostwhite"] = "#f8f8ff",
	["gold"] = "#ffd700",
	["goldenrod"] = "#daa520",
	["gray"] = "#808080",
	["grey"] = "#808080",
	["green"] = "#008000",
	["greenyellow"] = "#adff2f",
	["honeydew"] = "#f0fff0",
	["hotpink"] = "#ff69b4",
	["indianred "] = "#cd5c5c",
	["indigo "] = "#4b0082",
	["ivory"] = "#fffff0",
	["khaki"] = "#f0e68c",
	["lavender"] = "#e6e6fa",
	["lavenderblush"] = "#fff0f5",
	["lawngreen"] = "#7cfc00",
	["lemonchiffon"] = "#fffacd",
	["lightblue"] = "#add8e6",
	["lightcoral"] = "#f08080",
	["lightcyan"] = "#e0ffff",
	["lightgoldenrodyellow"] = "#fafad2",
	["lightgray"] = "#d3d3d3",
	["lightgrey"] = "#d3d3d3",
	["lightgreen"] = "#90ee90",
	["lightpink"] = "#ffb6c1",
	["lightsalmon"] = "#ffa07a",
	["lightseagreen"] = "#20b2aa",
	["lightskyblue"] = "#87cefa",
	["lightslategray"] = "#778899",
	["lightslategrey"] = "#778899",
	["lightsteelblue"] = "#b0c4de",
	["lightyellow"] = "#ffffe0",
	["lime"] = "#00ff00",
	["limegreen"] = "#32cd32",
	["linen"] = "#faf0e6",
	["magenta"] = "#ff00ff",
	["maroon"] = "#800000",
	["mediumaquamarine"] = "#66cdaa",
	["mediumblue"] = "#0000cd",
	["mediumorchid"] = "#ba55d3",
	["mediumpurple"] = "#9370db",
	["mediumseagreen"] = "#3cb371",
	["mediumslateblue"] = "#7b68ee",
	["mediumspringgreen"] = "#00fa9a",
	["mediumturquoise"] = "#48d1cc",
	["mediumvioletred"] = "#c71585",
	["midnightblue"] = "#191970",
	["mintcream"] = "#f5fffa",
	["mistyrose"] = "#ffe4e1",
	["moccasin"] = "#ffe4b5",
	["navajowhite"] = "#ffdead",
	["navy"] = "#000080",
	["oldlace"] = "#fdf5e6",
	["olive"] = "#808000",
	["olivedrab"] = "#6b8e23",
	["orange"] = "#ffa500",
	["orangered"] = "#ff4500",
	["orchid"] = "#da70d6",
	["palegoldenrod"] = "#eee8aa",
	["palegreen"] = "#98fb98",
	["paleturquoise"] = "#afeeee",
	["palevioletred"] = "#db7093",
	["papayawhip"] = "#ffefd5",
	["peachpuff"] = "#ffdab9",
	["peru"] = "#cd853f",
	["pink"] = "#ffc0cb",
	["plum"] = "#dda0dd",
	["powderblue"] = "#b0e0e6",
	["purple"] = "#800080",
	["rebeccapurple"] = "#663399",
	["red"] = "#ff0000",
	["rosybrown"] = "#bc8f8f",
	["royalblue"] = "#4169e1",
	["saddlebrown"] = "#8b4513",
	["salmon"] = "#fa8072",
	["sandybrown"] = "#f4a460",
	["seagreen"] = "#2e8b57",
	["seashell"] = "#fff5ee",
	["sienna"] = "#a0522d",
	["silver"] = "#c0c0c0",
	["skyblue"] = "#87ceeb",
	["slateblue"] = "#6a5acd",
	["slategray"] = "#708090",
	["slategrey"] = "#708090",
	["snow"] = "#fffafa",
	["springgreen"] = "#00ff7f",
	["steelblue"] = "#4682b4",
	["tan"] = "#d2b48c",
	["teal"] = "#008080",
	["thistle"] = "#d8bfd8",
	["tomato"] = "#ff6347",
	["turquoise"] = "#40e0d0",
	["violet"] = "#ee82ee",
	["wheat"] = "#f5deb3",
	["white"] = "#ffffff",
	["whitesmoke"] = "#f5f5f5",
	["yellow"] = "#ffff00",
	["yellowgreen"] = "#9acd32"
}

local theme = nil
local titlecolor = nil

function p.box(frame)
	local args = getArgs(frame)
	return p._box(args)
end	

function p._box(args)
	local div = mw.html.create'div'

	p._theme(args)
	div:cssText(theme[1])

	if args.title and args.titlebackground then
		div:css('background-color', args.titlebackground)
	elseif args.background then
		div:css('background-color', args.background)
	end

	if args.border then
		div:css('border', args.border)
	end

	if args.color then
		div:css('color', args.color)
	end
	
	if args.margin then
		div:css('margin', args.margin)
	else
		div:css('margin', 'auto')
	end
		
	if args.radius then
		div:css('border-radius', args.radius)
	end

	if args.width then
		div:css('width', args.width)
	end
	
	if args.style then
		div:cssText(args.style)
	end

	if args.title then
		div:node(p._title(args))
	end
	
	div:node(p._body(args))

	return div:allDone()
end

function p._theme(args)
	if not args.theme then
		theme = themes["0"]
		return
	end
	
	if themes[args.theme] then
		theme = themes[args.theme]
		return
	end

	theme = themes["0"]

	local title_background = nil
	if colors[string.lower(args.theme)] then
		title_background = colors[string.lower(args.theme)]
	else
		title_background = args.theme
	end

	titlecolor = p._color(title_background)
	local background = p._background(title_background)
	local border = p._border(title_background)

	theme[1] = "border: thin solid " .. border .. ";"
	theme[2] = "background-color: " .. title_background .. 
		"; border-bottom: thin solid " .. border .. 
		"; color: " .. titlecolor .. ";"
	theme[3] = "background-color: " .. background .. ";"
end

function p._background(color)
	color = string.gsub(color, "#", "")
	
	if string.len(color) == 3 then
		color = string.sub(color, 1, 1) .. string.sub(color, 1, 1) .. 
			string.sub(color, 2, 2) .. string.sub(color, 2, 2) ..
			string.sub(color, 3, 3) .. string.sub(color, 3, 3)
	end
	
	red = tonumber("0x" .. string.sub(color, 1, 2))
	green = tonumber("0x" .. string.sub(color, 3, 4))
	blue = tonumber("0x" .. string.sub(color, 5, 6))
	
	red = red / 255 * 15 + 240
	green = green / 255 * 15 + 240
	blue = blue / 255 * 15 + 240
	
	return string.format("#%02x%02x%02x", red, green, blue)
end
	
function p._border(color)
	color = string.gsub(color, "#", "")
	
	if string.len(color) == 3 then
		color = string.sub(color, 1, 1) .. string.sub(color, 1, 1) .. 
			string.sub(color, 2, 2) .. string.sub(color, 2, 2) ..
			string.sub(color, 3, 3) .. string.sub(color, 3, 3)
	end
	
	red = tonumber("0x" .. string.sub(color, 1, 2))
	green = tonumber("0x" .. string.sub(color, 3, 4))
	blue = tonumber("0x" .. string.sub(color, 5, 6))
	
	red = red * 3 / 4
	green = green * 3 / 4
	blue = blue * 3 / 4
	
	return string.format("#%02x%02x%02x", red, green, blue)
end
	
function p._color(color)
	color = string.gsub(color, "#", "")
	
	if string.len(color) == 3 then
		color = string.sub(color, 1, 1) .. string.sub(color, 1, 1) .. 
			string.sub(color, 2, 2) .. string.sub(color, 2, 2) ..
			string.sub(color, 3, 3) .. string.sub(color, 3, 3)
	end
	
	red = tonumber("0x" .. string.sub(color, 1, 2))
	green = tonumber("0x" .. string.sub(color, 3, 4))
	blue = tonumber("0x" .. string.sub(color, 5, 6))
	
	luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255

	if luminance >= 0.5 then
		return "#000000"
	else
		return "#ffffff"
	end
end

function p._edit(edit)
	frame = mw.getCurrentFrame()
	link = frame:callParserFunction('fullurl', {edit, 'action=edit'})
	text = '<div class="plainlinks" style="float: right; ' .. 
		'font-size: smaller; font-weight: normal;">' ..
		'[' .. link .. ' <span style="color: ' .. titlecolor ..
		';">edit</span>]</div>'
	return text
end

function p._title(args)
	local node = mw.html.create'div'

	node:cssText(theme[2])

	if args.titlebackground then
		node:css('background', args.titlebackground)
	end
	
	if args.border then
		node:css('bottom-border', args.border)
	end

	if args.titlecolor then
		node:css('color', args.titlecolor)
	end
	
	if args.titlefont then
		node:css('font', args.titlefont)
	else
		node:css('font-weight', 'bold')
	end

	if args.titlepadding then
		node:css('padding', args.titlepadding)
	else
		node:css('padding', '0.25em 0.5em 0.25em 0.5em')
	end
	
	if args.titlealign then
		node:css('text-align', args.titlealign)
	end
	
	if args.titlestyle then
		node:cssText(args.titlestyle)
	end

    node:wikitext(args.title)
    
    if args.edit ~= nil then
		node:wikitext(p._edit(args.edit))
    end
    
    node:done()
    return node
end

function p._body(args)
	local node = mw.html.create'div'

	node:cssText(theme[3])

	if args.background then
		node:css('background-color', args.background)
	end

	if args.font then
		node:css('font', args.font)
	end
	
	if args.padding then
		node:css('padding', args.padding)
	else
		node:css('padding', '0.25em 0.5em 0.25em 0.5em')
	end

	if args.radius then
		node:css('border-radius', args.radius)
	end

	if args.align then
		node:css('text-align', args.align)
	end
	
	if args.textalign then
		node:css('text-align', args.textalign)
	end
	
	if args.bodystyle then
		node:cssText(args.bodystyle)
	end

	node:wikitext(args['1'])
	node:done()
	
	return node
end

return p