/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.util;

import java.awt.Color;
import java.awt.color.ColorSpace;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.expr.PropertyException;

/**
 * Generic Color helper class.
 * <p>
 * This class supports parsing string values into color values and creating
 * color values for strings. It provides a list of standard color names.
 */
public final class ColorUtil {

    /**
     *
     * keeps all the predefined and parsed colors.
     * <p>
     * This map is used to predefine given colors, as well as speeding up
     * parsing of already parsed colors.
     */
    private static Map colorMap = null;

    /** Logger instance */
    protected static Log log = LogFactory.getLog(ColorUtil.class);

    static {
        initializeColorMap();
    }

    /**
     * Private constructor since this is an utility class.
     */
    private ColorUtil() {
    }

    /**
     * Creates a color from a given string.
     * <p>
     * This function supports a wide variety of inputs.
     * <ul>
     * <li>#RGB (hex 0..f)</li>
     * <li>#RGBA (hex 0..f)</li>
     * <li>#RRGGBB (hex 00..ff)</li>
     * <li>#RRGGBBAA (hex 00..ff)</li>
     * <li>rgb(r,g,b) (0..255 or 0%..100%)</li>
     * <li>java.awt.Color[r=r,g=g,b=b] (0..255)</li>
     * <li>system-color(colorname)</li>
     * <li>transparent</li>
     * <li>colorname</li>
     * <li>fop-rgb-icc(r,g,b,cs,cs-src,[num]+) (r/g/b: 0..1, num: 0..1)</li>
     * <li>cmyk(c,m,y,k) (0..1)</li>
     * </ul>
     *
     * @param foUserAgent FOUserAgent object
     * @param value
     *            the string to parse.
     * @return a Color representing the string if possible
     * @throws PropertyException
     *             if the string is not parsable or does not follow any of the
     *             given formats.
     */
    public static Color parseColorString(FOUserAgent foUserAgent, String value)
            throws PropertyException {
        if (value == null) {
            return null;
        }

        Color parsedColor = (Color) colorMap.get(value.toLowerCase());

        if (parsedColor == null) {
            if (value.startsWith("#")) {
                parsedColor = parseWithHash(value);
            } else if (value.startsWith("rgb(")) {
                parsedColor = parseAsRGB(value);
            } else if (value.startsWith("url(")) {
                throw new PropertyException(
                        "Colors starting with url( are not yet supported!");
            } else if (value.startsWith("java.awt.Color")) {
                parsedColor = parseAsJavaAWTColor(value);
            } else if (value.startsWith("system-color(")) {
                parsedColor = parseAsSystemColor(value);
            } else if (value.startsWith("fop-rgb-icc")) {
                parsedColor = parseAsFopRgbIcc(foUserAgent, value);
            } else if (value.startsWith("cmyk")) {
                parsedColor = parseAsCMYK(value);
            }

            if (parsedColor == null) {
                throw new PropertyException("Unknown Color: " + value);
            }

            colorMap.put(value, parsedColor);
        }

        // TODO - Returned Color object can be one from the static colorMap cache.
        //        That means it should be treated as read only for the rest of its lifetime.
        //        Not sure that is the case though.
        return parsedColor;
    }

    /**
     * Tries to parse a color given with the system-color() function.
     *
     * @param value
     *            the complete line
     * @return a color if possible
     * @throws PropertyException
     *             if the format is wrong.
     */
    private static Color parseAsSystemColor(String value)
            throws PropertyException {
        int poss = value.indexOf("(");
        int pose = value.indexOf(")");
        if (poss != -1 && pose != -1) {
            value = value.substring(poss + 1, pose);
        } else {
            throw new PropertyException("Unknown color format: " + value
                    + ". Must be system-color(x)");
        }
        return (Color) colorMap.get(value);
    }

