# Module:Overlay

-- this module implements Template:Overlay  
local p = {}  

local mArguments = require('Module:Arguments')  

-- used to cache the calculated font color to avoid repeat calculations  
local previous_backgroundcolor = ''  
local fontcolor = ''  

local function buildicon(n, form, lk, c, t)  
local res  
if form == 'text' then  
return tostring(  
mw.html.create('span')  
:css('font-weight', 'bold')  
:css('color', c)  
:wikitext(n)  
elseif form == 'color' or form == 'colour' then  
return tostring(  
mw.html.create('span')  
:css('background-color', c)  
:wikitext('&#160;&#160;')  
else  
-- check if the color is difference from the previous color  
if c ~= previous_backgroundcolor then  
-- color changed, so look up the best font color  
local greatercontrast = require('Module:Color contrast')._greatercontrast  
fontcolor = greatercontrast{c, 'white', 'black', bias = 1.3}  
-- update the previous value for the next check  
previous_backgroundcolor = c  
end  
-- build the inner span for the icon  
local span = mw.html.create('span')  
:css('color', fontcolor)  
:css('font-size', '88%')  
:css('font-weight', 'bold')  
:attr('title', t)  
:wikitext(n)  
-- build the outer div  
local div = mw.html.create('div')  
:css('display', 'inline-block')  
:css('width', 'auto')  
:css('height', 'auto')  
:css('text-align', '')  
:css('padding', ((tonumber(n) or 0) < 10) and ' ' or ' ')  
:css('vertical-align', 'middle')  
:css('-radius', '')  
:css('background-color', c)  

-- link the inner span if requested and insert in the div  
if lk ~= '' then  
div:wikitext(* .. tostring(span) .. *)  
else  
div:wikitext(tostring(span))  
end  
-- convert to a string  
return tostring(div)  
end  
end  

local function buildlegend(data, cols, , caption)  
-- create the outer table to hold the columns  
local root = mw.html.create('table')  
:css('width', '100%')  
:css(*, ( ~= 'no') and ' #ccc solid' or *)  
-- create the outer row which will contain the columns  
local outerrow = root:tag('tr')  
local percol = math.ceil((#data) / cols)  
local k = 0  
for j=1,cols do  
-- create the outer cell to hold this column  
local colcell = outerrow:tag('td')  
:css('width', (math.floor(10/cols)/10) .. '%')  
:css('vertical-align', 'top')  
-- create the inner table to hold the entries in the column  
local coltable = colcell:tag('table')  
:css('width', '100%')  
:css('font-size', '85%')  
:css('line-height', '95%')  
-- add the entries to the column  
for l = 1,percol do  
k = k + 1  
if k <= #data then  
local rdata = data[k]  
local tr = coltable:tag('tr'):css('vertical-align','top')  
tr:tag('td')  
:css('width', '')  
:css('text-align', '')  
:css('padding-bottom', '')  
:wikitext(rdata[1] or '')  
tr:tag('td')  
:css('padding-bottom', '')  
:wikitext(rdata[2] or '')  
end  
end  
end  
return caption .. tostring(root)  
end  

local function buildlegenditem(im, lk, t)  
local res = {im, ''}  
if t ~= '' then  
if lk ~= '' then  
res[2] = * .. t .. *  
else  
res[2] = t  
end  
else  
res[2] = * .. lk .. *  
end  
return res  
end  

function p.icon  
local args = mArguments.getArgs  
return tostring(  
mw.html.create('div')  
:css('display', 'inline-block')  
:css('line-height', '95%')  
:wikitext(buildicon(args['1'] or '',  
args['form'] or 'icon',  
args['link'] or '',  
args['2'] or 'red',  
args['tip'] or ''))  
end  

function p.main  
local args = mArguments.getArgs  

local image = args['image'] or ''  
local width = tonumber(args['width'] or '500') or 500  
local height = tonumber(args['height'] or '500') or 500  
local columns = tonumber(args['columns'] or '3') or 3  
local grid = ((args['grid'] or ''):lower == 'yes') and 'yes' or 'no'  
local legendbox = ((args['legendbox'] or ''):lower == 'no') and 'no' or 'yes'  
local overlay = (image == *) and 'no' or ( ((args['overlay'] or *):lower == 'no') and 'no' or 'yes' )  
local float = args['float'] or ''  
local = ((args[*] or *):lower == 'no') and 'no' or 'yes'  
local padding = args['padding'] or ''  

-- create the root table  
local root = mw.html.create('table')  
if float == '' or float == 'centre' then  
root:css('margin-', 'auto')  
:css('margin-', 'auto')  
elseif float == '' then  
root:css('float', '')  
:css('clear', '')  
:css('margin-', '1em')  
elseif float == '' then  
root:css('float', '')  
:css('clear', '')  
:css('margin-', '1em')  
else  
root:css('float', float)  
end  
if == 'yes' then  
root:css('', ' #ccc solid')  
end  

-- create a list of all the overlay numbers  
local itemnums = {}  
for k, v in pairs( args ) do  
local i = tonumber(tostring(k):match( '^%s*overlay([%d]+)%s*$' ) or '-1')  
if i > -1 then  
table.insert(itemnums, i)  
else  
i = tonumber(tostring(k):match( '^%s*overlay([%d]+)tip%s*$' ) or '-1')  
if i > -1 then  
table.insert(itemnums, i)  
end  
end  
end  
-- sort to process in order  
table.sort( itemnums )  

-- remove duplicates  
for k = 2,#itemnums do  
if itemnums[k] == itemnums[k-1] then  
table.remove(itemnums, k)  
end  
end  

-- build the overlay markers and text  
itemdata = {}  
local colori = args['color'] or args['colour'] or 'red'  
local formi = ''  
for k = 1,#itemnums do  
local i = itemnums[k]  
formi = args['overlay' .. i .. 'form'] or formi  
colori = args['overlay' .. i .. 'color'] or args['overlay' .. i .. 'colour'] or colori  
local linki = args['overlay' .. i .. 'link'] or ''  
local tipi = args['overlay' .. i .. 'tip'] or args['overlay' .. i] or ''  
local overlayi = args['overlay' .. i] or args['overlay' .. i .. 'tip'] or ''  
if (overlayi ~= * or tipi ~= *) then  
local imagei = buildicon(i, formi, linki, colori, tipi)  
itemdata[k] = buildlegenditem(imagei, args['overlay' .. i .. 'link'] or '', overlayi)  
end  
end  

-- create the overlay image  
if image ~= '' then  
local cell = root:tag('tr'):tag('td')  
cell:attr('align', '')  
if( padding ~= '' ) then  
cell:css('padding', padding)  
end  
if( columns > 1 and legendbox == 'yes' ) then  
cell:attr('colspan', columns)  
end  
local imagediv = cell:tag('div')  
imagediv:css('position','relative')  
:css(*, *)  
:css('top', '')  
:css('width', ((grid == 'yes') and 940 or width) .. 'px')  
:css('height', ((grid == 'yes') and 940 or height) .. 'px')  
if grid == 'yes' then  
imagediv:tag('span')  
:css('position', 'absolute')  
:css(*, *)  
:css('top', '')  
:css('z-index', '2')  
:wikitext('')  
end  
imagediv:tag('span')  
:css('position', 'absolute')  
:css(*, *)  
:css('top', '')  
:css('z-index', '0')  
:css('width', width .. 'px')  
:css('height', height .. 'px')  
:wikitext('')  
if overlay == 'yes' then  
for k = 1,#itemnums do  
local i = itemnums[k]  
local imagei = (itemdata[k])[1]  
for j =0,3 do  
local overlayileftj = args['overlay' .. i .. * .. ((j == 0) and * or j)] or ''  
local overlayitopj = args['overlay' .. i .. 'top' .. ((j == 0) and * or j)] or *  
if overlayileftj ~= '' then  
imagediv:tag('div')  
:css('position', 'absolute')  
:css('', overlayileftj .. 'px')  
:css('top', overlayitopj .. 'px')  
:css('line-height', '95%')  
:css('z-index', '1')  
:wikitext(imagei)  
end  
end  
end  
end  
end  

-- Split the legend items into sub-legends  
legend =  
local jmax = itemnums[#itemnums]  
for i=1,5 do  
if args['legend' .. i .. 'start'] then  
-- default is all items  
j1 = 0  
j2 = jmax  
-- set start item number to (legendistart) or (legend(i-1)end + 1)  
if args['legend' .. i .. 'start'] then  
j1 = tonumber(args['legend' .. i .. 'start']) or j1  
elseif args['legend' .. (i-1) .. 'end'] then  
j1 = (tonumber(args['legend' .. (i-1) .. 'end']) or j1) + 1  
end  
-- set end item number to (legendiend) or (legend(i+1)start - 1)  
if args['legend' .. i .. 'end'] then  
j2 = tonumber(args['legend' .. i .. 'end']) or j2  
elseif args['legend' .. (i+1) .. 'start'] then  
j2 = (tonumber(args['legend' .. (i+1) .. 'start']) or j2) - 1  
end  
-- get the items within the range, marking them as they are used  
for k=1,#itemnums do  
j = itemnums[k]  
if (j >= 0 and j >= j1 and j <= j2) then  
table.insert(legend[i], itemdata[k])  
itemnums[k] = -1  
end  
end  
end  
end  

-- Add any over items to the first legend  
for k = 1,#itemnums do  
if itemnums[k] >= 0 then  
table.insert(legend[1], itemdata[k])  
end  
end  

-- Build the legend  
if columns > 0 then  
for i = 1,5 do  
local locallegend = legend[i]  
if (locallegend and #locallegend > 0) then  
local cell = root:tag('tr'):tag('td')  
cell:wikitext(buildlegend(locallegend, columns, , args['legend' .. i .. 'title'] or ''))  
end  
end  
end  

return tostring(root)  
end  

return p