/*
 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text.html;

import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.HeadlessException;
import java.awt.Image;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.SizeRequirements;
import javax.swing.text.*;

/**
 * Defines a set of
 * <a href="http://www.w3.org/TR/REC-CSS1">CSS attributes</a>
 * as a typesafe enumeration.  The HTML View implementations use
 * CSS attributes to determine how they will render. This also defines
 * methods to map between CSS/HTML/StyleConstants. Any shorthand
 * properties, such as font, are mapped to the intrinsic properties.
 * <p>The following describes the CSS properties that are suppored by the
 * rendering engine:
 * <ul><li>font-family
 *   <li>font-style
 *   <li>font-size (supports relative units)
 *   <li>font-weight
 *   <li>font
 *   <li>color
 *   <li>background-color (with the exception of transparent)
 *   <li>background-image
 *   <li>background-repeat
 *   <li>background-position
 *   <li>background
 *   <li>background-repeat
 *   <li>text-decoration (with the exception of blink and overline)
 *   <li>vertical-align (only sup and super)
 *   <li>text-align (justify is treated as center)
 *   <li>margin-top
 *   <li>margin-right
 *   <li>margin-bottom
 *   <li>margin-left
 *   <li>margin
 *   <li>padding-top
 *   <li>padding-right
 *   <li>padding-bottom
 *   <li>padding-left
 *   <li>border-style (only supports inset, outset and none)
 *   <li>list-style-type
 *   <li>list-style-position
 * </ul>
 * The following are modeled, but currently not rendered.
 * <ul><li>font-variant
 *   <li>background-attachment (background always treated as scroll)
 *   <li>word-spacing
 *   <li>letter-spacing
 *   <li>text-indent
 *   <li>text-transform
 *   <li>line-height
 *   <li>border-top-width (this is used to indicate if a border should be used)
 *   <li>border-right-width
 *   <li>border-bottom-width
 *   <li>border-left-width
 *   <li>border-width
 *   <li>border-top
 *   <li>border-right
 *   <li>border-bottom
 *   <li>border-left
 *   <li>border
 *   <li>width
 *   <li>height
 *   <li>float
 *   <li>clear
 *   <li>display
 *   <li>white-space
 *   <li>list-style
 * </ul>
 * <p><b>Note: for the time being we do not fully support relative units,
 * unless noted, so that
 * p { margin-top: 10% } will be treated as if no margin-top was specified.
 *
 * @author  Timothy Prinzing
 * @author  Scott Violet
 * @see StyleSheet
 */
public class CSS implements Serializable {

    /**
     * Definitions to be used as a key on AttributeSet's
     * that might hold CSS attributes.  Since this is a
     * closed set (i.e. defined exactly by the specification),
     * it is final and cannot be extended.
     */
    public static final class Attribute {

        private Attribute(String name, String defaultValue, boolean inherited) {
            this.name = name;
            this.defaultValue = defaultValue;
            this.inherited = inherited;
        }

        /**
         * The string representation of the attribute.  This
         * should exactly match the string specified in the
         * CSS specification.
         */
        public String toString() {
            return name;
        }

        /**
         * Fetch the default value for the attribute.
         * If there is no default value (such as for
         * composite attributes), null will be returned.
         */
        public String getDefaultValue() {
            return defaultValue;
        }

        /**
         * Indicates if the attribute should be inherited
         * from the parent or not.
         */
        public boolean isInherited() {
            return inherited;
        }

        private String name;
        private String defaultValue;
        private boolean inherited;


        public static final Attribute BACKGROUND =
            new Attribute("background", null, false);

        public static final Attribute BACKGROUND_ATTACHMENT =
            new Attribute("background-attachment", "scroll", false);

        public static final Attribute BACKGROUND_COLOR =
            new Attribute("background-color", "transparent", false);

        public static final Attribute BACKGROUND_IMAGE =
            new Attribute("background-image", "none", false);

        public static final Attribute BACKGROUND_POSITION =
            new Attribute("background-position", null, false);

        public static final Attribute BACKGROUND_REPEAT =
            new Attribute("background-repeat", "repeat", false);

        public static final Attribute BORDER =
            new Attribute("border", null, false);

        public static final Attribute BORDER_BOTTOM =
            new Attribute("border-bottom", null, false);

        public static final Attribute BORDER_BOTTOM_COLOR =
            new Attribute("border-bottom-color", null, false);

        public static final Attribute BORDER_BOTTOM_STYLE =
            new Attribute("border-bottom-style", "none", false);

        public static final Attribute BORDER_BOTTOM_WIDTH =
            new Attribute("border-bottom-width", "medium", false);

        public static final Attribute BORDER_COLOR =
            new Attribute("border-color", null, false);

        public static final Attribute BORDER_LEFT =
            new Attribute("border-left", null, false);

        public static final Attribute BORDER_LEFT_COLOR =
            new Attribute("border-left-color", null, false);

        public static final Attribute BORDER_LEFT_STYLE =
            new Attribute("border-left-style", "none", false);

        public static final Attribute BORDER_LEFT_WIDTH =
            new Attribute("border-left-width", "medium", false);

        public static final Attribute BORDER_RIGHT =
            new Attribute("border-right", null, false);

        public static final Attribute BORDER_RIGHT_COLOR =
            new Attribute("border-right-color", null, false);

        public static final Attribute BORDER_RIGHT_STYLE =
            new Attribute("border-right-style", "none", false);

        public static final Attribute BORDER_RIGHT_WIDTH =
            new Attribute("border-right-width", "medium", false);

        public static final Attribute BORDER_STYLE =
            new Attribute("border-style", "none", false);

        public static final Attribute BORDER_TOP =
            new Attribute("border-top", null, false);

        public static final Attribute BORDER_TOP_COLOR =
            new Attribute("border-top-color", null, false);

        public static final Attribute BORDER_TOP_STYLE =
            new Attribute("border-top-style", "none", false);

        public static final Attribute BORDER_TOP_WIDTH =
            new Attribute("border-top-width", "medium", false);

        public static final Attribute BORDER_WIDTH =
            new Attribute("border-width", "medium", false);

        public static final Attribute CLEAR =
            new Attribute("clear", "none", false);

        public static final Attribute COLOR =
            new Attribute("color", "black", true);

        public static final Attribute DISPLAY =
            new Attribute("display", "block", false);

        public static final Attribute FLOAT =
            new Attribute("float", "none", false);

        public static final Attribute FONT =
            new Attribute("font", null, true);

        public static final Attribute FONT_FAMILY =
            new Attribute("font-family", null, true);

        public static final Attribute FONT_SIZE =
            new Attribute("font-size", "medium", true);

        public static final Attribute FONT_STYLE =
            new Attribute("font-style", "normal", true);

        public static final Attribute FONT_VARIANT =
            new Attribute("font-variant", "normal", true);

        public static final Attribute FONT_WEIGHT =
            new Attribute("font-weight", "normal", true);

        public static final Attribute HEIGHT =
            new Attribute("height", "auto", false);

        public static final Attribute LETTER_SPACING =
            new Attribute("letter-spacing", "normal", true);

        public static final Attribute LINE_HEIGHT =
            new Attribute("line-height", "normal", true);

        public static final Attribute LIST_STYLE =
            new Attribute("list-style", null, true);

        public static final Attribute LIST_STYLE_IMAGE =
            new Attribute("list-style-image", "none", true);

        public static final Attribute LIST_STYLE_POSITION =
            new Attribute("list-style-position", "outside", true);

        public static final Attribute LIST_STYLE_TYPE =
            new Attribute("list-style-type", "disc", true);

        public static final Attribute MARGIN =
            new Attribute("margin", null, false);

        public static final Attribute MARGIN_BOTTOM =
            new Attribute("margin-bottom", "0", false);

        public static final Attribute MARGIN_LEFT =
            new Attribute("margin-left", "0", false);

        public static final Attribute MARGIN_RIGHT =
            new Attribute("margin-right", "0", false);

        /*
         * made up css attributes to describe orientation depended
         * margins. used for <dir>, <menu>, <ul> etc. see
         * 5088268 for more details
         */
        static final Attribute MARGIN_LEFT_LTR =
            new Attribute("margin-left-ltr",
                          Integer.toString(Integer.MIN_VALUE), false);

        static final Attribute MARGIN_LEFT_RTL =
            new Attribute("margin-left-rtl",
                          Integer.toString(Integer.MIN_VALUE), false);

        static final Attribute MARGIN_RIGHT_LTR =
            new Attribute("margin-right-ltr",
                          Integer.toString(Integer.MIN_VALUE), false);

        static final Attribute MARGIN_RIGHT_RTL =
            new Attribute("margin-right-rtl",
                          Integer.toString(Integer.MIN_VALUE), false);


        public static final Attribute MARGIN_TOP =
            new Attribute("margin-top", "0", false);

        public static final Attribute PADDING =
            new Attribute("padding", null, false);

        public static final Attribute PADDING_BOTTOM =
            new Attribute("padding-bottom", "0", false);

        public static final Attribute PADDING_LEFT =
            new Attribute("padding-left", "0", false);

        public static final Attribute PADDING_RIGHT =
            new Attribute("padding-right", "0", false);

        public static final Attribute PADDING_TOP =
            new Attribute("padding-top", "0", false);

        public static final Attribute TEXT_ALIGN =
            new Attribute("text-align", null, true);

        public static final Attribute TEXT_DECORATION =
            new Attribute("text-decoration", "none", true);

        public static final Attribute TEXT_INDENT =
            new Attribute("text-indent", "0", true);

        public static final Attribute TEXT_TRANSFORM =
            new Attribute("text-transform", "none", true);

        public static final Attribute VERTICAL_ALIGN =
            new Attribute("vertical-align", "baseline", false);

        public static final Attribute WORD_SPACING =
            new Attribute("word-spacing", "normal", true);

        public static final Attribute WHITE_SPACE =
            new Attribute("white-space", "normal", true);

        public static final Attribute WIDTH =
            new Attribute("width", "auto", false);

        /*public*/ static final Attribute BORDER_SPACING =
            new Attribute("border-spacing", "0", true);

        /*public*/ static final Attribute CAPTION_SIDE =
            new Attribute("caption-side", "left", true);

        // All possible CSS attribute keys.
        static final Attribute[] allAttributes = {
            BACKGROUND, BACKGROUND_ATTACHMENT, BACKGROUND_COLOR,
            BACKGROUND_IMAGE, BACKGROUND_POSITION, BACKGROUND_REPEAT,
            BORDER, BORDER_BOTTOM, BORDER_BOTTOM_WIDTH, BORDER_COLOR,
            BORDER_LEFT, BORDER_LEFT_WIDTH, BORDER_RIGHT, BORDER_RIGHT_WIDTH,
            BORDER_STYLE, BORDER_TOP, BORDER_TOP_WIDTH, BORDER_WIDTH,
            BORDER_TOP_STYLE, BORDER_RIGHT_STYLE, BORDER_BOTTOM_STYLE,
            BORDER_LEFT_STYLE,
            BORDER_TOP_COLOR, BORDER_RIGHT_COLOR, BORDER_BOTTOM_COLOR,
            BORDER_LEFT_COLOR,
            CLEAR, COLOR, DISPLAY, FLOAT, FONT, FONT_FAMILY, FONT_SIZE,
            FONT_STYLE, FONT_VARIANT, FONT_WEIGHT, HEIGHT, LETTER_SPACING,
            LINE_HEIGHT, LIST_STYLE, LIST_STYLE_IMAGE, LIST_STYLE_POSITION,
            LIST_STYLE_TYPE, MARGIN, MARGIN_BOTTOM, MARGIN_LEFT, MARGIN_RIGHT,
            MARGIN_TOP, PADDING, PADDING_BOTTOM, PADDING_LEFT, PADDING_RIGHT,
            PADDING_TOP, TEXT_ALIGN, TEXT_DECORATION, TEXT_INDENT, TEXT_TRANSFORM,
            VERTICAL_ALIGN, WORD_SPACING, WHITE_SPACE, WIDTH,
            BORDER_SPACING, CAPTION_SIDE,
            MARGIN_LEFT_LTR, MARGIN_LEFT_RTL, MARGIN_RIGHT_LTR, MARGIN_RIGHT_RTL
        };

        private static final Attribute[] ALL_MARGINS =
                { MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM, MARGIN_LEFT };
        private static final Attribute[] ALL_PADDING =
                { PADDING_TOP, PADDING_RIGHT, PADDING_BOTTOM, PADDING_LEFT };
        private static final Attribute[] ALL_BORDER_WIDTHS =
                { BORDER_TOP_WIDTH, BORDER_RIGHT_WIDTH, BORDER_BOTTOM_WIDTH,
                  BORDER_LEFT_WIDTH };
        private static final Attribute[] ALL_BORDER_STYLES =
                { BORDER_TOP_STYLE, BORDER_RIGHT_STYLE, BORDER_BOTTOM_STYLE,
                  BORDER_LEFT_STYLE };
        private static final Attribute[] ALL_BORDER_COLORS =
                { BORDER_TOP_COLOR, BORDER_RIGHT_COLOR, BORDER_BOTTOM_COLOR,
                  BORDER_LEFT_COLOR };

    }

    static final class Value {

        private Value(String name) {
            this.name = name;
        }