    /**
     * Tries to parse the standard java.awt.Color toString output.
     *
     * @param value
     *            the complete line
     * @return a color if possible
     * @throws PropertyException
     *             if the format is wrong.
     * @see java.awt.Color#toString()
     */
    private static Color parseAsJavaAWTColor(String value)
            throws PropertyException {
        float red = 0.0f, green = 0.0f, blue = 0.0f;
        int poss = value.indexOf("[");
        int pose = value.indexOf("]");
        try {
            if (poss != -1 && pose != -1) {
                value = value.substring(poss + 1, pose);
                String[] args = value.split(",");
                if (args.length != 3) {
                    throw new PropertyException(
                            "Invalid number of arguments for a java.awt.Color: " + value);
                }

                red = Float.parseFloat(args[0].trim().substring(2)) / 255f;
                green = Float.parseFloat(args[1].trim().substring(2)) / 255f;
                blue = Float.parseFloat(args[2].trim().substring(2)) / 255f;
                if ((red < 0.0 || red > 1.0)
                        || (green < 0.0 || green > 1.0)
                        || (blue < 0.0 || blue > 1.0)) {
                    throw new PropertyException("Color values out of range");
                }
            } else {
                throw new IllegalArgumentException(
                            "Invalid format for a java.awt.Color: " + value);
            }
        } catch (PropertyException pe) {
            throw pe;
        } catch (Exception e) {
            throw new PropertyException(e);
        }
        return new Color(red, green, blue);
    }

    /**
     * Parse a color given with the rgb() function.
     *
     * @param value
     *            the complete line
     * @return a color if possible
     * @throws PropertyException
     *             if the format is wrong.
     */
    private static Color parseAsRGB(String value) throws PropertyException {
        Color parsedColor;
        int poss = value.indexOf("(");
        int pose = value.indexOf(")");
        if (poss != -1 && pose != -1) {
            value = value.substring(poss + 1, pose);
            try {
                String[] args = value.split(",");
                if (args.length != 3) {
                    throw new PropertyException(
                            "Invalid number of arguments: rgb(" + value + ")");
                }
                float red = 0.0f, green = 0.0f, blue = 0.0f;
                String str = args[0].trim();
                if (str.endsWith("%")) {
                    red = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100f;
                } else {
                    red = Float.parseFloat(str) / 255f;
                }
                str = args[1].trim();
                if (str.endsWith("%")) {
                    green = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100f;
                } else {
                    green = Float.parseFloat(str) / 255f;
                }
                str = args[2].trim();
                if (str.endsWith("%")) {
                    blue = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100f;
                } else {
                    blue = Float.parseFloat(str) / 255f;
                }
                if ((red < 0.0 || red > 1.0)
                        || (green < 0.0 || green > 1.0)
                        || (blue < 0.0 || blue > 1.0)) {
                    throw new PropertyException("Color values out of range");
                }
                parsedColor = new Color(red, green, blue);
            } catch (PropertyException pe) {
                //simply re-throw
                throw pe;
            } catch (Exception e) {
                //wrap in a PropertyException
                throw new PropertyException(e);
            }
        } else {
            throw new PropertyException("Unknown color format: " + value
                    + ". Must be rgb(r,g,b)");
        }
        return parsedColor;
    }

    /**
     * parse a color given in the #.... format.
     *
     * @param value
     *            the complete line
     * @return a color if possible
     * @throws PropertyException
     *             if the format is wrong.
     */
    private static Color parseWithHash(String value) throws PropertyException {
        Color parsedColor = null;
        try {
            int len = value.length();
            int alpha;
            if (len == 5 || len == 9) {
                alpha = Integer.parseInt(
                        value.substring((len == 5) ? 3 : 7), 16);
            } else {
                alpha = 0xFF;
            }
            int red = 0, green = 0, blue = 0;
            if ((len == 4) || (len == 5)) {
                //multiply by 0x11 = 17 = 255/15
                red = Integer.parseInt(value.substring(1, 2), 16) * 0x11;
                green = Integer.parseInt(value.substring(2, 3), 16) * 0x11;
                blue = Integer.parseInt(value.substring(3, 4), 16) * 0X11;
            } else if ((len == 7) || (len == 9)) {
                red = Integer.parseInt(value.substring(1, 3), 16);
                green = Integer.parseInt(value.substring(3, 5), 16);
                blue = Integer.parseInt(value.substring(5, 7), 16);
            } else {
                throw new NumberFormatException();
            }
            parsedColor = new Color(red, green, blue, alpha);
        } catch (Exception e) {
            throw new PropertyException("Unknown color format: " + value
                    + ". Must be #RGB. #RGBA, #RRGGBB, or #RRGGBBAA");
        }
        return parsedColor;
    }

