Module:Color

De ARK Wiki
Aller à la navigation Aller à la recherche

Ce module est utilisé par le Modèle:Color pour afficher des carrés de couleur selon le nom précisé. Les noms de couleurs utilisables peuvent être vus dans le Module:Color/codes.


local p = {}
local Utility = require( 'Module:Utility' )
local colorCodes = mw.loadData( 'Module:Color/codes' )
local colorIds = mw.loadData( 'Module:Color/ids' )
local SQUARE_SIZE = 20


function p.parseRgbHex( hex )
    hex = hex:gsub( '#', '' )
    return {
    	tonumber( '0x'..hex:sub( 1, 2 ) ),
    	tonumber( '0x'..hex:sub( 3, 4 ) ),
    	tonumber( '0x'..hex:sub( 5, 6 ) )
    }
end


function p.selectTextColor( color )
	return ( color[1] * 0.2126 + color[2] * 0.7152 + color[3] * 0.0722 > (0.5 * 255) ) and 'black' or 'white'
end

local function findColorName(colorId)
	for name, id in pairs(colorIds) do
		if id == colorId then
			return name
		end
	end
	return ''
end

function p.colors( f )
  local args = f:getParent().args
  local colorBlocks = {}
  local size = 20
  local colorNameLower = ''
  local colorId = 0
  local colorCode = ''
  local unknownId = 256

  --This slices one parameter into a variable number of parameters with a comma as a delimiter.
  --This allows the list to be called into another Template as its own parameter.
  local M_SLICES = {}
  for part in string.gmatch((args[1])..',', "([^,]*),") do
  	local slice = part:match "^%s*(.-)%s*$"
  	if #slice <= 3 and tonumber(slice) ~= nil then
  		slice = findColorName(slice)
  	end
    table.insert(M_SLICES, slice)
  end

  local colorIdsOrdered={}
  for _, colorNameInput in ipairs(M_SLICES) do
    colorNameLower = colorNameInput:gsub('%W',''):lower()

    colorId = colorIds[colorNameLower]
    if colorId ~= nil then
      colorId = tonumber(colorId)
    end

    -- colorId must be a number for the sorting later
    -- internally in this module, an unknown id is represented by numbers > 256
    if colorId == nil then
      colorId = unknownId
      unknownId = unknownId + 1
    end

    colorCode = colorCodes[colorNameLower]

    if colorCode ~= nil and not p.isColorNameInTable(colorIdsOrdered, colorNameLower) then
      table.insert(colorIdsOrdered, {colorId, colorCode, colorNameInput})
    end
  end

  -- the sorting function must be stable, i.e. a==b => b==a
  table.sort(colorIdsOrdered, function(a,b) return a[1] < b[1] end)

  -- colorInfo[1]: color Id
  -- colorInfo[2]: color code (hex)
  -- colorInfo[3]: color name as entered in the template call
  for _, colorInfo in ipairs(colorIdsOrdered) do
    table.insert( colorBlocks, string.format(
    	'<div class="color-square" style="height:%dpx; width: %dpx; background: %s; color: %s" title="%s&nbsp;&#40;%s&#41;">%s</div>',
    	size, size, colorInfo[2], p.selectTextColor( p.parseRgbHex( colorInfo[2] ) ), colorInfo[3],
    	(colorInfo[1] < 256 and colorInfo[1] or 'no id'),
    	(colorInfo[1] < 256 and '<span>'..colorInfo[1]..'</span>' or '')
    ) )
  end
  return '<div class="color-container">'..table.concat(colorBlocks)..'</div>'
end

function p.isColorNameInTable(tab, colorNameLower)
  for _, colorInfo in ipairs(tab) do
    if colorInfo[3] == colorNameLower then return true end
  end
  return false
end

function p.queryColorTable()
    local results = Utility.runCachedCargoQuery( 'ColorTable', {
        tableName = 'Colors',
        fields = 'Id, Name, sRGB',
        expiryTime = 60 * 60 * 8,
        options = {
            orderBy = 'Id ASC',
        },
    } )
    for index = 1, #results do
    	results[index].Id = tonumber( results[index].Id )
   	end
   	return results
end

function p.findRecord( records, needle )
    if tonumber( needle ) ~= nil then
        needle = tonumber( needle )
    elseif type( needle ) == 'string' then
        needle = mw.text.trim( string.lower( needle ) )
    end

	for index = 1, #records do
        local record = records[index]
        local compared

        if type( needle ) == 'number' then
            compared = record.Id
        else
            compared = string.lower( record.Name )
        end

		if compared == needle then
			return record
		end
	end

	return nil
end

function p.selectSubset( records, needles )
    local out = {}
    local needleMap = {}
    local expectedCount = 0

    for index = 1, #needles do
        local needle = needles[index]
        if tonumber( needle ) ~= nil then
            needle = tonumber( needle )
        elseif type( needle ) == 'string' then
            needle = mw.text.trim( string.lower( needle ) )
        end
        
        if needle ~= '' and needleMap[needle] == nil then
	        needleMap[needle] = true
    	    expectedCount = expectedCount + 1
    	end
    end

    for index = 1, #records do
        local record = records[index]
        if needleMap[record.Id] or needleMap[string.lower( record.Name )] then
            out[#out + 1] = record
        end
    end

    if expectedCount ~= #out then
        --error( 'Une ou des couleurs non pas été trouvées dans le tableau' )
        out[#out + 1] = {
        	Id = 0,
        	Name = 'Non définie',
        	sRGB = '00000000'
        }
    end

	return out
end

function p.makeColoredSquares( records )
    local out = {}

    table.sort( records, function ( a, b ) return a.Id < b.Id end )

    for index = 1, #records do
        local record = records[index]
        out[#out + 1] = string.format(
        	'<div class="color-square" style="height: %dpx; width: %dpx; background: #%s; color: %s" '
                .. 'title="%s (%d)"><span>%d</span></div>',
            SQUARE_SIZE,
            SQUARE_SIZE,
            record.sRGB,
            p.selectTextColor( p.parseRgbHex( record.sRGB ) ),
            record.Name,
    	    record.Id,
    	    record.Id
        )
    end

    return string.format( '<div class="color-container">%s</div>', table.concat( out, '' ) )
end

function p.selectTextColorW( frame )
    return p.selectTextColor( p.parseRgbHex( frame.args[1] ) )
end

function p.queryW( frame )
    local record = p.findRecord( p.queryColorTable(), frame.args[1] )
    if record == nil then
        error( 'Couleur non trouvée : ' .. frame.args[1] )
    end
    return record[frame.args[2]]        
end

function p.makeColoredSquaresW( frame )
    local colors = mw.text.split( frame.args[1], ',', true )
    local records = p.selectSubset( p.queryColorTable(), colors )
    return p.makeColoredSquares( records )
end

return p