        /**
         * The string representation of the attribute.  This
         * should exactly match the string specified in the
         * CSS specification.
         */
        public String toString() {
            return name;
        }

        static final Value INHERITED = new Value("inherited");
        static final Value NONE = new Value("none");
        static final Value HIDDEN = new Value("hidden");
        static final Value DOTTED = new Value("dotted");
        static final Value DASHED = new Value("dashed");
        static final Value SOLID = new Value("solid");
        static final Value DOUBLE = new Value("double");
        static final Value GROOVE = new Value("groove");
        static final Value RIDGE = new Value("ridge");
        static final Value INSET = new Value("inset");
        static final Value OUTSET = new Value("outset");
        // Lists.
        static final Value DISC = new Value("disc");
        static final Value CIRCLE = new Value("circle");
        static final Value SQUARE = new Value("square");
        static final Value DECIMAL = new Value("decimal");
        static final Value LOWER_ROMAN = new Value("lower-roman");
        static final Value UPPER_ROMAN = new Value("upper-roman");
        static final Value LOWER_ALPHA = new Value("lower-alpha");
        static final Value UPPER_ALPHA = new Value("upper-alpha");
        // background-repeat
        static final Value BACKGROUND_NO_REPEAT = new Value("no-repeat");
        static final Value BACKGROUND_REPEAT = new Value("repeat");
        static final Value BACKGROUND_REPEAT_X = new Value("repeat-x");
        static final Value BACKGROUND_REPEAT_Y = new Value("repeat-y");
        // background-attachment
        static final Value BACKGROUND_SCROLL = new Value("scroll");
        static final Value BACKGROUND_FIXED = new Value("fixed");

        private String name;

        static final Value[] allValues = {
            INHERITED, NONE, DOTTED, DASHED, SOLID, DOUBLE, GROOVE,
            RIDGE, INSET, OUTSET, DISC, CIRCLE, SQUARE, DECIMAL,
            LOWER_ROMAN, UPPER_ROMAN, LOWER_ALPHA, UPPER_ALPHA,
            BACKGROUND_NO_REPEAT, BACKGROUND_REPEAT,
            BACKGROUND_REPEAT_X, BACKGROUND_REPEAT_Y,
            BACKGROUND_FIXED, BACKGROUND_FIXED
        };
    }

    public CSS() {
        baseFontSize = baseFontSizeIndex + 1;
        // setup the css conversion table
        valueConvertor = new Hashtable<Object, Object>();
        valueConvertor.put(CSS.Attribute.FONT_SIZE, new FontSize());
        valueConvertor.put(CSS.Attribute.FONT_FAMILY, new FontFamily());
        valueConvertor.put(CSS.Attribute.FONT_WEIGHT, new FontWeight());
        Object bs = new BorderStyle();
        valueConvertor.put(CSS.Attribute.BORDER_TOP_STYLE, bs);
        valueConvertor.put(CSS.Attribute.BORDER_RIGHT_STYLE, bs);
        valueConvertor.put(CSS.Attribute.BORDER_BOTTOM_STYLE, bs);
        valueConvertor.put(CSS.Attribute.BORDER_LEFT_STYLE, bs);
        Object cv = new ColorValue();
        valueConvertor.put(CSS.Attribute.COLOR, cv);
        valueConvertor.put(CSS.Attribute.BACKGROUND_COLOR, cv);
        valueConvertor.put(CSS.Attribute.BORDER_TOP_COLOR, cv);
        valueConvertor.put(CSS.Attribute.BORDER_RIGHT_COLOR, cv);
        valueConvertor.put(CSS.Attribute.BORDER_BOTTOM_COLOR, cv);
        valueConvertor.put(CSS.Attribute.BORDER_LEFT_COLOR, cv);
        Object lv = new LengthValue();
        valueConvertor.put(CSS.Attribute.MARGIN_TOP, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_BOTTOM, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_LEFT, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_LEFT_LTR, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_LEFT_RTL, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_RIGHT, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_RIGHT_LTR, lv);
        valueConvertor.put(CSS.Attribute.MARGIN_RIGHT_RTL, lv);
        valueConvertor.put(CSS.Attribute.PADDING_TOP, lv);
        valueConvertor.put(CSS.Attribute.PADDING_BOTTOM, lv);
        valueConvertor.put(CSS.Attribute.PADDING_LEFT, lv);
        valueConvertor.put(CSS.Attribute.PADDING_RIGHT, lv);
        Object bv = new BorderWidthValue(null, 0);
        valueConvertor.put(CSS.Attribute.BORDER_TOP_WIDTH, bv);
        valueConvertor.put(CSS.Attribute.BORDER_BOTTOM_WIDTH, bv);
        valueConvertor.put(CSS.Attribute.BORDER_LEFT_WIDTH, bv);
        valueConvertor.put(CSS.Attribute.BORDER_RIGHT_WIDTH, bv);
        Object nlv = new LengthValue(true);
        valueConvertor.put(CSS.Attribute.TEXT_INDENT, nlv);
        valueConvertor.put(CSS.Attribute.WIDTH, lv);
        valueConvertor.put(CSS.Attribute.HEIGHT, lv);
        valueConvertor.put(CSS.Attribute.BORDER_SPACING, lv);
        Object sv = new StringValue();
        valueConvertor.put(CSS.Attribute.FONT_STYLE, sv);
        valueConvertor.put(CSS.Attribute.TEXT_DECORATION, sv);
        valueConvertor.put(CSS.Attribute.TEXT_ALIGN, sv);
        valueConvertor.put(CSS.Attribute.VERTICAL_ALIGN, sv);
        Object valueMapper = new CssValueMapper();
        valueConvertor.put(CSS.Attribute.LIST_STYLE_TYPE,
                           valueMapper);
        valueConvertor.put(CSS.Attribute.BACKGROUND_IMAGE,
                           new BackgroundImage());
        valueConvertor.put(CSS.Attribute.BACKGROUND_POSITION,
                           new BackgroundPosition());
        valueConvertor.put(CSS.Attribute.BACKGROUND_REPEAT,
                           valueMapper);
        valueConvertor.put(CSS.Attribute.BACKGROUND_ATTACHMENT,
                           valueMapper);
        Object generic = new CssValue();
        int n = CSS.Attribute.allAttributes.length;
        for (int i = 0; i < n; i++) {
            CSS.Attribute key = CSS.Attribute.allAttributes[i];
            if (valueConvertor.get(key) == null) {
                valueConvertor.put(key, generic);
            }
        }
    }

    /**
     * Sets the base font size. <code>sz</code> is a CSS value, and is
     * not necessarily the point size. Use getPointSize to determine the
     * point size corresponding to <code>sz</code>.
     */
    void setBaseFontSize(int sz) {
        if (sz < 1)
          baseFontSize = 0;
        else if (sz > 7)
          baseFontSize = 7;
        else
          baseFontSize = sz;
    }

    /**
     * Sets the base font size from the passed in string.
     */
    void setBaseFontSize(String size) {
        int relSize, absSize, diff;

        if (size != null) {
            if (size.startsWith("+")) {
                relSize = Integer.valueOf(size.substring(1)).intValue();
                setBaseFontSize(baseFontSize + relSize);
            } else if (size.startsWith("-")) {
                relSize = -Integer.valueOf(size.substring(1)).intValue();
                setBaseFontSize(baseFontSize + relSize);
            } else {
                setBaseFontSize(Integer.valueOf(size).intValue());
            }
        }
    }

    /**
     * Returns the base font size.
     */
    int getBaseFontSize() {
        return baseFontSize;
    }

    /**
     * Parses the CSS property <code>key</code> with value
     * <code>value</code> placing the result in <code>att</code>.
     */
    void addInternalCSSValue(MutableAttributeSet attr,
                             CSS.Attribute key, String value) {
        if (key == CSS.Attribute.FONT) {
            ShorthandFontParser.parseShorthandFont(this, value, attr);
        }
        else if (key == CSS.Attribute.BACKGROUND) {
            ShorthandBackgroundParser.parseShorthandBackground
                               (this, value, attr);
        }
        else if (key == CSS.Attribute.MARGIN) {
            ShorthandMarginParser.parseShorthandMargin(this, value, attr,
                                           CSS.Attribute.ALL_MARGINS);
        }
        else if (key == CSS.Attribute.PADDING) {
            ShorthandMarginParser.parseShorthandMargin(this, value, attr,
                                           CSS.Attribute.ALL_PADDING);
        }
        else if (key == CSS.Attribute.BORDER_WIDTH) {
            ShorthandMarginParser.parseShorthandMargin(this, value, attr,
                                           CSS.Attribute.ALL_BORDER_WIDTHS);
        }
        else if (key == CSS.Attribute.BORDER_COLOR) {
            ShorthandMarginParser.parseShorthandMargin(this, value, attr,
                                            CSS.Attribute.ALL_BORDER_COLORS);
        }
        else if (key == CSS.Attribute.BORDER_STYLE) {
            ShorthandMarginParser.parseShorthandMargin(this, value, attr,
                                            CSS.Attribute.ALL_BORDER_STYLES);
        }
        else if ((key == CSS.Attribute.BORDER) ||
                   (key == CSS.Attribute.BORDER_TOP) ||
                   (key == CSS.Attribute.BORDER_RIGHT) ||
                   (key == CSS.Attribute.BORDER_BOTTOM) ||
                   (key == CSS.Attribute.BORDER_LEFT)) {
            ShorthandBorderParser.parseShorthandBorder(attr, key, value);
        }
        else {
            Object iValue = getInternalCSSValue(key, value);
            if (iValue != null) {
                attr.addAttribute(key, iValue);
            }
        }
    }

    /**
     * Gets the internal CSS representation of <code>value</code> which is
     * a CSS value of the CSS attribute named <code>key</code>. The receiver
     * should not modify <code>value</code>, and the first <code>count</code>
     * strings are valid.
     */
    Object getInternalCSSValue(CSS.Attribute key, String value) {
        CssValue conv = (CssValue) valueConvertor.get(key);
        Object r = conv.parseCssValue(value);
        return r != null ? r : conv.parseCssValue(key.getDefaultValue());
    }

    /**
     * Maps from a StyleConstants to a CSS Attribute.
     */
    Attribute styleConstantsKeyToCSSKey(StyleConstants sc) {
        return styleConstantToCssMap.get(sc);
    }

    /**
     * Maps from a StyleConstants value to a CSS value.
     */
    Object styleConstantsValueToCSSValue(StyleConstants sc,
                                         Object styleValue) {
        Attribute cssKey = styleConstantsKeyToCSSKey(sc);
        if (cssKey != null) {
            CssValue conv = (CssValue)valueConvertor.get(cssKey);
            return conv.fromStyleConstants(sc, styleValue);
        }
        return null;
    }

    /**
     * Converts the passed in CSS value to a StyleConstants value.
     * <code>key</code> identifies the CSS attribute being mapped.
     */
    Object cssValueToStyleConstantsValue(StyleConstants key, Object value) {
        if (value instanceof CssValue) {
            return ((CssValue)value).toStyleConstants(key, null);
        }
        return null;
    }

    /**
     * Returns the font for the values in the passed in AttributeSet.
     * It is assumed the keys will be CSS.Attribute keys.
     * <code>sc</code> is the StyleContext that will be messaged to get
     * the font once the size, name and style have been determined.
     */
    Font getFont(StyleContext sc, AttributeSet a, int defaultSize, StyleSheet ss) {
        ss = getStyleSheet(ss);
        int size = getFontSize(a, defaultSize, ss);

        /*
         * If the vertical alignment is set to either superscirpt or
         * subscript we reduce the font size by 2 points.
         */
        StringValue vAlignV = (StringValue)a.getAttribute
                              (CSS.Attribute.VERTICAL_ALIGN);
        if ((vAlignV != null)) {
            String vAlign = vAlignV.toString();
            if ((vAlign.indexOf("sup") >= 0) ||
                (vAlign.indexOf("sub") >= 0)) {
                size -= 2;
            }
        }

        FontFamily familyValue = (FontFamily)a.getAttribute
                                            (CSS.Attribute.FONT_FAMILY);
        String family = (familyValue != null) ? familyValue.getValue() :
                                  Font.SANS_SERIF;
        int style = Font.PLAIN;
        FontWeight weightValue = (FontWeight) a.getAttribute
                                  (CSS.Attribute.FONT_WEIGHT);
        if ((weightValue != null) && (weightValue.getValue() > 400)) {
            style |= Font.BOLD;
        }
        Object fs = a.getAttribute(CSS.Attribute.FONT_STYLE);
        if ((fs != null) && (fs.toString().indexOf("italic") >= 0)) {
            style |= Font.ITALIC;
        }
        if (family.equalsIgnoreCase("monospace")) {
            family = Font.MONOSPACED;
        }
        Font f = sc.getFont(family, style, size);
        if (f == null
            || (f.getFamily().equals(Font.DIALOG)
                && ! family.equalsIgnoreCase(Font.DIALOG))) {
            family = Font.SANS_SERIF;
            f = sc.getFont(family, style, size);
        }
        return f;
    }

    static int getFontSize(AttributeSet attr, int defaultSize, StyleSheet ss) {
        // PENDING(prinz) this is a 1.1 based implementation, need to also
        // have a 1.2 version.
        FontSize sizeValue = (FontSize)attr.getAttribute(CSS.Attribute.
                                                         FONT_SIZE);

        return (sizeValue != null) ? sizeValue.getValue(attr, ss)
                                   : defaultSize;
    }

