__version__ = "$Id$"

colors = {
        # color values taken from HTML 4.0 spec
        'aqua': (0x00, 0xFF, 0xFF),
        'black': (0x00, 0x00, 0x00),
        'blue': (0x00, 0x00, 0xFF),
        'fuchsia': (0xFF, 0x00, 0xFF),
        'gray': (0x80, 0x80, 0x80),
        'green': (0x00, 0x80, 0x00),
        'lime': (0x00, 0xFF, 0x00),
        'maroon': (0x80, 0x00, 0x00),
        'navy': (0x00, 0x00, 0x80),
        'olive': (0x80, 0x80, 0x00),
        'purple': (0x80, 0x00, 0x80),
        'red': (0xFF, 0x00, 0x00),
        'silver': (0xC0, 0xC0, 0xC0),
        'teal': (0x00, 0x80, 0x80),
        'white': (0xFF, 0xFF, 0xFF),
        'yellow': (0xFF, 0xFF, 0x00),
        'orange': (0xFF, 0xA5, 0x00),
        'blend': (-1, -1, -1),
        'no value': (-255, -255, -255),
        }
colorsX11 = {
        # map of X11 implementation colors supported by
        # Microsoft Internet Explorer and Netscape Navigator
        # (the map contains 140 entries)
        'LightPink': (0xFF, 0xB6, 0xC1),
        'Pink': (0xFF, 0xC0, 0xCB),
        'Crimson': (0xDC, 0x14, 0x3C),
        'LavenderBlush': (0xFF, 0xF0, 0xF5),
        'PaleVioletRed': (0xDB, 0x70, 0x93),
        'HotPink': (0xFF, 0x69, 0xB4),
        'DeepPink': (0xFF, 0x14, 0x93),
        'MediumVioletRed': (0xC7, 0x15, 0x85),
        'Orchid': (0xDA, 0x70, 0xD6),
        'Thistle': (0xD8, 0xBF, 0xD8),
        'Plum': (0xDD, 0xA0, 0xDD),
        'Violet': (0xEE, 0x82, 0xEE),
        'Magenta': (0xFF, 0x00, 0xFF),
        'Fuchsia': (0xFF, 0x00, 0xFF),
        'DarkMagenta': (0x8B, 0x00, 0x8B),
        'Purple': (0x80, 0x00, 0x80),
        'MediumOrchid': (0xBA, 0x55, 0xD3),
        'DarkViolet': (0x94, 0x00, 0xD3),
        'DarkOrchid': (0x99, 0x32, 0xCC),
        'Indigo': (0x4B, 0x00, 0x82),
        'BlueViolet': (0x8A, 0x2B, 0xE2),
        'MediumPurple': (0x93, 0x70, 0xDB),
        'MediumSlateBlue': (0x7B, 0x68, 0xEE),
        'SlateBlue': (0x6A, 0x5A, 0xCD),
        'DarkSlateBlue': (0x48, 0x3D, 0x8B),
        'Lavender': (0xE6, 0xE6, 0xFA),
        'GhostWhite': (0xF8, 0xF8, 0xFF),
        'Blue': (0x00, 0x00, 0xFF),
        'MediumBlue': (0x00, 0x00, 0xCD),
        'MidnightBlue': (0x19, 0x19, 0x70),
        'DarkBlue': (0x00, 0x00, 0x8B),
        'Navy': (0x00, 0x00, 0x80),
        'RoyalBlue': (0x41, 0x69, 0xE1),
        'CornflowerBlue': (0x64, 0x95, 0xED),
        'LightSteelBlue': (0xB0, 0xC4, 0xDE),
        'LightSlateGray': (0x77, 0x88, 0x99),
        'SlateGray': (0x70, 0x80, 0x90),
        'DodgerBlue': (0x1E, 0x90, 0xFF),
        'AliceBlue': (0xF0, 0xF8, 0xFF),
        'SteelBlue': (0x46, 0x82, 0xB4),
        'LightSkyBlue': (0x87, 0xCE, 0xFA),
        'SkyBlue': (0x87, 0xCE, 0xEB),
        'DeepSkyBlue': (0x00, 0xBF, 0xFF),
        'LightBlue': (0xAD, 0xD8, 0xE6),
        'PowderBlue': (0xB0, 0xE0, 0xE6),
        'CadetBlue': (0x5F, 0x9E, 0xA0),
        'Azure': (0xF0, 0xFF, 0xFF),
        'LightCyan': (0xE0, 0xFF, 0xFF),
        'PaleTurquoise': (0xAF, 0xEE, 0xEE),
        'Cyan': (0x00, 0xFF, 0xFF),
        'Aqua': (0x00, 0xFF, 0xFF),
        'DarkTurquoise': (0x00, 0xCE, 0xD1),
        'DarkSlateGray': (0x2F, 0x4F, 0x4F),
        'DarkCyan': (0x00, 0x8B, 0x8B),
        'Teal': (0x00, 0x80, 0x80),
        'MediumTurquoise': (0x48, 0xD1, 0xCC),
        'LightSeaGreen': (0x20, 0xB2, 0xAA),
        'Turquoise': (0x40, 0xE0, 0xD0),
        'Aquamarine': (0x7F, 0xFF, 0xD4),
        'MediumAquamarine': (0x66, 0xCD, 0xAA),
        'MediumSpringGreen': (0x00, 0xFA, 0x9A),
        'MintCream': (0xF5, 0xFF, 0xFA),
        'SpringGreen': (0x00, 0xFF, 0x7F),
        'MediumSeaGreen': (0x3C, 0xB3, 0x71),
        'SeaGreen': (0x2E, 0x8B, 0x57),
        'Honeydew': (0xF0, 0xFF, 0xF0),
        'LightGreen': (0x90, 0xEE, 0x90),
        'PaleGreen': (0x98, 0xFB, 0x98),
        'DarkSeaGreen': (0x8F, 0xBC, 0x8F),
        'LimeGreen': (0x32, 0xCD, 0x32),
        'Lime': (0x00, 0xFF, 0x00),
        'ForestGreen': (0x22, 0x8B, 0x22),
        'Green': (0x00, 0x80, 0x00),
        'DarkGreen': (0x00, 0x64, 0x00),
        'Chartreuse': (0x7F, 0xFF, 0x00),
        'LawnGreen': (0x7C, 0xFC, 0x00),
        'GreenYellow': (0xAD, 0xFF, 0x2F),
        'DarkOliveGreen': (0x55, 0x6B, 0x2F),
        'YellowGreen': (0x9A, 0xCD, 0x32),
        'OliveDrab': (0x6B, 0x8E, 0x23),
        'Beige': (0xF5, 0xF5, 0xDC),
        'LightGoldenrodYellow': (0xFA, 0xFA, 0xD2),
        'Ivory': (0xFF, 0xFF, 0xF0),
        'LightYellow': (0xFF, 0xFF, 0xE0),
        'Yellow': (0xFF, 0xFF, 0x00),
        'Olive': (0x80, 0x80, 0x00),
        'DarkKhaki': (0xBD, 0xB7, 0x6B),
        'LemonChiffon': (0xFF, 0xFA, 0xCD),
        'PaleGoldenrod': (0xEE, 0xE8, 0xAA),
        'Khaki': (0xF0, 0xE6, 0x8C),
        'Gold': (0xFF, 0xD7, 0x00),
        'Cornsilk': (0xFF, 0xF8, 0xDC),
        'Goldenrod': (0xDA, 0xA5, 0x20),
        'DarkGoldenrod': (0xB8, 0x86, 0x0B),
        'FloralWhite': (0xFF, 0xFA, 0xF0),
        'OldLace': (0xFD, 0xF5, 0xE6),
        'Wheat': (0xF5, 0xDE, 0xB3),
        'Moccasin': (0xFF, 0xE4, 0xB5),
        'Orange': (0xFF, 0xA5, 0x00),
        'PapayaWhip': (0xFF, 0xEF, 0xD5),
        'BlanchedAlmond': (0xFF, 0xEB, 0xCD),
        'NavajoWhite': (0xFF, 0xDE, 0xAD),
        'AntiqueWhite': (0xFA, 0xEB, 0xD7),
        'Tan': (0xD2, 0xB4, 0x8C),
        'BurlyWood': (0xDE, 0xB8, 0x87),
        'Bisque': (0xFF, 0xE4, 0xC4),
        'DarkOrange': (0xFF, 0x8C, 0x00),
        'Linen': (0xFA, 0xF0, 0xE6),
        'Peru': (0xCD8, 0x5, 0x3F),
        'PeachPuff': (0xFF, 0xDA, 0xB9),
        'SandyBrown': (0xF4, 0xA4, 0x60),
        'Chocolate': (0xD2, 0x69, 0x1E),
        'SaddleBrown': (0x8B, 0x45, 0x13),
        'Seashell': (0xFF, 0xF5, 0xEE),
        'Sienna': (0xA0, 0x52, 0x2D),
        'LightSalmon': (0xFF, 0xA0, 0x7A),
        'Coral': (0xFF, 0x7F, 0x50),
        'OrangeRed': (0xFF, 0x45, 0x00),
        'DarkSalmon': (0xE9, 0x96, 0x7A),
        'Tomato': (0xFF, 0x63, 0x47),
        'MistyRose': (0xFF, 0xE4, 0xE1),
        'Salmon': (0xFA, 0x80, 0x72),
        'Snow': (0xFF, 0xFA, 0xFA),
        'LightCoral': (0xF0, 0x80, 0x80),
        'RosyBrown': (0xBC, 0x8F, 0x8F),
        'IndianRed': (0xCD, 0x5C, 0x5C),
        'Red': (0xFF, 0x00, 0x00),
        'Brown': (0xA5, 0x2A, 0x2A),
        'FireBrick': (0xB2, 0x22, 0x22),
        'DarkRed': (0x8B, 0x00, 0x00),
        'Maroon': (0x80, 0x00, 0x00),
        'White': (0xFF, 0xFF, 0xFF),
        'WhiteSmoke': (0xF5, 0xF5, 0xF5),
        'Gainsboro': (0xDC, 0xDC, 0xDC),
        'LightGrey': (0xD3, 0xD3, 0xD3),
        'Silver': (0xC0, 0xC0, 0xC0),
        'DarkGray': (0xA9, 0xA9, 0xA9),
        'Gray': (0x80, 0x80, 0x80),
        'DimGray': (0x69, 0x69, 0x69),
        'Black': (0x00, 0x00, 0x00),
}