    /**
     * Parse a color specified using the fop-rgb-icc() function.
     *
     * @param value the function call
     * @return a color if possible
     * @throws PropertyException if the format is wrong.
     */
    private static Color parseAsFopRgbIcc(FOUserAgent foUserAgent, String value)
            throws PropertyException {
        Color parsedColor;
        int poss = value.indexOf("(");
        int pose = value.indexOf(")");
        if (poss != -1 && pose != -1) {
            String[] args = value.substring(poss + 1, pose).split(",");

            try {
                if (args.length < 5) {
                    throw new PropertyException("Too few arguments for rgb-icc() function");
                }
                /* Get and verify ICC profile name */
                String iccProfileName = args[3].trim();
                if (iccProfileName == null || "".equals(iccProfileName)) {
                    throw new PropertyException("ICC profile name missing");
                }
                /* Get and verify ICC profile source */
                String iccProfileSrc = args[4].trim();
                if (iccProfileSrc == null || "".equals(iccProfileSrc)) {
                    throw new PropertyException("ICC profile source missing");
                }
                if (iccProfileSrc.startsWith("\"") || iccProfileSrc.startsWith("'")) {
                    iccProfileSrc = iccProfileSrc.substring(1);
                }
                if (iccProfileSrc.endsWith("\"") || iccProfileSrc.endsWith("'")) {
                    iccProfileSrc = iccProfileSrc.substring(0, iccProfileSrc.length() - 1);
                }
                /* ICC profile arguments */
                float[] iccComponents = new float[args.length - 5];
                for (int ix = 4; ++ix < args.length;) {
                    iccComponents[ix - 5] = Float.parseFloat(args[ix].trim());
                }
                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
                ColorSpace colorSpace = (foUserAgent != null
                        ? foUserAgent.getFactory().getColorSpace(
                                foUserAgent.getBaseURL(), iccProfileSrc) : null);

                float red = 0, green = 0, blue = 0;
                red = Float.parseFloat(args[0].trim());
                green = Float.parseFloat(args[1].trim());
                blue = Float.parseFloat(args[2].trim());
                /* Verify rgb replacement arguments */
                if ((red < 0 || red > 1)
                        || (green < 0 || green > 1)
                        || (blue < 0 || blue > 1)) {
                    throw new PropertyException("Color values out of range. "
                            + "Fallback RGB arguments to fop-rgb-icc() must be [0..1]");
                }

                if (colorSpace != null) {
                    // ColorSpace available - create ColorExt (keeps track of replacement rgb
                    // values for possible later colorTOsRGBString call
                    parsedColor = ColorExt.createFromFoRgbIcc(red, green, blue,
                            iccProfileName, iccProfileSrc, colorSpace, iccComponents);
                } else {
                    // ICC profile could not be loaded - use rgb replacement values */
                    log.warn("Color profile '" + iccProfileSrc
                            + "' not found. Using rgb replacement values.");
                    parsedColor = new Color(Math.round(red * 255),
                            Math.round(green * 255), Math.round(blue * 255));
                }
            } catch (PropertyException pe) {
                //simply re-throw
                throw pe;
            } catch (Exception e) {
                //wrap in a PropertyException
                throw new PropertyException(e);
            }
        } else {
            throw new PropertyException("Unknown color format: " + value
                    + ". Must be fop-rgb-icc(r,g,b,NCNAME,src,....)");
        }
        return parsedColor;
    }