    /**
     * Takes a set of attributes and turn it into a color
     * specification.  This might be used to specify things
     * like brighter, more hue, etc.
     * This will return null if there is no value for <code>key</code>.
     *
     * @param key CSS.Attribute identifying where color is stored.
     * @param a the set of attributes
     * @return the color
     */
    Color getColor(AttributeSet a, CSS.Attribute key) {
        ColorValue cv = (ColorValue) a.getAttribute(key);
        if (cv != null) {
            return cv.getValue();
        }
        return null;
    }

    /**
     * Returns the size of a font from the passed in string.
     *
     * @param size CSS string describing font size
     * @param baseFontSize size to use for relative units.
     */
    float getPointSize(String size, StyleSheet ss) {
        int relSize, absSize, diff, index;
        ss = getStyleSheet(ss);
        if (size != null) {
            if (size.startsWith("+")) {
                relSize = Integer.valueOf(size.substring(1)).intValue();
                return getPointSize(baseFontSize + relSize, ss);
            } else if (size.startsWith("-")) {
                relSize = -Integer.valueOf(size.substring(1)).intValue();
                return getPointSize(baseFontSize + relSize, ss);
            } else {
                absSize = Integer.valueOf(size).intValue();
                return getPointSize(absSize, ss);
            }
        }
        return 0;
    }

    /**
     * Returns the length of the attribute in <code>a</code> with
     * key <code>key</code>.
     */
    float getLength(AttributeSet a, CSS.Attribute key, StyleSheet ss) {
        ss = getStyleSheet(ss);
        LengthValue lv = (LengthValue) a.getAttribute(key);
        boolean isW3CLengthUnits = (ss == null) ? false : ss.isW3CLengthUnits();
        float len = (lv != null) ? lv.getValue(isW3CLengthUnits) : 0;
        return len;
    }