rcolors = {}
for name, color in colors.items():
    rcolors[color] = name

colorsx11 = {}
for name, color in colorsX11.items():
    colorsx11[name.lower()] = color

del name, color

import SystemColors

class error(Exception):
    pass

import re
from xmllib import _opS
colorre = re.compile('(?:'
                   '#(?P<hex>[0-9a-fA-F]{3}|'           # #f00
                            '[0-9a-fA-F]{6})|'          # #ff0000
                   'rgb' + _opS + r'\(' +               # rgb(R,G,B)
                           _opS + '(?:(?P<ri>[0-9]+)' + _opS + ',' + # rgb(255,0,0)
                           _opS + '(?P<gi>[0-9]+)' + _opS + ',' +
                           _opS + '(?P<bi>[0-9]+)|' +
                           _opS + '(?P<rp>[0-9]+)' + _opS + '%' + _opS + ',' + # rgb(100%,0%,0%)
                           _opS + '(?P<gp>[0-9]+)' + _opS + '%' + _opS + ',' +
                           _opS + '(?P<bp>[0-9]+)' + _opS + '%)' + _opS + r'\))$')

def convert_color(val, extend = 0, system = 1):
    val = val.lower()
    if colors.has_key(val):
        return colors[val]
    if val in ('transparent', 'inherit'):
        return val
    if system and SystemColors.colors.has_key(val):
        return SystemColors.colors[val]
    if extend and colorsx11.has_key(val.lower()):
        return colorsx11[val.lower()]
    res = colorre.match(val)
    if res is None:
        raise error, 'bad color specification'
    hex = res.group('hex')
    if hex is not None:
        if len(hex) == 3:
            r = int(hex[0]*2, 16)
            g = int(hex[1]*2, 16)
            b = int(hex[2]*2, 16)
        else:
            r = int(hex[0:2], 16)
            g = int(hex[2:4], 16)
            b = int(hex[4:6], 16)
    else:
        r = res.group('ri')
        if r is not None:
            r = int(r)
            g = int(res.group('gi'))
            b = int(res.group('bi'))
        else:
            r = int(float(res.group('rp')) * 255 / 100.0 + 0.5)
            g = int(float(res.group('gp')) * 255 / 100.0 + 0.5)
            b = int(float(res.group('bp')) * 255 / 100.0 + 0.5)
    if r > 255: r = 255
    if g > 255: g = 255
    if b > 255: b = 255
    return r, g, b