    /**
     * Parse a color given with the cmyk() function.
     *
     * @param value
     *            the complete line
     * @return a color if possible
     * @throws PropertyException
     *             if the format is wrong.
     */
    private static Color parseAsCMYK(String value) throws PropertyException {
        Color parsedColor;
        int poss = value.indexOf("(");
        int pose = value.indexOf(")");
        if (poss != -1 && pose != -1) {
            value = value.substring(poss + 1, pose);
            String[] args = value.split(",");
            try {
                if (args.length != 4) {
                    throw new PropertyException(
                            "Invalid number of arguments: cmyk(" + value + ")");
                }
                float cyan = 0.0f, magenta = 0.0f, yellow = 0.0f, black = 0.0f;
                String str = args[0].trim();
                if (str.endsWith("%")) {
                  cyan  = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100.0f;
                } else {
                  cyan  = Float.parseFloat(str);
                }
                str = args[1].trim();
                if (str.endsWith("%")) {
                  magenta = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100.0f;
                } else {
                  magenta = Float.parseFloat(str);
                }
                str = args[2].trim();
                if (str.endsWith("%")) {
                  yellow = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100.0f;
                } else {
                  yellow = Float.parseFloat(str);
                }
                str = args[3].trim();
                if (str.endsWith("%")) {
                  black = Float.parseFloat(str.substring(0,
                            str.length() - 1)) / 100.0f;
                } else {
                  black = Float.parseFloat(str);
                }

                if ((cyan < 0.0 || cyan > 1.0)
                        || (magenta < 0.0 || magenta > 1.0)
                        || (yellow < 0.0 || yellow > 1.0)
                        || (black < 0.0 || black > 1.0)) {
                    throw new PropertyException("Color values out of range"
                            + "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]");
                }
                float[] cmyk = new float[] {cyan, magenta, yellow, black};
                CMYKColorSpace cmykCs = CMYKColorSpace.getInstance();
                float[] rgb = cmykCs.toRGB(cmyk);
                parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
                        null, "#CMYK", cmykCs, cmyk);
            } catch (PropertyException pe) {
                throw pe;
            } catch (Exception e) {
                throw new PropertyException(e);
            }
        } else {
            throw new PropertyException("Unknown color format: " + value
                    + ". Must be cmyk(c,m,y,k)");
        }
        return parsedColor;
    }

    /**
     * Creates a re-parsable string representation of the given color.
     * <p>
     * First, the color will be converted into the sRGB colorspace. It will then
     * be printed as #rrggbb, or as #rrrggbbaa if an alpha value is present.
     *
     * @param color
     *            the color to represent.
     * @return a re-parsable string representadion.
     */
    public static String colorToString(Color color) {
        ColorSpace cs = color.getColorSpace();
        if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
            StringBuffer sbuf = new StringBuffer(24);
            float[] cmyk = color.getColorComponents(null);
            sbuf.append("cmyk(" + cmyk[0] + "," + cmyk[1] + "," + cmyk[2] + "," +  cmyk[3] + ")");
            return sbuf.toString();
        } else if (color instanceof ColorExt) {
            return ((ColorExt)color).toFunctionCall();
        } else {
            StringBuffer sbuf = new StringBuffer();
            sbuf.append('#');
            String s = Integer.toHexString(color.getRed());
            if (s.length() == 1) {
                sbuf.append('0');
            }
            sbuf.append(s);
            s = Integer.toHexString(color.getGreen());
            if (s.length() == 1) {
                sbuf.append('0');
            }
            sbuf.append(s);
            s = Integer.toHexString(color.getBlue());
            if (s.length() == 1) {
                sbuf.append('0');
            }
            sbuf.append(s);
            if (color.getAlpha() != 255) {
                s = Integer.toHexString(color.getAlpha());
                if (s.length() == 1) {
                    sbuf.append('0');
                }
                sbuf.append(s);
            }
            return sbuf.toString();
        }
    }

    /**
     * Initializes the colorMap with some predefined values.
     */
    private static void initializeColorMap() {
        colorMap = Collections.synchronizedMap(new java.util.HashMap());

        colorMap.put("aliceblue", new Color(240, 248, 255));
        colorMap.put("antiquewhite", new Color(250, 235, 215));
        colorMap.put("aqua", new Color(0, 255, 255));
        colorMap.put("aquamarine", new Color(127, 255, 212));
        colorMap.put("azure", new Color(240, 255, 255));
        colorMap.put("beige", new Color(245, 245, 220));
        colorMap.put("bisque", new Color(255, 228, 196));
        colorMap.put("black", new Color(0, 0, 0));
        colorMap.put("blanchedalmond", new Color(255, 235, 205));
        colorMap.put("blue", new Color(0, 0, 255));
        colorMap.put("blueviolet", new Color(138, 43, 226));
        colorMap.put("brown", new Color(165, 42, 42));
        colorMap.put("burlywood", new Color(222, 184, 135));
        colorMap.put("cadetblue", new Color(95, 158, 160));
        colorMap.put("chartreuse", new Color(127, 255, 0));
        colorMap.put("chocolate", new Color(210, 105, 30));
        colorMap.put("coral", new Color(255, 127, 80));
        colorMap.put("cornflowerblue", new Color(100, 149, 237));
        colorMap.put("cornsilk", new Color(255, 248, 220));
        colorMap.put("crimson", new Color(220, 20, 60));
        colorMap.put("cyan", new Color(0, 255, 255));
        colorMap.put("darkblue", new Color(0, 0, 139));
        colorMap.put("darkcyan", new Color(0, 139, 139));
        colorMap.put("darkgoldenrod", new Color(184, 134, 11));
        colorMap.put("darkgray", new Color(169, 169, 169));
        colorMap.put("darkgreen", new Color(0, 100, 0));
        colorMap.put("darkgrey", new Color(169, 169, 169));
        colorMap.put("darkkhaki", new Color(189, 183, 107));
        colorMap.put("darkmagenta", new Color(139, 0, 139));
        colorMap.put("darkolivegreen", new Color(85, 107, 47));
        colorMap.put("darkorange", new Color(255, 140, 0));
        colorMap.put("darkorchid", new Color(153, 50, 204));
        colorMap.put("darkred", new Color(139, 0, 0));
        colorMap.put("darksalmon", new Color(233, 150, 122));
        colorMap.put("darkseagreen", new Color(143, 188, 143));
        colorMap.put("darkslateblue", new Color(72, 61, 139));
        colorMap.put("darkslategray", new Color(47, 79, 79));
        colorMap.put("darkslategrey", new Color(47, 79, 79));
        colorMap.put("darkturquoise", new Color(0, 206, 209));
        colorMap.put("darkviolet", new Color(148, 0, 211));
        colorMap.put("deeppink", new Color(255, 20, 147));
        colorMap.put("deepskyblue", new Color(0, 191, 255));
        colorMap.put("dimgray", new Color(105, 105, 105));
        colorMap.put("dimgrey", new Color(105, 105, 105));
        colorMap.put("dodgerblue", new Color(30, 144, 255));
        colorMap.put("firebrick", new Color(178, 34, 34));
        colorMap.put("floralwhite", new Color(255, 250, 240));
        colorMap.put("forestgreen", new Color(34, 139, 34));
        colorMap.put("fuchsia", new Color(255, 0, 255));
        colorMap.put("gainsboro", new Color(220, 220, 220));
        colorMap.put("ghostwhite", new Color(248, 248, 255));
        colorMap.put("gold", new Color(255, 215, 0));
        colorMap.put("goldenrod", new Color(218, 165, 32));
        colorMap.put("gray", new Color(128, 128, 128));
        colorMap.put("green", new Color(0, 128, 0));
        colorMap.put("greenyellow", new Color(173, 255, 47));
        colorMap.put("grey", new Color(128, 128, 128));
        colorMap.put("honeydew", new Color(240, 255, 240));
        colorMap.put("hotpink", new Color(255, 105, 180));
        colorMap.put("indianred", new Color(205, 92, 92));
        colorMap.put("indigo", new Color(75, 0, 130));
        colorMap.put("ivory", new Color(255, 255, 240));
        colorMap.put("khaki", new Color(240, 230, 140));
        colorMap.put("lavender", new Color(230, 230, 250));
        colorMap.put("lavenderblush", new Color(255, 240, 245));
        colorMap.put("lawngreen", new Color(124, 252, 0));
        colorMap.put("lemonchiffon", new Color(255, 250, 205));
        colorMap.put("lightblue", new Color(173, 216, 230));
        colorMap.put("lightcoral", new Color(240, 128, 128));
        colorMap.put("lightcyan", new Color(224, 255, 255));
        colorMap.put("lightgoldenrodyellow", new Color(250, 250, 210));
        colorMap.put("lightgray", new Color(211, 211, 211));
        colorMap.put("lightgreen", new Color(144, 238, 144));
        colorMap.put("lightgrey", new Color(211, 211, 211));
        colorMap.put("lightpink", new Color(255, 182, 193));
        colorMap.put("lightsalmon", new Color(255, 160, 122));
        colorMap.put("lightseagreen", new Color(32, 178, 170));
        colorMap.put("lightskyblue", new Color(135, 206, 250));
        colorMap.put("lightslategray", new Color(119, 136, 153));
        colorMap.put("lightslategrey", new Color(119, 136, 153));
        colorMap.put("lightsteelblue", new Color(176, 196, 222));
        colorMap.put("lightyellow", new Color(255, 255, 224));
        colorMap.put("lime", new Color(0, 255, 0));
        colorMap.put("limegreen", new Color(50, 205, 50));
        colorMap.put("linen", new Color(250, 240, 230));
        colorMap.put("magenta", new Color(255, 0, 255));
        colorMap.put("maroon", new Color(128, 0, 0));
        colorMap.put("mediumaquamarine", new Color(102, 205, 170));
        colorMap.put("mediumblue", new Color(0, 0, 205));
        colorMap.put("mediumorchid", new Color(186, 85, 211));
        colorMap.put("mediumpurple", new Color(147, 112, 219));
        colorMap.put("mediumseagreen", new Color(60, 179, 113));
        colorMap.put("mediumslateblue", new Color(123, 104, 238));
        colorMap.put("mediumspringgreen", new Color(0, 250, 154));
        colorMap.put("mediumturquoise", new Color(72, 209, 204));
        colorMap.put("mediumvioletred", new Color(199, 21, 133));
        colorMap.put("midnightblue", new Color(25, 25, 112));
        colorMap.put("mintcream", new Color(245, 255, 250));
        colorMap.put("mistyrose", new Color(255, 228, 225));
        colorMap.put("moccasin", new Color(255, 228, 181));
        colorMap.put("navajowhite", new Color(255, 222, 173));
        colorMap.put("navy", new Color(0, 0, 128));
        colorMap.put("oldlace", new Color(253, 245, 230));
        colorMap.put("olive", new Color(128, 128, 0));
        colorMap.put("olivedrab", new Color(107, 142, 35));
        colorMap.put("orange", new Color(255, 165, 0));
        colorMap.put("orangered", new Color(255, 69, 0));
        colorMap.put("orchid", new Color(218, 112, 214));
        colorMap.put("palegoldenrod", new Color(238, 232, 170));
        colorMap.put("palegreen", new Color(152, 251, 152));
        colorMap.put("paleturquoise", new Color(175, 238, 238));
        colorMap.put("palevioletred", new Color(219, 112, 147));
        colorMap.put("papayawhip", new Color(255, 239, 213));
        colorMap.put("peachpuff", new Color(255, 218, 185));
        colorMap.put("peru", new Color(205, 133, 63));
        colorMap.put("pink", new Color(255, 192, 203));
        colorMap.put("plum ", new Color(221, 160, 221));
        colorMap.put("plum", new Color(221, 160, 221));
        colorMap.put("powderblue", new Color(176, 224, 230));
        colorMap.put("purple", new Color(128, 0, 128));
        colorMap.put("red", new Color(255, 0, 0));
        colorMap.put("rosybrown", new Color(188, 143, 143));
        colorMap.put("royalblue", new Color(65, 105, 225));
        colorMap.put("saddlebrown", new Color(139, 69, 19));
        colorMap.put("salmon", new Color(250, 128, 114));
        colorMap.put("sandybrown", new Color(244, 164, 96));
        colorMap.put("seagreen", new Color(46, 139, 87));
        colorMap.put("seashell", new Color(255, 245, 238));
        colorMap.put("sienna", new Color(160, 82, 45));
        colorMap.put("silver", new Color(192, 192, 192));
        colorMap.put("skyblue", new Color(135, 206, 235));
        colorMap.put("slateblue", new Color(106, 90, 205));
        colorMap.put("slategray", new Color(112, 128, 144));
        colorMap.put("slategrey", new Color(112, 128, 144));
        colorMap.put("snow", new Color(255, 250, 250));
        colorMap.put("springgreen", new Color(0, 255, 127));
        colorMap.put("steelblue", new Color(70, 130, 180));
        colorMap.put("tan", new Color(210, 180, 140));
        colorMap.put("teal", new Color(0, 128, 128));
        colorMap.put("thistle", new Color(216, 191, 216));
        colorMap.put("tomato", new Color(255, 99, 71));
        colorMap.put("turquoise", new Color(64, 224, 208));
        colorMap.put("violet", new Color(238, 130, 238));
        colorMap.put("wheat", new Color(245, 222, 179));
        colorMap.put("white", new Color(255, 255, 255));
        colorMap.put("whitesmoke", new Color(245, 245, 245));
        colorMap.put("yellow", new Color(255, 255, 0));
        colorMap.put("yellowgreen", new Color(154, 205, 50));
        colorMap.put("transparent", new Color(0, 0, 0, 0));
    }

    /**
     * Lightens up a color for groove, ridge, inset and outset border effects.
     * @param col the color to lighten up
     * @param factor factor by which to lighten up (negative values darken the color)
     * @return the modified color
     */
    public static Color lightenColor(Color col, float factor) {
        // TODO: This function converts the color into the sRGB namespace.
        // This should be avoided if possible.
        float[] cols = new float[4];
        cols = col.getRGBComponents(cols);
        if (factor > 0) {
            cols[0] += (1.0 - cols[0]) * factor;
            cols[1] += (1.0 - cols[1]) * factor;
            cols[2] += (1.0 - cols[2]) * factor;
        } else {
            cols[0] -= cols[0] * -factor;
            cols[1] -= cols[1] * -factor;
            cols[2] -= cols[2] * -factor;
        }
        return new Color(cols[0], cols[1], cols[2], cols[3]);
    }

}