    /**
     * Convert a set of HTML attributes to an equivalent
     * set of CSS attributes.
     *
     * @param htmlAttrSet AttributeSet containing the HTML attributes.
     * @return AttributeSet containing the corresponding CSS attributes.
     *        The AttributeSet will be empty if there are no mapping
     *        CSS attributes.
     */
    AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) {
        MutableAttributeSet cssAttrSet = new SimpleAttributeSet();
        Element elem = (Element)htmlAttrSet;
        HTML.Tag tag = getHTMLTag(htmlAttrSet);
        if ((tag == HTML.Tag.TD) || (tag == HTML.Tag.TH)) {
            // translate border width into the cells, if it has non-zero value.
            AttributeSet tableAttr = elem.getParentElement().
                                     getParentElement().getAttributes();
            int borderWidth;
            try {
                borderWidth = Integer.parseInt(
                    (String) tableAttr.getAttribute(HTML.Attribute.BORDER));
            } catch (NumberFormatException e) {
                borderWidth = 0;
            }
            if (borderWidth > 0) {
                translateAttribute(HTML.Attribute.BORDER, tableAttr, cssAttrSet);
            }
            String pad = (String)tableAttr.getAttribute(HTML.Attribute.CELLPADDING);
            if (pad != null) {
                LengthValue v =
                    (LengthValue)getInternalCSSValue(CSS.Attribute.PADDING_TOP, pad);
                v.span = (v.span < 0) ? 0 : v.span;
                cssAttrSet.addAttribute(CSS.Attribute.PADDING_TOP, v);
                cssAttrSet.addAttribute(CSS.Attribute.PADDING_BOTTOM, v);
                cssAttrSet.addAttribute(CSS.Attribute.PADDING_LEFT, v);
                cssAttrSet.addAttribute(CSS.Attribute.PADDING_RIGHT, v);
            }
        }
        if (elem.isLeaf()) {
            translateEmbeddedAttributes(htmlAttrSet, cssAttrSet);
        } else {
            translateAttributes(tag, htmlAttrSet, cssAttrSet);
        }
        if (tag == HTML.Tag.CAPTION) {
            /*
             * Navigator uses ALIGN for caption placement and IE uses VALIGN.
             */
            Object v = htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
            if ((v != null) && (v.equals("top") || v.equals("bottom"))) {
                cssAttrSet.addAttribute(CSS.Attribute.CAPTION_SIDE, v);
                cssAttrSet.removeAttribute(CSS.Attribute.TEXT_ALIGN);
            } else {
                v = htmlAttrSet.getAttribute(HTML.Attribute.VALIGN);
                if (v != null) {
                    cssAttrSet.addAttribute(CSS.Attribute.CAPTION_SIDE, v);
                }
            }
        }
        return cssAttrSet;
    }

    private static final Hashtable<String, Attribute> attributeMap = new Hashtable<String, Attribute>();
    private static final Hashtable<String, Value> valueMap = new Hashtable<String, Value>();

    /**
     * The hashtable and the static initalization block below,
     * set up a mapping from well-known HTML attributes to
     * CSS attributes.  For the most part, there is a 1-1 mapping
     * between the two.  However in the case of certain HTML
     * attributes for example HTML.Attribute.VSPACE or
     * HTML.Attribute.HSPACE, end up mapping to two CSS.Attribute's.
     * Therefore, the value associated with each HTML.Attribute.
     * key ends up being an array of CSS.Attribute.* objects.
     */
    private static final Hashtable<HTML.Attribute, CSS.Attribute[]> htmlAttrToCssAttrMap = new Hashtable<HTML.Attribute, CSS.Attribute[]>(20);

    /**
     * The hashtable and static initialization that follows sets
     * up a translation from StyleConstants (i.e. the <em>well known</em>
     * attributes) to the associated CSS attributes.
     */
    private static final Hashtable<Object, Attribute> styleConstantToCssMap = new Hashtable<Object, Attribute>(17);
    /** Maps from HTML value to a CSS value. Used in internal mapping. */
    private static final Hashtable<String, CSS.Value> htmlValueToCssValueMap = new Hashtable<String, CSS.Value>(8);
    /** Maps from CSS value (string) to internal value. */
    private static final Hashtable<String, CSS.Value> cssValueToInternalValueMap = new Hashtable<String, CSS.Value>(13);

    static {
        // load the attribute map
        for (int i = 0; i < Attribute.allAttributes.length; i++ ) {
            attributeMap.put(Attribute.allAttributes[i].toString(),
                             Attribute.allAttributes[i]);
        }
        // load the value map
        for (int i = 0; i < Value.allValues.length; i++ ) {
            valueMap.put(Value.allValues[i].toString(),
                             Value.allValues[i]);
        }

        htmlAttrToCssAttrMap.put(HTML.Attribute.COLOR,
                                 new CSS.Attribute[]{CSS.Attribute.COLOR});
        htmlAttrToCssAttrMap.put(HTML.Attribute.TEXT,
                                 new CSS.Attribute[]{CSS.Attribute.COLOR});
        htmlAttrToCssAttrMap.put(HTML.Attribute.CLEAR,
                                 new CSS.Attribute[]{CSS.Attribute.CLEAR});
        htmlAttrToCssAttrMap.put(HTML.Attribute.BACKGROUND,
                                 new CSS.Attribute[]{CSS.Attribute.BACKGROUND_IMAGE});
        htmlAttrToCssAttrMap.put(HTML.Attribute.BGCOLOR,
                                 new CSS.Attribute[]{CSS.Attribute.BACKGROUND_COLOR});
        htmlAttrToCssAttrMap.put(HTML.Attribute.WIDTH,
                                 new CSS.Attribute[]{CSS.Attribute.WIDTH});
        htmlAttrToCssAttrMap.put(HTML.Attribute.HEIGHT,
                                 new CSS.Attribute[]{CSS.Attribute.HEIGHT});
        htmlAttrToCssAttrMap.put(HTML.Attribute.BORDER,
                                 new CSS.Attribute[]{CSS.Attribute.BORDER_TOP_WIDTH, CSS.Attribute.BORDER_RIGHT_WIDTH, CSS.Attribute.BORDER_BOTTOM_WIDTH, CSS.Attribute.BORDER_LEFT_WIDTH});
        htmlAttrToCssAttrMap.put(HTML.Attribute.CELLPADDING,
                                 new CSS.Attribute[]{CSS.Attribute.PADDING});
        htmlAttrToCssAttrMap.put(HTML.Attribute.CELLSPACING,
                                 new CSS.Attribute[]{CSS.Attribute.BORDER_SPACING});
        htmlAttrToCssAttrMap.put(HTML.Attribute.MARGINWIDTH,
                                 new CSS.Attribute[]{CSS.Attribute.MARGIN_LEFT,
                                                     CSS.Attribute.MARGIN_RIGHT});
        htmlAttrToCssAttrMap.put(HTML.Attribute.MARGINHEIGHT,
                                 new CSS.Attribute[]{CSS.Attribute.MARGIN_TOP,
                                                     CSS.Attribute.MARGIN_BOTTOM});
        htmlAttrToCssAttrMap.put(HTML.Attribute.HSPACE,
                                 new CSS.Attribute[]{CSS.Attribute.PADDING_LEFT,
                                                     CSS.Attribute.PADDING_RIGHT});
        htmlAttrToCssAttrMap.put(HTML.Attribute.VSPACE,
                                 new CSS.Attribute[]{CSS.Attribute.PADDING_BOTTOM,
                                                     CSS.Attribute.PADDING_TOP});
        htmlAttrToCssAttrMap.put(HTML.Attribute.FACE,
                                 new CSS.Attribute[]{CSS.Attribute.FONT_FAMILY});
        htmlAttrToCssAttrMap.put(HTML.Attribute.SIZE,
                                 new CSS.Attribute[]{CSS.Attribute.FONT_SIZE});
        htmlAttrToCssAttrMap.put(HTML.Attribute.VALIGN,
                                 new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN});
        htmlAttrToCssAttrMap.put(HTML.Attribute.ALIGN,
                                 new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN,
                                                     CSS.Attribute.TEXT_ALIGN,
                                                     CSS.Attribute.FLOAT});
        htmlAttrToCssAttrMap.put(HTML.Attribute.TYPE,
                                 new CSS.Attribute[]{CSS.Attribute.LIST_STYLE_TYPE});
        htmlAttrToCssAttrMap.put(HTML.Attribute.NOWRAP,
                                 new CSS.Attribute[]{CSS.Attribute.WHITE_SPACE});

        // initialize StyleConstants mapping
        styleConstantToCssMap.put(StyleConstants.FontFamily,
                                  CSS.Attribute.FONT_FAMILY);
        styleConstantToCssMap.put(StyleConstants.FontSize,
                                  CSS.Attribute.FONT_SIZE);
        styleConstantToCssMap.put(StyleConstants.Bold,
                                  CSS.Attribute.FONT_WEIGHT);
        styleConstantToCssMap.put(StyleConstants.Italic,
                                  CSS.Attribute.FONT_STYLE);
        styleConstantToCssMap.put(StyleConstants.Underline,
                                  CSS.Attribute.TEXT_DECORATION);
        styleConstantToCssMap.put(StyleConstants.StrikeThrough,
                                  CSS.Attribute.TEXT_DECORATION);
        styleConstantToCssMap.put(StyleConstants.Superscript,
                                  CSS.Attribute.VERTICAL_ALIGN);
        styleConstantToCssMap.put(StyleConstants.Subscript,
                                  CSS.Attribute.VERTICAL_ALIGN);
        styleConstantToCssMap.put(StyleConstants.Foreground,
                                  CSS.Attribute.COLOR);
        styleConstantToCssMap.put(StyleConstants.Background,
                                  CSS.Attribute.BACKGROUND_COLOR);
        styleConstantToCssMap.put(StyleConstants.FirstLineIndent,
                                  CSS.Attribute.TEXT_INDENT);
        styleConstantToCssMap.put(StyleConstants.LeftIndent,
                                  CSS.Attribute.MARGIN_LEFT);
        styleConstantToCssMap.put(StyleConstants.RightIndent,
                                  CSS.Attribute.MARGIN_RIGHT);
        styleConstantToCssMap.put(StyleConstants.SpaceAbove,
                                  CSS.Attribute.MARGIN_TOP);
        styleConstantToCssMap.put(StyleConstants.SpaceBelow,
                                  CSS.Attribute.MARGIN_BOTTOM);
        styleConstantToCssMap.put(StyleConstants.Alignment,
                                  CSS.Attribute.TEXT_ALIGN);

        // HTML->CSS
        htmlValueToCssValueMap.put("disc", CSS.Value.DISC);
        htmlValueToCssValueMap.put("square", CSS.Value.SQUARE);
        htmlValueToCssValueMap.put("circle", CSS.Value.CIRCLE);
        htmlValueToCssValueMap.put("1", CSS.Value.DECIMAL);
        htmlValueToCssValueMap.put("a", CSS.Value.LOWER_ALPHA);
        htmlValueToCssValueMap.put("A", CSS.Value.UPPER_ALPHA);
        htmlValueToCssValueMap.put("i", CSS.Value.LOWER_ROMAN);
        htmlValueToCssValueMap.put("I", CSS.Value.UPPER_ROMAN);

        // CSS-> internal CSS
        cssValueToInternalValueMap.put("none", CSS.Value.NONE);
        cssValueToInternalValueMap.put("disc", CSS.Value.DISC);
        cssValueToInternalValueMap.put("square", CSS.Value.SQUARE);
        cssValueToInternalValueMap.put("circle", CSS.Value.CIRCLE);
        cssValueToInternalValueMap.put("decimal", CSS.Value.DECIMAL);
        cssValueToInternalValueMap.put("lower-roman", CSS.Value.LOWER_ROMAN);
        cssValueToInternalValueMap.put("upper-roman", CSS.Value.UPPER_ROMAN);
        cssValueToInternalValueMap.put("lower-alpha", CSS.Value.LOWER_ALPHA);
        cssValueToInternalValueMap.put("upper-alpha", CSS.Value.UPPER_ALPHA);
        cssValueToInternalValueMap.put("repeat", CSS.Value.BACKGROUND_REPEAT);
        cssValueToInternalValueMap.put("no-repeat",
                                       CSS.Value.BACKGROUND_NO_REPEAT);
        cssValueToInternalValueMap.put("repeat-x",
                                       CSS.Value.BACKGROUND_REPEAT_X);
        cssValueToInternalValueMap.put("repeat-y",
                                       CSS.Value.BACKGROUND_REPEAT_Y);
        cssValueToInternalValueMap.put("scroll",
                                       CSS.Value.BACKGROUND_SCROLL);
        cssValueToInternalValueMap.put("fixed",
                                       CSS.Value.BACKGROUND_FIXED);

        // Register all the CSS attribute keys for archival/unarchival
        Object[] keys = CSS.Attribute.allAttributes;
        try {
            for (Object key : keys) {
                StyleContext.registerStaticAttributeKey(key);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }

        // Register all the CSS Values for archival/unarchival
        keys = CSS.Value.allValues;
        try {
            for (Object key : keys) {
                StyleContext.registerStaticAttributeKey(key);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * Return the set of all possible CSS attribute keys.
     */
    public static Attribute[] getAllAttributeKeys() {
        Attribute[] keys = new Attribute[Attribute.allAttributes.length];
        System.arraycopy(Attribute.allAttributes, 0, keys, 0, Attribute.allAttributes.length);
        return keys;
    }

    /**
     * Translates a string to a <code>CSS.Attribute</code> object.
     * This will return <code>null</code> if there is no attribute
     * by the given name.
     *
     * @param name the name of the CSS attribute to fetch the
     *  typesafe enumeration for
     * @return the <code>CSS.Attribute</code> object,
     *  or <code>null</code> if the string
     *  doesn't represent a valid attribute key
     */
    public static final Attribute getAttribute(String name) {
        return attributeMap.get(name);
    }

    /**
     * Translates a string to a <code>CSS.Value</code> object.
     * This will return <code>null</code> if there is no value
     * by the given name.
     *
     * @param name the name of the CSS value to fetch the
     *  typesafe enumeration for
     * @return the <code>CSS.Value</code> object,
     *  or <code>null</code> if the string
     *  doesn't represent a valid CSS value name; this does
     *  not mean that it doesn't represent a valid CSS value
     */
    static final Value getValue(String name) {
        return valueMap.get(name);
    }


    //
    // Conversion related methods/classes
    //

    /**
     * Returns a URL for the given CSS url string. If relative,
     * <code>base</code> is used as the parent. If a valid URL can not
     * be found, this will not throw a MalformedURLException, instead
     * null will be returned.
     */
    static URL getURL(URL base, String cssString) {
        if (cssString == null) {
            return null;
        }
        if (cssString.startsWith("url(") &&
            cssString.endsWith(")")) {
            cssString = cssString.substring(4, cssString.length() - 1);
        }
        // Absolute first
        try {
            URL url = new URL(cssString);
            if (url != null) {
                return url;
            }
        } catch (MalformedURLException mue) {
        }
        // Then relative
        if (base != null) {
            // Relative URL, try from base
            try {
                URL url = new URL(base, cssString);
                return url;
            }
            catch (MalformedURLException muee) {
            }
        }
        return null;
    }

    /**
     * Converts a type Color to a hex string
     * in the format "#RRGGBB"
     */
    static String colorToHex(Color color) {

      String colorstr = "#";

      // Red
      String str = Integer.toHexString(color.getRed());
      if (str.length() > 2)
        str = str.substring(0, 2);
      else if (str.length() < 2)
        colorstr += "0" + str;
      else
        colorstr += str;

      // Green
      str = Integer.toHexString(color.getGreen());
      if (str.length() > 2)
        str = str.substring(0, 2);
      else if (str.length() < 2)
        colorstr += "0" + str;
      else
        colorstr += str;

      // Blue
      str = Integer.toHexString(color.getBlue());
      if (str.length() > 2)
        str = str.substring(0, 2);
      else if (str.length() < 2)
        colorstr += "0" + str;
      else
        colorstr += str;

      return colorstr;
    }

     /**
      * Convert a "#FFFFFF" hex string to a Color.
      * If the color specification is bad, an attempt
      * will be made to fix it up.
      */
    static final Color hexToColor(String value) {
        String digits;
        int n = value.length();
        if (value.startsWith("#")) {
            digits = value.substring(1, Math.min(value.length(), 7));
        } else {
            digits = value;
        }
        String hstr = "0x" + digits;
        Color c;
        try {
            c = Color.decode(hstr);
        } catch (NumberFormatException nfe) {
            c = null;
        }
         return c;
     }

    /**
     * Convert a color string such as "RED" or "#NNNNNN" or "rgb(r, g, b)"
     * to a Color.
     */
    static Color stringToColor(String str) {
      Color color;

      if (str == null) {
          return null;
      }
      if (str.length() == 0)
        color = Color.black;
      else if (str.startsWith("rgb(")) {
          color = parseRGB(str);
      }
      else if (str.charAt(0) == '#')
        color = hexToColor(str);
      else if (str.equalsIgnoreCase("Black"))
        color = hexToColor("#000000");
      else if(str.equalsIgnoreCase("Silver"))
        color = hexToColor("#C0C0C0");
      else if(str.equalsIgnoreCase("Gray"))
        color = hexToColor("#808080");
      else if(str.equalsIgnoreCase("White"))
        color = hexToColor("#FFFFFF");
      else if(str.equalsIgnoreCase("Maroon"))
        color = hexToColor("#800000");
      else if(str.equalsIgnoreCase("Red"))
        color = hexToColor("#FF0000");
      else if(str.equalsIgnoreCase("Purple"))
        color = hexToColor("#800080");
      else if(str.equalsIgnoreCase("Fuchsia"))
        color = hexToColor("#FF00FF");
      else if(str.equalsIgnoreCase("Green"))
        color = hexToColor("#008000");
      else if(str.equalsIgnoreCase("Lime"))
        color = hexToColor("#00FF00");
      else if(str.equalsIgnoreCase("Olive"))
        color = hexToColor("#808000");
      else if(str.equalsIgnoreCase("Yellow"))
        color = hexToColor("#FFFF00");
      else if(str.equalsIgnoreCase("Navy"))
        color = hexToColor("#000080");
      else if(str.equalsIgnoreCase("Blue"))
        color = hexToColor("#0000FF");
      else if(str.equalsIgnoreCase("Teal"))
        color = hexToColor("#008080");
      else if(str.equalsIgnoreCase("Aqua"))
        color = hexToColor("#00FFFF");
      else if(str.equalsIgnoreCase("Orange"))
        color = hexToColor("#FF8000");
      else
          color = hexToColor(str); // sometimes get specified without leading #
      return color;
    }

    /**
     * Parses a String in the format <code>rgb(r, g, b)</code> where
     * each of the Color components is either an integer, or a floating number
     * with a % after indicating a percentage value of 255. Values are
     * constrained to fit with 0-255. The resulting Color is returned.
     */
    private static Color parseRGB(String string) {
        // Find the next numeric char
        int[] index = new int[1];

        index[0] = 4;
        int red = getColorComponent(string, index);
        int green = getColorComponent(string, index);
        int blue = getColorComponent(string, index);

        return new Color(red, green, blue);
    }

    /**
     * Returns the next integer value from <code>string</code> starting
     * at <code>index[0]</code>. The value can either can an integer, or
     * a percentage (floating number ending with %), in which case it is
     * multiplied by 255.
     */
    private static int getColorComponent(String string, int[] index) {
        int length = string.length();
        char aChar;

        // Skip non-decimal chars
        while(index[0] < length && (aChar = string.charAt(index[0])) != '-' &&
              !Character.isDigit(aChar) && aChar != '.') {
            index[0]++;
        }

        int start = index[0];

        if (start < length && string.charAt(index[0]) == '-') {
            index[0]++;
        }
        while(index[0] < length &&
                         Character.isDigit(string.charAt(index[0]))) {
            index[0]++;
        }
        if (index[0] < length && string.charAt(index[0]) == '.') {
            // Decimal value
            index[0]++;
            while(index[0] < length &&
                  Character.isDigit(string.charAt(index[0]))) {
                index[0]++;
            }
        }
        if (start != index[0]) {
            try {
                float value = Float.parseFloat(string.substring
                                               (start, index[0]));

                if (index[0] < length && string.charAt(index[0]) == '%') {
                    index[0]++;
                    value = value * 255f / 100f;
                }
                return Math.min(255, Math.max(0, (int)value));
            } catch (NumberFormatException nfe) {
                // Treat as 0
            }
        }
        return 0;
    }

    static int getIndexOfSize(float pt, int[] sizeMap) {
        for (int i = 0; i < sizeMap.length; i ++ )
                if (pt <= sizeMap[i])
                        return i + 1;
        return sizeMap.length;
    }

    static int getIndexOfSize(float pt, StyleSheet ss) {
        int[] sizeMap = (ss != null) ? ss.getSizeMap() :
            StyleSheet.sizeMapDefault;
        return getIndexOfSize(pt, sizeMap);
    }


    /**
     * @return an array of all the strings in <code>value</code>
     *         that are separated by whitespace.
     */
    static String[] parseStrings(String value) {
        int         current, last;
        int         length = (value == null) ? 0 : value.length();
        Vector<String> temp = new Vector<String>(4);

        current = 0;
        while (current < length) {
            // Skip ws
            while (current < length && Character.isWhitespace
                   (value.charAt(current))) {
                current++;
            }
            last = current;
            while (current < length && !Character.isWhitespace
                   (value.charAt(current))) {
                current++;
            }
            if (last != current) {
                temp.addElement(value.substring(last, current));
            }
            current++;
        }
        String[] retValue = new String[temp.size()];
        temp.copyInto(retValue);
        return retValue;
    }

    /**
     * Return the point size, given a size index. Legal HTML index sizes
     * are 1-7.
     */
    float getPointSize(int index, StyleSheet ss) {
        ss = getStyleSheet(ss);
        int[] sizeMap = (ss != null) ? ss.getSizeMap() :
            StyleSheet.sizeMapDefault;
        --index;
        if (index < 0)
          return sizeMap[0];
        else if (index > sizeMap.length - 1)
          return sizeMap[sizeMap.length - 1];
        else
          return sizeMap[index];
    }


    private void translateEmbeddedAttributes(AttributeSet htmlAttrSet,
                                             MutableAttributeSet cssAttrSet) {
        Enumeration keys = htmlAttrSet.getAttributeNames();
        if (htmlAttrSet.getAttribute(StyleConstants.NameAttribute) ==
            HTML.Tag.HR) {
            // HR needs special handling due to us treating it as a leaf.
            translateAttributes(HTML.Tag.HR, htmlAttrSet, cssAttrSet);
        }
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            if (key instanceof HTML.Tag) {
                HTML.Tag tag = (HTML.Tag)key;
                Object o = htmlAttrSet.getAttribute(tag);
                if (o != null && o instanceof AttributeSet) {
                    translateAttributes(tag, (AttributeSet)o, cssAttrSet);
                }
            } else if (key instanceof CSS.Attribute) {
                cssAttrSet.addAttribute(key, htmlAttrSet.getAttribute(key));
            }
        }
    }

    private void translateAttributes(HTML.Tag tag,
                                            AttributeSet htmlAttrSet,
                                            MutableAttributeSet cssAttrSet) {
        Enumeration names = htmlAttrSet.getAttributeNames();
        while (names.hasMoreElements()) {
            Object name = names.nextElement();

            if (name instanceof HTML.Attribute) {
                HTML.Attribute key = (HTML.Attribute)name;

                /*
                 * HTML.Attribute.ALIGN needs special processing.
                 * It can map to to 1 of many(3) possible CSS attributes
                 * depending on the nature of the tag the attribute is
                 * part off and depending on the value of the attribute.
                 */
                if (key == HTML.Attribute.ALIGN) {
                    String htmlAttrValue = (String)htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
                    if (htmlAttrValue != null) {
                        CSS.Attribute cssAttr = getCssAlignAttribute(tag, htmlAttrSet);
                        if (cssAttr != null) {
                            Object o = getCssValue(cssAttr, htmlAttrValue);
                            if (o != null) {
                                cssAttrSet.addAttribute(cssAttr, o);
                            }
                        }
                    }
                } else {

                    /*
                     * The html size attribute has a mapping in the CSS world only
                     * if it is par of a font or base font tag.
                     */

                    if (key == HTML.Attribute.SIZE && !isHTMLFontTag(tag)) {
                        continue;
                    }

                    translateAttribute(key, htmlAttrSet, cssAttrSet);
                }
            } else if (name instanceof CSS.Attribute) {
                cssAttrSet.addAttribute(name, htmlAttrSet.getAttribute(name));
            }
        }
    }

    private void translateAttribute(HTML.Attribute key,
                                           AttributeSet htmlAttrSet,
                                           MutableAttributeSet cssAttrSet) {
        /*
         * In the case of all remaining HTML.Attribute's they
         * map to 1 or more CCS.Attribute.
         */
        CSS.Attribute[] cssAttrList = getCssAttribute(key);

        String htmlAttrValue = (String)htmlAttrSet.getAttribute(key);

        if (cssAttrList == null || htmlAttrValue == null) {
            return;
        }
        for (Attribute cssAttr : cssAttrList) {
            Object o = getCssValue(cssAttr, htmlAttrValue);
            if (o != null) {
                cssAttrSet.addAttribute(cssAttr , o);
            }
        }
    }

    /**
     * Given a CSS.Attribute object and its corresponding HTML.Attribute's
     * value, this method returns a CssValue object to associate with the
     * CSS attribute.
     *
     * @param the CSS.Attribute
     * @param a String containing the value associated HTML.Attribtue.
     */
    Object getCssValue(CSS.Attribute cssAttr, String htmlAttrValue) {
        CssValue value = (CssValue)valueConvertor.get(cssAttr);
        Object o = value.parseHtmlValue(htmlAttrValue);
        return o;
    }

    /**
     * Maps an HTML.Attribute object to its appropriate CSS.Attributes.
     *
     * @param HTML.Attribute
     * @return CSS.Attribute[]
     */
    private CSS.Attribute[] getCssAttribute(HTML.Attribute hAttr) {
        return htmlAttrToCssAttrMap.get(hAttr);
    }

    /**
     * Maps HTML.Attribute.ALIGN to either:
     *     CSS.Attribute.TEXT_ALIGN
     *     CSS.Attribute.FLOAT
     *     CSS.Attribute.VERTICAL_ALIGN
     * based on the tag associated with the attribute and the
     * value of the attribute.
     *
     * @param AttributeSet containing HTML attributes.
     * @return CSS.Attribute mapping for HTML.Attribute.ALIGN.
     */
    private CSS.Attribute getCssAlignAttribute(HTML.Tag tag,
                                                   AttributeSet htmlAttrSet) {
        return CSS.Attribute.TEXT_ALIGN;
/*
        String htmlAttrValue = (String)htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
        CSS.Attribute cssAttr = CSS.Attribute.TEXT_ALIGN;
        if (htmlAttrValue != null && htmlAttrSet instanceof Element) {
            Element elem = (Element)htmlAttrSet;
            if (!elem.isLeaf() && tag.isBlock() && validTextAlignValue(htmlAttrValue)) {
                return CSS.Attribute.TEXT_ALIGN;
            } else if (isFloater(htmlAttrValue)) {
                return CSS.Attribute.FLOAT;
            } else if (elem.isLeaf()) {
                return CSS.Attribute.VERTICAL_ALIGN;
            }
        }
        return null;
        */
    }

    /**
     * Fetches the tag associated with the HTML AttributeSet.
     *
     * @param  AttributeSet containing the HTML attributes.
     * @return HTML.Tag
     */
    private HTML.Tag getHTMLTag(AttributeSet htmlAttrSet) {
        Object o = htmlAttrSet.getAttribute(StyleConstants.NameAttribute);
        if (o instanceof HTML.Tag) {
            HTML.Tag tag = (HTML.Tag) o;
            return tag;
        }
        return null;
    }


    private boolean isHTMLFontTag(HTML.Tag tag) {
        return (tag != null && ((tag == HTML.Tag.FONT) || (tag == HTML.Tag.BASEFONT)));
    }


    private boolean isFloater(String alignValue) {
        return (alignValue.equals("left") || alignValue.equals("right"));
    }

    private boolean validTextAlignValue(String alignValue) {
        return (isFloater(alignValue) || alignValue.equals("center"));
    }

    /**
     * Base class to CSS values in the attribute sets.  This
     * is intended to act as a convertor to/from other attribute
     * formats.
     * <p>
     * The CSS parser uses the parseCssValue method to convert
     * a string to whatever format is appropriate a given key
     * (i.e. these convertors are stored in a map using the
     * CSS.Attribute as a key and the CssValue as the value).
     * <p>
     * The HTML to CSS conversion process first converts the
     * HTML.Attribute to a CSS.Attribute, and then calls
     * the parseHtmlValue method on the value of the HTML
     * attribute to produce the corresponding CSS value.
     * <p>
     * The StyleConstants to CSS conversion process first
     * converts the StyleConstants attribute to a
     * CSS.Attribute, and then calls the fromStyleConstants
     * method to convert the StyleConstants value to a
     * CSS value.
     * <p>
     * The CSS to StyleConstants conversion process first
     * converts the StyleConstants attribute to a
     * CSS.Attribute, and then calls the toStyleConstants
     * method to convert the CSS value to a StyleConstants
     * value.
     */
    static class CssValue implements Serializable {

        /**
         * Convert a CSS value string to the internal format
         * (for fast processing) used in the attribute sets.
         * The fallback storage for any value that we don't
         * have a special binary format for is a String.
         */
        Object parseCssValue(String value) {
            return value;
        }

        /**
         * Convert an HTML attribute value to a CSS attribute
         * value.  If there is no conversion, return null.
         * This is implemented to simply forward to the CSS
         * parsing by default (since some of the attribute
         * values are the same).  If the attribute value
         * isn't recognized as a CSS value it is generally
         * returned as null.
         */
        Object parseHtmlValue(String value) {
            return parseCssValue(value);
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion,
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            return null;
        }

        /**
         * Converts a CSS attribute value to a
         * <code>StyleConstants</code>
         * value.  If there is no conversion, returns
         * <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param v the view containing <code>AttributeSet</code>
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            return null;
        }

        /**
         * Return the CSS format of the value
         */
        public String toString() {
            return svalue;
        }

        /**
         * The value as a string... before conversion to a
         * binary format.
         */
        String svalue;
    }

    /**
     * By default CSS attributes are represented as simple
     * strings.  They also have no conversion to/from
     * StyleConstants by default. This class represents the
     * value as a string (via the superclass), but
     * provides StyleConstants conversion support for the
     * CSS attributes that are held as strings.
     */
    static class StringValue extends CssValue {

        /**
         * Convert a CSS value string to the internal format
         * (for fast processing) used in the attribute sets.
         * This produces a StringValue, so that it can be
         * used to convert from CSS to StyleConstants values.
         */
        Object parseCssValue(String value) {
            StringValue sv = new StringValue();
            sv.svalue = value;
            return sv;
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion
         * returns <code>null</code>.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            if (key == StyleConstants.Italic) {
                if (value.equals(Boolean.TRUE)) {
                    return parseCssValue("italic");
                }
                return parseCssValue("");
            } else if (key == StyleConstants.Underline) {
                if (value.equals(Boolean.TRUE)) {
                    return parseCssValue("underline");
                }
                return parseCssValue("");
            } else if (key == StyleConstants.Alignment) {
                int align = ((Integer)value).intValue();
                String ta;
                switch(align) {
                case StyleConstants.ALIGN_LEFT:
                    ta = "left";
                    break;
                case StyleConstants.ALIGN_RIGHT:
                    ta = "right";
                    break;
                case StyleConstants.ALIGN_CENTER:
                    ta = "center";
                    break;
                case StyleConstants.ALIGN_JUSTIFIED:
                    ta = "justify";
                    break;
                default:
                    ta = "left";
                }
                return parseCssValue(ta);
            } else if (key == StyleConstants.StrikeThrough) {
                if (value.equals(Boolean.TRUE)) {
                    return parseCssValue("line-through");
                }
                return parseCssValue("");
            } else if (key == StyleConstants.Superscript) {
                if (value.equals(Boolean.TRUE)) {
                    return parseCssValue("super");
                }
                return parseCssValue("");
            } else if (key == StyleConstants.Subscript) {
                if (value.equals(Boolean.TRUE)) {
                    return parseCssValue("sub");
                }
                return parseCssValue("");
            }
            return null;
        }

        /**
         * Converts a CSS attribute value to a
         * <code>StyleConstants</code> value.
         * If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            if (key == StyleConstants.Italic) {
                if (svalue.indexOf("italic") >= 0) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            } else if (key == StyleConstants.Underline) {
                if (svalue.indexOf("underline") >= 0) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            } else if (key == StyleConstants.Alignment) {
                if (svalue.equals("right")) {
                    return new Integer(StyleConstants.ALIGN_RIGHT);
                } else if (svalue.equals("center")) {
                    return new Integer(StyleConstants.ALIGN_CENTER);
                } else if  (svalue.equals("justify")) {
                    return new Integer(StyleConstants.ALIGN_JUSTIFIED);
                }
                return new Integer(StyleConstants.ALIGN_LEFT);
            } else if (key == StyleConstants.StrikeThrough) {
                if (svalue.indexOf("line-through") >= 0) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            } else if (key == StyleConstants.Superscript) {
                if (svalue.indexOf("super") >= 0) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            } else if (key == StyleConstants.Subscript) {
                if (svalue.indexOf("sub") >= 0) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            }
            return null;
        }

        // Used by ViewAttributeSet
        boolean isItalic() {
            return (svalue.indexOf("italic") != -1);
        }

        boolean isStrike() {
            return (svalue.indexOf("line-through") != -1);
        }

        boolean isUnderline() {
            return (svalue.indexOf("underline") != -1);
        }

        boolean isSub() {
            return (svalue.indexOf("sub") != -1);
        }

        boolean isSup() {
            return (svalue.indexOf("sup") != -1);
        }
    }

    /**
     * Represents a value for the CSS.FONT_SIZE attribute.
     * The binary format of the value can be one of several
     * types.  If the type is Float,
     * the value is specified in terms of point or
     * percentage, depending upon the ending of the
     * associated string.
     * If the type is Integer, the value is specified
     * in terms of a size index.
     */
    class FontSize extends CssValue {

        /**
         * Returns the size in points.  This is ultimately
         * what we need for the purpose of creating/fetching
         * a Font object.
         *
         * @param a the attribute set the value is being
         *  requested from.  We may need to walk up the
         *  resolve hierarchy if it's relative.
         */
        int getValue(AttributeSet a, StyleSheet ss) {
            ss = getStyleSheet(ss);
            if (index) {
                // it's an index, translate from size table
                return Math.round(getPointSize((int) value, ss));
            }
            else if (lu == null) {
                return Math.round(value);
            }
            else {
                if (lu.type == 0) {
                    boolean isW3CLengthUnits = (ss == null) ? false : ss.isW3CLengthUnits();
                    return Math.round(lu.getValue(isW3CLengthUnits));
                }
                if (a != null) {
                    AttributeSet resolveParent = a.getResolveParent();

                    if (resolveParent != null) {
                        int pValue = StyleConstants.getFontSize(resolveParent);

                        float retValue;
                        if (lu.type == 1 || lu.type == 3) {
                            retValue = lu.value * (float)pValue;
                        }
                        else {
                            retValue = lu.value + (float)pValue;
                        }
                        return Math.round(retValue);
                    }
                }
                // a is null, or no resolve parent.
                return 12;
            }
        }

        Object parseCssValue(String value) {
            FontSize fs = new FontSize();
            fs.svalue = value;
            try {
                if (value.equals("xx-small")) {
                    fs.value = 1;
                    fs.index = true;
                } else if (value.equals("x-small")) {
                    fs.value = 2;
                    fs.index = true;
                } else if (value.equals("small")) {
                    fs.value = 3;
                    fs.index = true;
                } else if (value.equals("medium")) {
                    fs.value = 4;
                    fs.index = true;
                } else if (value.equals("large")) {
                    fs.value = 5;
                    fs.index = true;
                } else if (value.equals("x-large")) {
                    fs.value = 6;
                    fs.index = true;
                } else if (value.equals("xx-large")) {
                    fs.value = 7;
                    fs.index = true;
                } else {
                    fs.lu = new LengthUnit(value, (short)1, 1f);
                }
                // relative sizes, larger | smaller (adjust from parent by
                // 1.5 pixels)
                // em, ex refer to parent sizes
                // lengths: pt, mm, cm, pc, in, px
                //          em (font height 3em would be 3 times font height)
                //          ex (height of X)
                // lengths are (+/-) followed by a number and two letter
                // unit identifier
            } catch (NumberFormatException nfe) {
                fs = null;
            }
            return fs;
        }

        Object parseHtmlValue(String value) {
            if ((value == null) || (value.length() == 0)) {
                return null;
            }
            FontSize fs = new FontSize();
            fs.svalue = value;

            try {
                /*
                 * relative sizes in the size attribute are relative
                 * to the <basefont>'s size.
                 */
                int baseFontSize = getBaseFontSize();
                if (value.charAt(0) == '+') {
                    int relSize = Integer.valueOf(value.substring(1)).intValue();
                    fs.value = baseFontSize + relSize;
                    fs.index = true;
                } else if (value.charAt(0) == '-') {
                    int relSize = -Integer.valueOf(value.substring(1)).intValue();
                    fs.value = baseFontSize + relSize;
                    fs.index = true;
                } else {
                    fs.value = Integer.parseInt(value);
                    if (fs.value > 7) {
                        fs.value = 7;
                    } else if (fs.value < 0) {
                        fs.value = 0;
                    }
                    fs.index = true;
                }

            } catch (NumberFormatException nfe) {
                fs = null;
            }
            return fs;
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            if (value instanceof Number) {
                FontSize fs = new FontSize();

                fs.value = getIndexOfSize(((Number)value).floatValue(), StyleSheet.sizeMapDefault);
                fs.svalue = Integer.toString((int)fs.value);
                fs.index = true;
                return fs;
            }
            return parseCssValue(value.toString());
        }

        /**
         * Converts a CSS attribute value to a <code>StyleConstants</code>
         * value.  If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            if (v != null) {
                return Integer.valueOf(getValue(v.getAttributes(), null));
            }
            return Integer.valueOf(getValue(null, null));
        }

        float value;
        boolean index;
        LengthUnit lu;
    }

    static class FontFamily extends CssValue {

        /**
         * Returns the font family to use.
         */
        String getValue() {
            return family;
        }

        Object parseCssValue(String value) {
            int cIndex = value.indexOf(',');
            FontFamily ff = new FontFamily();
            ff.svalue = value;
            ff.family = null;

            if (cIndex == -1) {
                setFontName(ff, value);
            }
            else {
                boolean done = false;
                int lastIndex;
                int length = value.length();
                cIndex = 0;
                while (!done) {
                    // skip ws.
                    while (cIndex < length &&
                           Character.isWhitespace(value.charAt(cIndex)))
                        cIndex++;
                    // Find next ','
                    lastIndex = cIndex;
                    cIndex = value.indexOf(',', cIndex);
                    if (cIndex == -1) {
                        cIndex = length;
                    }
                    if (lastIndex < length) {
                        if (lastIndex != cIndex) {
                            int lastCharIndex = cIndex;
                            if (cIndex > 0 && value.charAt(cIndex - 1) == ' '){
                                lastCharIndex--;
                            }
                            setFontName(ff, value.substring
                                        (lastIndex, lastCharIndex));
                            done = (ff.family != null);
                        }
                        cIndex++;
                    }
                    else {
                        done = true;
                    }
                }
            }
            if (ff.family == null) {
                ff.family = Font.SANS_SERIF;
            }
            return ff;
        }

        private void setFontName(FontFamily ff, String fontName) {
            ff.family = fontName;
        }

        Object parseHtmlValue(String value) {
            // TBD
            return parseCssValue(value);
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            return parseCssValue(value.toString());
        }

        /**
         * Converts a CSS attribute value to a <code>StyleConstants</code>
         * value.  If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            return family;
        }

        String family;
    }

    static class FontWeight extends CssValue {

        int getValue() {
            return weight;
        }

        Object parseCssValue(String value) {
            FontWeight fw = new FontWeight();
            fw.svalue = value;
            if (value.equals("bold")) {
                fw.weight = 700;
            } else if (value.equals("normal")) {
                fw.weight = 400;
            } else {
                // PENDING(prinz) add support for relative values
                try {
                    fw.weight = Integer.parseInt(value);
                } catch (NumberFormatException nfe) {
                    fw = null;
                }
            }
            return fw;
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            if (value.equals(Boolean.TRUE)) {
                return parseCssValue("bold");
            }
            return parseCssValue("normal");
        }

        /**
         * Converts a CSS attribute value to a <code>StyleConstants</code>
         * value.  If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            return (weight > 500) ? Boolean.TRUE : Boolean.FALSE;
        }

        boolean isBold() {
            return (weight > 500);
        }

        int weight;
    }

    static class ColorValue extends CssValue {

        /**
         * Returns the color to use.
         */
        Color getValue() {
            return c;
        }

        Object parseCssValue(String value) {

            Color c = stringToColor(value);
            if (c != null) {
                ColorValue cv = new ColorValue();
                cv.svalue = value;
                cv.c = c;
                return cv;
            }
            return null;
        }

        Object parseHtmlValue(String value) {
            return parseCssValue(value);
        }

        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            ColorValue colorValue = new ColorValue();
            colorValue.c = (Color)value;
            colorValue.svalue = colorToHex(colorValue.c);
            return colorValue;
        }

        /**
         * Converts a CSS attribute value to a <code>StyleConstants</code>
         * value.  If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            return c;
        }

        Color c;
    }

    static class BorderStyle extends CssValue {

        CSS.Value getValue() {
            return style;
        }

        Object parseCssValue(String value) {
            CSS.Value cssv = CSS.getValue(value);
            if (cssv != null) {
                if ((cssv == CSS.Value.INSET) ||
                    (cssv == CSS.Value.OUTSET) ||
                    (cssv == CSS.Value.NONE) ||
                    (cssv == CSS.Value.DOTTED) ||
                    (cssv == CSS.Value.DASHED) ||
                    (cssv == CSS.Value.SOLID) ||
                    (cssv == CSS.Value.DOUBLE) ||
                    (cssv == CSS.Value.GROOVE) ||
                    (cssv == CSS.Value.RIDGE)) {

                    BorderStyle bs = new BorderStyle();
                    bs.svalue = value;
                    bs.style = cssv;
                    return bs;
                }
            }
            return null;
        }

        private void writeObject(java.io.ObjectOutputStream s)
                     throws IOException {
            s.defaultWriteObject();
            if (style == null) {
                s.writeObject(null);
            }
            else {
                s.writeObject(style.toString());
            }
        }

        private void readObject(ObjectInputStream s)
                throws ClassNotFoundException, IOException {
            s.defaultReadObject();
            Object value = s.readObject();
            if (value != null) {
                style = CSS.getValue((String)value);
            }
        }

        // CSS.Values are static, don't archive it.
        transient private CSS.Value style;
    }

    static class LengthValue extends CssValue {

        /**
         * if this length value may be negative.
         */
        boolean mayBeNegative;

        LengthValue() {
            this(false);
        }

        LengthValue(boolean mayBeNegative) {
            this.mayBeNegative = mayBeNegative;
        }

        /**
         * Returns the length (span) to use.
         */
        float getValue() {
            return getValue(false);
        }

        float getValue(boolean isW3CLengthUnits) {
            return getValue(0, isW3CLengthUnits);
        }

        /**
         * Returns the length (span) to use. If the value represents
         * a percentage, it is scaled based on <code>currentValue</code>.
         */
        float getValue(float currentValue) {
            return getValue(currentValue, false);
        }
        float getValue(float currentValue, boolean isW3CLengthUnits) {
            if (percentage) {
                return span * currentValue;
            }
            return LengthUnit.getValue(span, units, isW3CLengthUnits);
        }

        /**
         * Returns true if the length represents a percentage of the
         * containing box.
         */
        boolean isPercentage() {
            return percentage;
        }

        Object parseCssValue(String value) {
            LengthValue lv;
            try {
                // Assume pixels
                float absolute = Float.valueOf(value).floatValue();
                lv = new LengthValue();
                lv.span = absolute;
            } catch (NumberFormatException nfe) {
                // Not pixels, use LengthUnit
                LengthUnit lu = new LengthUnit(value,
                                               LengthUnit.UNINITALIZED_LENGTH,
                                               0);

                // PENDING: currently, we only support absolute values and
                // percentages.
                switch (lu.type) {
                case 0:
                    // Absolute
                    lv = new LengthValue();
                    lv.span =
                        (mayBeNegative) ? lu.value : Math.max(0, lu.value);
                    lv.units = lu.units;
                    break;
                case 1:
                    // %
                    lv = new LengthValue();
                    lv.span = Math.max(0, Math.min(1, lu.value));
                    lv.percentage = true;
                    break;
                default:
                    return null;
                }
            }
            lv.svalue = value;
            return lv;
        }

        Object parseHtmlValue(String value) {
            if (value.equals(HTML.NULL_ATTRIBUTE_VALUE)) {
                value = "1";
            }
            return parseCssValue(value);
        }
        /**
         * Converts a <code>StyleConstants</code> attribute value to
         * a CSS attribute value.  If there is no conversion,
         * returns <code>null</code>.  By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @param value the value of a <code>StyleConstants</code>
         *   attribute to be converted
         * @return the CSS value that represents the
         *   <code>StyleConstants</code> value
         */
        Object fromStyleConstants(StyleConstants key, Object value) {
            LengthValue v = new LengthValue();
            v.svalue = value.toString();
            v.span = ((Float)value).floatValue();
            return v;
        }

        /**
         * Converts a CSS attribute value to a <code>StyleConstants</code>
         * value.  If there is no conversion, returns <code>null</code>.
         * By default, there is no conversion.
         *
         * @param key the <code>StyleConstants</code> attribute
         * @return the <code>StyleConstants</code> attribute value that
         *   represents the CSS attribute value
         */
        Object toStyleConstants(StyleConstants key, View v) {
            return new Float(getValue(false));
        }

        /** If true, span is a percentage value, and that to determine
         * the length another value needs to be passed in. */
        boolean percentage;
        /** Either the absolute value (percentage == false) or
         * a percentage value. */
        float span;

        String units = null;
    }


    /**
     * BorderWidthValue is used to model BORDER_XXX_WIDTH and adds support
     * for the thin/medium/thick values.
     */
    static class BorderWidthValue extends LengthValue {
        BorderWidthValue(String svalue, int index) {
            this.svalue = svalue;
            span = values[index];
            percentage = false;
        }

        Object parseCssValue(String value) {
            if (value != null) {
                if (value.equals("thick")) {
                    return new BorderWidthValue(value, 2);
                }
                else if (value.equals("medium")) {
                    return new BorderWidthValue(value, 1);
                }
                else if (value.equals("thin")) {
                    return new BorderWidthValue(value, 0);
                }
            }
            // Assume its a length.
            return super.parseCssValue(value);
        }

        Object parseHtmlValue(String value) {
            if (value == HTML.NULL_ATTRIBUTE_VALUE) {
                return parseCssValue("medium");
            }
            return parseCssValue(value);
        }

        /** Values used to represent border width. */
        private static final float[] values = { 1, 2, 4 };
   }


    /**
     * Handles uniquing of CSS values, like lists, and background image
     * repeating.
     */
    static class CssValueMapper extends CssValue {
        Object parseCssValue(String value) {
            Object retValue = cssValueToInternalValueMap.get(value);
            if (retValue == null) {
                retValue = cssValueToInternalValueMap.get(value.toLowerCase());
            }
            return retValue;
        }


        Object parseHtmlValue(String value) {
            Object retValue = htmlValueToCssValueMap.get(value);
            if (retValue == null) {
                retValue = htmlValueToCssValueMap.get(value.toLowerCase());
            }
            return retValue;
        }
    }


    /**
     * Used for background images, to represent the position.
     */
    static class BackgroundPosition extends CssValue {
        float horizontalPosition;
        float verticalPosition;
        // bitmask: bit 0, horizontal relative, bit 1 horizontal relative to
        // font size, 2 vertical relative to size, 3 vertical relative to
        // font size.
        //
        short relative;

        Object parseCssValue(String value) {
            // 'top left' and 'left top' both mean the same as '0% 0%'.
            // 'top', 'top center' and 'center top' mean the same as '50% 0%'.
            // 'right top' and 'top right' mean the same as '100% 0%'.
            // 'left', 'left center' and 'center left' mean the same as
            //        '0% 50%'.
            // 'center' and 'center center' mean the same as '50% 50%'.
            // 'right', 'right center' and 'center right' mean the same as
            //        '100% 50%'.
            // 'bottom left' and 'left bottom' mean the same as '0% 100%'.
            // 'bottom', 'bottom center' and 'center bottom' mean the same as
            //        '50% 100%'.
            // 'bottom right' and 'right bottom' mean the same as '100% 100%'.
            String[]  strings = CSS.parseStrings(value);
            int count = strings.length;
            BackgroundPosition bp = new BackgroundPosition();
            bp.relative = 5;
            bp.svalue = value;

            if (count > 0) {
                // bit 0 for vert, 1 hor, 2 for center
                short found = 0;
                int index = 0;
                while (index < count) {
                    // First, check for keywords
                    String string = strings[index++];
                    if (string.equals("center")) {
                        found |= 4;
                        continue;
                    }
                    else {
                        if ((found & 1) == 0) {
                            if (string.equals("top")) {
                                found |= 1;
                            }
                            else if (string.equals("bottom")) {
                                found |= 1;
                                bp.verticalPosition = 1;
                                continue;
                            }
                        }
                        if ((found & 2) == 0) {
                            if (string.equals("left")) {
                                found |= 2;
                                bp.horizontalPosition = 0;
                            }
                            else if (string.equals("right")) {
                                found |= 2;
                                bp.horizontalPosition = 1;
                            }
                        }
                    }
                }
                if (found != 0) {
                    if ((found & 1) == 1) {
                        if ((found & 2) == 0) {
                            // vert and no horiz.
                            bp.horizontalPosition = .5f;
                        }
                    }
                    else if ((found & 2) == 2) {
                        // horiz and no vert.
                        bp.verticalPosition = .5f;
                    }
                    else {
                        // no horiz, no vert, but center
                        bp.horizontalPosition = bp.verticalPosition = .5f;
                    }
                }
                else {
                    // Assume lengths
                    LengthUnit lu = new LengthUnit(strings[0], (short)0, 0f);

                    if (lu.type == 0) {
                        bp.horizontalPosition = lu.value;
                        bp.relative = (short)(1 ^ bp.relative);
                    }
                    else if (lu.type == 1) {
                        bp.horizontalPosition = lu.value;
                    }
                    else if (lu.type == 3) {
                        bp.horizontalPosition = lu.value;
                        bp.relative = (short)((1 ^ bp.relative) | 2);
                    }
                    if (count > 1) {
                        lu = new LengthUnit(strings[1], (short)0, 0f);

                        if (lu.type == 0) {
                            bp.verticalPosition = lu.value;
                            bp.relative = (short)(4 ^ bp.relative);
                        }
                        else if (lu.type == 1) {
                            bp.verticalPosition = lu.value;
                        }
                        else if (lu.type == 3) {
                            bp.verticalPosition = lu.value;
                            bp.relative = (short)((4 ^ bp.relative) | 8);
                        }
                    }
                    else {
                        bp.verticalPosition = .5f;
                    }
                }
            }
            return bp;
        }

        boolean isHorizontalPositionRelativeToSize() {
            return ((relative & 1) == 1);
        }

        boolean isHorizontalPositionRelativeToFontSize() {
            return ((relative & 2) == 2);
        }

        float getHorizontalPosition() {
            return horizontalPosition;
        }

        boolean isVerticalPositionRelativeToSize() {
            return ((relative & 4) == 4);
        }

        boolean isVerticalPositionRelativeToFontSize() {
            return ((relative & 8) == 8);
        }

        float getVerticalPosition() {
            return verticalPosition;
        }
    }


    /**
     * Used for BackgroundImages.
     */
    static class BackgroundImage extends CssValue {
        private boolean    loadedImage;
        private ImageIcon  image;

        Object parseCssValue(String value) {
            BackgroundImage retValue = new BackgroundImage();
            retValue.svalue = value;
            return retValue;
        }

        Object parseHtmlValue(String value) {
            return parseCssValue(value);
        }

        // PENDING: this base is wrong for linked style sheets.
        ImageIcon getImage(URL base) {
            if (!loadedImage) {
                synchronized(this) {
                    if (!loadedImage) {
                        URL url = CSS.getURL(base, svalue);
                        loadedImage = true;
                        if (url != null) {
                            image = new ImageIcon();
                            Image tmpImg = Toolkit.getDefaultToolkit().createImage(url);
                            if (tmpImg != null) {
                                image.setImage(tmpImg);
                            }
                        }
                    }
                }
            }
            return image;
        }
    }

    /**
     * Parses a length value, this is used internally, and never added
     * to an AttributeSet or returned to the developer.
     */
    static class LengthUnit implements Serializable {
        static Hashtable<String, Float> lengthMapping = new Hashtable<String, Float>(6);
        static Hashtable<String, Float> w3cLengthMapping = new Hashtable<String, Float>(6);
        static {
            lengthMapping.put("pt", new Float(1f));
            // Not sure about 1.3, determined by experiementation.
            lengthMapping.put("px", new Float(1.3f));
            lengthMapping.put("mm", new Float(2.83464f));
            lengthMapping.put("cm", new Float(28.3464f));
            lengthMapping.put("pc", new Float(12f));
            lengthMapping.put("in", new Float(72f));
            int res = 72;
            try {
                res = Toolkit.getDefaultToolkit().getScreenResolution();
            } catch (HeadlessException e) {
            }
            // mapping according to the CSS2 spec
            w3cLengthMapping.put("pt", new Float(res/72f));
            w3cLengthMapping.put("px", new Float(1f));
            w3cLengthMapping.put("mm", new Float(res/25.4f));
            w3cLengthMapping.put("cm", new Float(res/2.54f));
            w3cLengthMapping.put("pc", new Float(res/6f));
            w3cLengthMapping.put("in", new Float(res));
        }

        LengthUnit(String value, short defaultType, float defaultValue) {
            parse(value, defaultType, defaultValue);
        }

        void parse(String value, short defaultType, float defaultValue) {
            type = defaultType;
            this.value = defaultValue;

            int length = value.length();
            if (length > 0 && value.charAt(length - 1) == '%') {
                try {
                    this.value = Float.valueOf(value.substring(0, length - 1)).
                                               floatValue() / 100.0f;
                    type = 1;
                }
                catch (NumberFormatException nfe) { }
            }
            if (length >= 2) {
                units = value.substring(length - 2, length);
                Float scale = lengthMapping.get(units);
                if (scale != null) {
                    try {
                        this.value = Float.valueOf(value.substring(0,
                               length - 2)).floatValue();
                        type = 0;
                    }
                    catch (NumberFormatException nfe) { }
                }
                else if (units.equals("em") ||
                         units.equals("ex")) {
                    try {
                        this.value = Float.valueOf(value.substring(0,
                                      length - 2)).floatValue();
                        type = 3;
                    }
                    catch (NumberFormatException nfe) { }
                }
                else if (value.equals("larger")) {
                    this.value = 2f;
                    type = 2;
                }
                else if (value.equals("smaller")) {
                    this.value = -2;
                    type = 2;
                }
                else {
                    // treat like points.
                    try {
                        this.value = Float.valueOf(value).floatValue();
                        type = 0;
                    } catch (NumberFormatException nfe) {}
                }
            }
            else if (length > 0) {
                // treat like points.
                try {
                    this.value = Float.valueOf(value).floatValue();
                    type = 0;
                } catch (NumberFormatException nfe) {}
            }
        }

        float getValue(boolean w3cLengthUnits) {
            Hashtable<String, Float> mapping = (w3cLengthUnits) ? w3cLengthMapping : lengthMapping;
            float scale = 1;
            if (units != null) {
                Float scaleFloat = mapping.get(units);
                if (scaleFloat != null) {
                    scale = scaleFloat.floatValue();
                }
            }
            return this.value * scale;

        }

        static float getValue(float value, String units, Boolean w3cLengthUnits) {
            Hashtable<String, Float> mapping = (w3cLengthUnits) ? w3cLengthMapping : lengthMapping;
            float scale = 1;
            if (units != null) {
                Float scaleFloat = mapping.get(units);
                if (scaleFloat != null) {
                    scale = scaleFloat.floatValue();
                }
            }
            return value * scale;
        }

        public String toString() {
            return type + " " + value;
        }

        // 0 - value indicates real value
        // 1 - % value, value relative to depends upon key.
        //     50% will have a value = .5
        // 2 - add value to parent value.
        // 3 - em/ex relative to font size of element (except for
        //     font-size, which is relative to parent).
        short type;
        float value;
        String units = null;


        static final short UNINITALIZED_LENGTH = (short)10;
    }


    /**
     * Class used to parse font property. The font property is shorthand
     * for the other font properties. This expands the properties, placing
     * them in the attributeset.
     */
    static class ShorthandFontParser {
        /**
         * Parses the shorthand font string <code>value</code>, placing the
         * result in <code>attr</code>.
         */
        static void parseShorthandFont(CSS css, String value,
                                       MutableAttributeSet attr) {
            // font is of the form:
            // [ <font-style> || <font-variant> || <font-weight> ]? <font-size>
            //   [ / <line-height> ]? <font-family>
            String[]   strings = CSS.parseStrings(value);
            int        count = strings.length;
            int        index = 0;
            // bitmask, 1 for style, 2 for variant, 3 for weight
            short      found = 0;
            int        maxC = Math.min(3, count);

            // Check for font-style font-variant font-weight
            while (index < maxC) {
                if ((found & 1) == 0 && isFontStyle(strings[index])) {
                    css.addInternalCSSValue(attr, CSS.Attribute.FONT_STYLE,
                                            strings[index++]);
                    found |= 1;
                }
                else if ((found & 2) == 0 && isFontVariant(strings[index])) {
                    css.addInternalCSSValue(attr, CSS.Attribute.FONT_VARIANT,
                                            strings[index++]);
                    found |= 2;
                }
                else if ((found & 4) == 0 && isFontWeight(strings[index])) {
                    css.addInternalCSSValue(attr, CSS.Attribute.FONT_WEIGHT,
                                            strings[index++]);
                    found |= 4;
                }
                else if (strings[index].equals("normal")) {
                    index++;
                }
                else {
                    break;
                }
            }
            if ((found & 1) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_STYLE,
                                        "normal");
            }
            if ((found & 2) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_VARIANT,
                                        "normal");
            }
            if ((found & 4) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_WEIGHT,
                                        "normal");
            }

            // string at index should be the font-size
            if (index < count) {
                String fontSize = strings[index];
                int slashIndex = fontSize.indexOf('/');

                if (slashIndex != -1) {
                    fontSize = fontSize.substring(0, slashIndex);
                    strings[index] = strings[index].substring(slashIndex);
                }
                else {
                    index++;
                }
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_SIZE,
                                        fontSize);
            }
            else {
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_SIZE,
                                        "medium");
            }

            // Check for line height
            if (index < count && strings[index].startsWith("/")) {
                String lineHeight = null;
                if (strings[index].equals("/")) {
                    if (++index < count) {
                        lineHeight = strings[index++];
                    }
                }
                else {
                    lineHeight = strings[index++].substring(1);
                }
                // line height
                if (lineHeight != null) {
                    css.addInternalCSSValue(attr, CSS.Attribute.LINE_HEIGHT,
                                            lineHeight);
                }
                else {
                    css.addInternalCSSValue(attr, CSS.Attribute.LINE_HEIGHT,
                                            "normal");
                }
            }
            else {
                css.addInternalCSSValue(attr, CSS.Attribute.LINE_HEIGHT,
                                        "normal");
            }

            // remainder of strings are font-family
            if (index < count) {
                String family = strings[index++];

                while (index < count) {
                    family += " " + strings[index++];
                }
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_FAMILY,
                                        family);
            }
            else {
                css.addInternalCSSValue(attr, CSS.Attribute.FONT_FAMILY,
                                        Font.SANS_SERIF);
            }
        }

        private static boolean isFontStyle(String string) {
            return (string.equals("italic") ||
                    string.equals("oblique"));
        }

        private static boolean isFontVariant(String string) {
            return (string.equals("small-caps"));
        }

        private static boolean isFontWeight(String string) {
            if (string.equals("bold") || string.equals("bolder") ||
                string.equals("italic") || string.equals("lighter")) {
                return true;
            }
            // test for 100-900
            return (string.length() == 3 &&
                    string.charAt(0) >= '1' && string.charAt(0) <= '9' &&
                    string.charAt(1) == '0' && string.charAt(2) == '0');
        }

    }


    /**
     * Parses the background property into its intrinsic values.
     */
    static class ShorthandBackgroundParser {
        /**
         * Parses the shorthand font string <code>value</code>, placing the
         * result in <code>attr</code>.
         */
        static void parseShorthandBackground(CSS css, String value,
                                             MutableAttributeSet attr) {
            String[] strings = parseStrings(value);
            int count = strings.length;
            int index = 0;
            // bitmask: 0 for image, 1 repeat, 2 attachment, 3 position,
            //          4 color
            short found = 0;

            while (index < count) {
                String string = strings[index++];
                if ((found & 1) == 0 && isImage(string)) {
                    css.addInternalCSSValue(attr, CSS.Attribute.
                                            BACKGROUND_IMAGE, string);
                    found |= 1;
                }
                else if ((found & 2) == 0 && isRepeat(string)) {
                    css.addInternalCSSValue(attr, CSS.Attribute.
                                            BACKGROUND_REPEAT, string);
                    found |= 2;
                }
                else if ((found & 4) == 0 && isAttachment(string)) {
                    css.addInternalCSSValue(attr, CSS.Attribute.
                                            BACKGROUND_ATTACHMENT, string);
                    found |= 4;
                }
                else if ((found & 8) == 0 && isPosition(string)) {
                    if (index < count && isPosition(strings[index])) {
                        css.addInternalCSSValue(attr, CSS.Attribute.
                                                BACKGROUND_POSITION,
                                                string + " " +
                                                strings[index++]);
                    }
                    else {
                        css.addInternalCSSValue(attr, CSS.Attribute.
                                                BACKGROUND_POSITION, string);
                    }
                    found |= 8;
                }
                else if ((found & 16) == 0 && isColor(string)) {
                    css.addInternalCSSValue(attr, CSS.Attribute.
                                            BACKGROUND_COLOR, string);
                    found |= 16;
                }
            }
            if ((found & 1) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.BACKGROUND_IMAGE,
                                        null);
            }
            if ((found & 2) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.BACKGROUND_REPEAT,
                                        "repeat");
            }
            if ((found & 4) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.
                                        BACKGROUND_ATTACHMENT, "scroll");
            }
            if ((found & 8) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.
                                        BACKGROUND_POSITION, null);
            }
            // Currently, there is no good way to express this.
            /*
            if ((found & 16) == 0) {
                css.addInternalCSSValue(attr, CSS.Attribute.BACKGROUND_COLOR,
                                        null);
            }
            */
        }

        static boolean isImage(String string) {
            return (string.startsWith("url(") && string.endsWith(")"));
        }

        static boolean isRepeat(String string) {
            return (string.equals("repeat-x") || string.equals("repeat-y") ||
                    string.equals("repeat") || string.equals("no-repeat"));
        }

        static boolean isAttachment(String string) {
            return (string.equals("fixed") || string.equals("scroll"));
        }

        static boolean isPosition(String string) {
            return (string.equals("top") || string.equals("bottom") ||
                    string.equals("left") || string.equals("right") ||
                    string.equals("center") ||
                    (string.length() > 0 &&
                     Character.isDigit(string.charAt(0))));
        }

        static boolean isColor(String string) {
            return (CSS.stringToColor(string) != null);
        }
    }


    /**
     * Used to parser margin and padding.
     */
    static class ShorthandMarginParser {
        /**
         * Parses the shorthand margin/padding/border string
         * <code>value</code>, placing the result in <code>attr</code>.
         * <code>names</code> give the 4 instrinsic property names.
         */
        static void parseShorthandMargin(CSS css, String value,
                                         MutableAttributeSet attr,
                                         CSS.Attribute[] names) {
            String[] strings = parseStrings(value);
            int count = strings.length;
            int index = 0;
            switch (count) {
            case 0:
                // empty string
                return;
            case 1:
                // Identifies all values.
                for (int counter = 0; counter < 4; counter++) {
                    css.addInternalCSSValue(attr, names[counter], strings[0]);
                }
                break;
            case 2:
                // 0 & 2 = strings[0], 1 & 3 = strings[1]
                css.addInternalCSSValue(attr, names[0], strings[0]);
                css.addInternalCSSValue(attr, names[2], strings[0]);
                css.addInternalCSSValue(attr, names[1], strings[1]);
                css.addInternalCSSValue(attr, names[3], strings[1]);
                break;
            case 3:
                css.addInternalCSSValue(attr, names[0], strings[0]);
                css.addInternalCSSValue(attr, names[1], strings[1]);
                css.addInternalCSSValue(attr, names[2], strings[2]);
                css.addInternalCSSValue(attr, names[3], strings[1]);
                break;
            default:
                for (int counter = 0; counter < 4; counter++) {
                    css.addInternalCSSValue(attr, names[counter],
                                            strings[counter]);
                }
                break;
            }
        }
    }

    static class ShorthandBorderParser {
        static Attribute[] keys = {
            Attribute.BORDER_TOP, Attribute.BORDER_RIGHT,
            Attribute.BORDER_BOTTOM, Attribute.BORDER_LEFT,
        };

        static void parseShorthandBorder(MutableAttributeSet attributes,
                                            CSS.Attribute key, String value) {
            Object[] parts = new Object[CSSBorder.PARSERS.length];
            String[] strings = parseStrings(value);
            for (String s : strings) {
                boolean valid = false;
                for (int i = 0; i < parts.length; i++) {
                    Object v = CSSBorder.PARSERS[i].parseCssValue(s);
                    if (v != null) {
                        if (parts[i] == null) {
                            parts[i] = v;
                            valid = true;
                        }
                        break;
                    }
                }
                if (!valid) {
                    // Part is non-parseable or occured more than once.
                    return;
                }
            }

            // Unspecified parts get default values.
            for (int i = 0; i < parts.length; i++) {
                if (parts[i] == null) {
                    parts[i] = CSSBorder.DEFAULTS[i];
                }
            }

            // Dispatch collected values to individual properties.
            for (int i = 0; i < keys.length; i++) {
                if ((key == Attribute.BORDER) || (key == keys[i])) {
                    for (int k = 0; k < parts.length; k++) {
                        attributes.addAttribute(
                                        CSSBorder.ATTRIBUTES[k][i], parts[k]);
                    }
                }
            }
        }
    }

    /**
     * Calculate the requirements needed to tile the requirements
     * given by the iterator that would be tiled.  The calculation
     * takes into consideration margin and border spacing.
     */
    static SizeRequirements calculateTiledRequirements(LayoutIterator iter, SizeRequirements r) {
        long minimum = 0;
        long maximum = 0;
        long preferred = 0;
        int lastMargin = 0;
        int totalSpacing = 0;
        int n = iter.getCount();
        for (int i = 0; i < n; i++) {
            iter.setIndex(i);
            int margin0 = lastMargin;
            int margin1 = (int) iter.getLeadingCollapseSpan();
            totalSpacing += Math.max(margin0, margin1);
            preferred += (int) iter.getPreferredSpan(0);
            minimum += iter.getMinimumSpan(0);
            maximum += iter.getMaximumSpan(0);

            lastMargin = (int) iter.getTrailingCollapseSpan();
        }
        totalSpacing += lastMargin;
        totalSpacing += 2 * iter.getBorderWidth();

        // adjust for the spacing area
        minimum += totalSpacing;
        preferred += totalSpacing;
        maximum += totalSpacing;

        // set return value
        if (r == null) {
            r = new SizeRequirements();
        }
        r.minimum = (minimum > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)minimum;
        r.preferred = (preferred > Integer.MAX_VALUE) ? Integer.MAX_VALUE :(int) preferred;
        r.maximum = (maximum > Integer.MAX_VALUE) ? Integer.MAX_VALUE :(int) maximum;
        return r;
    }

    /**
     * Calculate a tiled layout for the given iterator.
     * This should be done collapsing the neighboring
     * margins to be a total of the maximum of the two
     * neighboring margin areas as described in the CSS spec.
     */
    static void calculateTiledLayout(LayoutIterator iter, int targetSpan) {

        /*
         * first pass, calculate the preferred sizes, adjustments needed because
         * of margin collapsing, and the flexibility to adjust the sizes.
         */
        long preferred = 0;
        long currentPreferred;
        int lastMargin = 0;
        int totalSpacing = 0;
        int n = iter.getCount();
        int adjustmentWeightsCount = LayoutIterator.WorstAdjustmentWeight + 1;
        //max gain we can get adjusting elements with adjustmentWeight <= i
        long gain[] = new long[adjustmentWeightsCount];
        //max loss we can get adjusting elements with adjustmentWeight <= i
        long loss[] = new long[adjustmentWeightsCount];

        for (int i = 0; i < adjustmentWeightsCount; i++) {
            gain[i] = loss[i] = 0;
        }
        for (int i = 0; i < n; i++) {
            iter.setIndex(i);
            int margin0 = lastMargin;
            int margin1 = (int) iter.getLeadingCollapseSpan();

            iter.setOffset(Math.max(margin0, margin1));
            totalSpacing += iter.getOffset();

            currentPreferred = (long)iter.getPreferredSpan(targetSpan);
            iter.setSpan((int) currentPreferred);
            preferred += currentPreferred;
            gain[iter.getAdjustmentWeight()] +=
                (long)iter.getMaximumSpan(targetSpan) - currentPreferred;
            loss[iter.getAdjustmentWeight()] +=
                currentPreferred - (long)iter.getMinimumSpan(targetSpan);
            lastMargin = (int) iter.getTrailingCollapseSpan();
        }
        totalSpacing += lastMargin;
        totalSpacing += 2 * iter.getBorderWidth();

        for (int i = 1; i < adjustmentWeightsCount; i++) {
            gain[i] += gain[i - 1];
            loss[i] += loss[i - 1];
        }

        /*
         * Second pass, expand or contract by as much as possible to reach
         * the target span.  This takes the margin collapsing into account
         * prior to adjusting the span.
         */

        // determine the adjustment to be made
        int allocated = targetSpan - totalSpacing;
        long desiredAdjustment = allocated - preferred;
        long adjustmentsArray[] = (desiredAdjustment > 0) ? gain : loss;
        desiredAdjustment = Math.abs(desiredAdjustment);
        int adjustmentLevel = 0;
        for (;adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight;
             adjustmentLevel++) {
            // adjustmentsArray[] is sorted. I do not bother about
            // binary search though
            if (adjustmentsArray[adjustmentLevel] >= desiredAdjustment) {
                break;
            }
        }
        float adjustmentFactor = 0.0f;
        if (adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight) {
            desiredAdjustment -= (adjustmentLevel > 0) ?
                adjustmentsArray[adjustmentLevel - 1] : 0;
            if (desiredAdjustment != 0) {
                float maximumAdjustment =
                    adjustmentsArray[adjustmentLevel] -
                    ((adjustmentLevel > 0) ?
                     adjustmentsArray[adjustmentLevel - 1] : 0
                     );
                adjustmentFactor = desiredAdjustment / maximumAdjustment;
            }
        }
        // make the adjustments
        int totalOffset = (int)iter.getBorderWidth();
        for (int i = 0; i < n; i++) {
            iter.setIndex(i);
            iter.setOffset( iter.getOffset() + totalOffset);
            if (iter.getAdjustmentWeight() < adjustmentLevel) {
                iter.setSpan((int)
                             ((allocated > preferred) ?
                              Math.floor(iter.getMaximumSpan(targetSpan)) :
                              Math.ceil(iter.getMinimumSpan(targetSpan))
                              )
                             );
            } else if (iter.getAdjustmentWeight() == adjustmentLevel) {
                int availableSpan = (allocated > preferred) ?
                    (int) iter.getMaximumSpan(targetSpan) - iter.getSpan() :
                    iter.getSpan() - (int) iter.getMinimumSpan(targetSpan);
                int adj = (int)Math.floor(adjustmentFactor * availableSpan);
                iter.setSpan(iter.getSpan() +
                             ((allocated > preferred) ? adj : -adj));
            }
            totalOffset = (int) Math.min((long) iter.getOffset() +
                                         (long) iter.getSpan(),
                                         Integer.MAX_VALUE);
        }

        // while rounding we could lose several pixels.
        int roundError = targetSpan - totalOffset -
            (int)iter.getTrailingCollapseSpan() -
            (int)iter.getBorderWidth();
        int adj = (roundError > 0) ? 1 : -1;
        roundError *= adj;

        boolean canAdjust = true;
        while (roundError > 0 && canAdjust) {
            // check for infinite loop
            canAdjust = false;
            int offsetAdjust = 0;
            // try to distribute roundError. one pixel per cell
            for (int i = 0; i < n; i++) {
                iter.setIndex(i);
                iter.setOffset(iter.getOffset() + offsetAdjust);
                int curSpan = iter.getSpan();
                if (roundError > 0) {
                    int boundGap = (adj > 0) ?
                        (int)Math.floor(iter.getMaximumSpan(targetSpan)) - curSpan :
                        curSpan - (int)Math.ceil(iter.getMinimumSpan(targetSpan));
                    if (boundGap >= 1) {
                        canAdjust = true;
                        iter.setSpan(curSpan + adj);
                        offsetAdjust += adj;
                        roundError--;
                    }
                }
            }
        }
    }

    /**
     * An iterator to express the requirements to use when computing
     * layout.
     */
    interface LayoutIterator {

        void setOffset(int offs);

        int getOffset();

        void setSpan(int span);

        int getSpan();

        int getCount();

        void setIndex(int i);

        float getMinimumSpan(float parentSpan);

        float getPreferredSpan(float parentSpan);

        float getMaximumSpan(float parentSpan);

        int getAdjustmentWeight(); //0 is the best weight WorstAdjustmentWeight is a worst one

        //float getAlignment();

        float getBorderWidth();

        float getLeadingCollapseSpan();

        float getTrailingCollapseSpan();
        public static final int WorstAdjustmentWeight = 2;
    }

    //
    // Serialization support
    //

    private void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        s.defaultWriteObject();

        // Determine what values in valueConvertor need to be written out.
        Enumeration keys = valueConvertor.keys();
        s.writeInt(valueConvertor.size());
        if (keys != null) {
            while (keys.hasMoreElements()) {
                Object key = keys.nextElement();
                Object value = valueConvertor.get(key);
                if (!(key instanceof Serializable) &&
                    (key = StyleContext.getStaticAttributeKey(key)) == null) {
                    // Should we throw an exception here?
                    key = null;
                    value = null;
                }
                else if (!(value instanceof Serializable) &&
                    (value = StyleContext.getStaticAttributeKey(value)) == null){
                    // Should we throw an exception here?
                    key = null;
                    value = null;
                }
                s.writeObject(key);
                s.writeObject(value);
            }
        }
    }

    private void readObject(ObjectInputStream s)
      throws ClassNotFoundException, IOException
    {
        s.defaultReadObject();
        // Reconstruct the hashtable.
        int numValues = s.readInt();
        valueConvertor = new Hashtable<Object, Object>(Math.max(1, numValues));
        while (numValues-- > 0) {
            Object key = s.readObject();
            Object value = s.readObject();
            Object staticKey = StyleContext.getStaticAttribute(key);
            if (staticKey != null) {
                key = staticKey;
            }
            Object staticValue = StyleContext.getStaticAttribute(value);
            if (staticValue != null) {
                value = staticValue;
            }
            if (key != null && value != null) {
                valueConvertor.put(key, value);
            }
        }
    }


    /*
     * we need StyleSheet for resolving lenght units. (see
     * isW3CLengthUnits)
     * we can not pass stylesheet for handling relative sizes. (do not
     * think changing public API is necessary)
     * CSS is not likely to be accessed from more then one thread.
     * Having local storage for StyleSheet for resolving relative
     * sizes is safe
     *
     * idk 08/30/2004
     */
    private StyleSheet getStyleSheet(StyleSheet ss) {
        if (ss != null) {
            styleSheet = ss;
        }
        return styleSheet;
    }
    //
    // Instance variables
    //

    /** Maps from CSS key to CssValue. */
    private transient Hashtable<Object, Object> valueConvertor;

    /** Size used for relative units. */
    private int baseFontSize;

    private transient StyleSheet styleSheet = null;

    static int baseFontSizeIndex = 3;
}
