/* StyleSheet.java --
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text.html;

import gnu.javax.swing.text.html.css.BorderWidth;
import gnu.javax.swing.text.html.css.CSSColor;
import gnu.javax.swing.text.html.css.CSSParser;
import gnu.javax.swing.text.html.css.CSSParserCallback;
import gnu.javax.swing.text.html.css.FontSize;
import gnu.javax.swing.text.html.css.FontStyle;
import gnu.javax.swing.text.html.css.FontWeight;
import gnu.javax.swing.text.html.css.Length;
import gnu.javax.swing.text.html.css.Selector;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.border.Border;
import javax.swing.event.ChangeListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.View;


/**
 * This class adds support for defining the visual characteristics of HTML views
 * being rendered. This enables views to be customized by a look-and-feel, mulitple
 * views over the same model can be rendered differently. Each EditorPane has its
 * own StyleSheet, but by default one sheet will be shared by all of the HTMLEditorKit
 * instances. An HTMLDocument can also have a StyleSheet, which holds specific CSS
 * specs.
 *
 *  In order for Views to store less state and therefore be more lightweight,
 *  the StyleSheet can act as a factory for painters that handle some of the
 *  rendering tasks. Since the StyleSheet may be used by views over multiple
 *  documents the HTML attributes don't effect the selector being used.
 *
 *  The rules are stored as named styles, and other information is stored to
 *  translate the context of an element to a rule.
 *
 * @author Lillian Angel (langel@redhat.com)
 */
public class StyleSheet extends StyleContext
{

  /**
   * Parses CSS stylesheets using the parser in gnu/javax/swing/html/css.
   *
   * This is package private to avoid accessor methods.
   */
  class CSSStyleSheetParserCallback
    implements CSSParserCallback
  {
    /**
     * The current styles.
     */
    private CSSStyle[] styles;

    /**
     * The precedence of the stylesheet to be parsed.
     */
    private int precedence;

    /**
     * Creates a new CSS parser. This parser parses a CSS stylesheet with
     * the specified precedence.
     *
     * @param prec the precedence, according to the constants defined in
     *        CSSStyle
     */
    CSSStyleSheetParserCallback(int prec)
    {
      precedence = prec;
    }

    /**
     * Called at the beginning of a statement.
     *
     * @param sel the selector
     */
    public void startStatement(Selector[] sel)
    {
      styles = new CSSStyle[sel.length];
      for (int i = 0; i < sel.length; i++)
        styles[i] = new CSSStyle(precedence, sel[i]);
    }

    /**
     * Called at the end of a statement.
     */
    public void endStatement()
    {
      for (int i = 0; i < styles.length; i++)
        css.add(styles[i]);
      styles = null;
    }

    /**
     * Called when a declaration is parsed.
     *
     * @param property the property
     * @param value the value
     */
    public void declaration(String property, String value)
    {
      CSS.Attribute cssAtt = CSS.getAttribute(property);
      Object val = CSS.getValue(cssAtt, value);
      for (int i = 0; i < styles.length; i++)
        {
          CSSStyle style = styles[i];
          CSS.addInternal(style, cssAtt, value);
          if (cssAtt != null)
            style.addAttribute(cssAtt, val);
        }
    }

  }

  /**
   * Represents a style that is defined by a CSS rule.
   */
  private class CSSStyle
    extends SimpleAttributeSet
    implements Style, Comparable<CSSStyle>
  {

    static final int PREC_UA = 0;
    static final int PREC_NORM = 100000;
    static final int PREC_AUTHOR_NORMAL = 200000;
    static final int PREC_AUTHOR_IMPORTANT = 300000;
    static final int PREC_USER_IMPORTANT = 400000;

    /**
     * The priority of this style when matching CSS selectors.
     */
    private int precedence;

    /**
     * The selector for this rule.
     *
     * This is package private to avoid accessor methods.
     */
    Selector selector;

    CSSStyle(int prec, Selector sel)
    {
      precedence = prec;
      selector = sel;
    }

    public String getName()
    {
      // TODO: Implement this for correctness.
      return null;
    }

    public void addChangeListener(ChangeListener listener)
    {
      // TODO: Implement this for correctness.
    }

    public void removeChangeListener(ChangeListener listener)
    {
      // TODO: Implement this for correctness.
    }

    /**
     * Sorts the rule according to the style's precedence and the
     * selectors specificity.
     */
    public int compareTo(CSSStyle other)
    {
      return other.precedence + other.selector.getSpecificity()
             - precedence - selector.getSpecificity();
    }

  }

  /** The base URL */
  URL base;

  /** Base font size (int) */
  int baseFontSize;

  /**
   * The linked style sheets stored.
   */
  private ArrayList<StyleSheet> linked;

  /**
   * Maps element names (selectors) to AttributSet (the corresponding style
   * information).
   */
  ArrayList<CSSStyle> css = new ArrayList<CSSStyle>();

  /**
   * Maps selectors to their resolved styles.
   */
  private HashMap<String,Style> resolvedStyles;

  /**
   * Constructs a StyleSheet.
   */
  public StyleSheet()
  {
    super();
    baseFontSize = 4; // Default font size from CSS
    resolvedStyles = new HashMap<String,Style>();
  }

  /**
   * Gets the style used to render the given tag. The element represents the tag
   * and can be used to determine the nesting, where the attributes will differ
   * if there is nesting inside of elements.
   *
   * @param t - the tag to translate to visual attributes
   * @param e - the element representing the tag
   * @return the set of CSS attributes to use to render the tag.
   */
  public Style getRule(HTML.Tag t, Element e)
  {
    // Create list of the element and all of its parents, starting
    // with the bottommost element.
    ArrayList<Element> path = new ArrayList<Element>();
    Element el;
    AttributeSet atts;
    for (el = e; el != null; el = el.getParentElement())
      path.add(el);

    // Create fully qualified selector.
    StringBuilder selector = new StringBuilder();
    int count = path.size();
    // We append the actual element after this loop.
    for (int i = count - 1; i > 0; i--)
      {
        el = path.get(i);
        atts = el.getAttributes();
        Object name = atts.getAttribute(StyleConstants.NameAttribute);
        selector.append(name.toString());
        if (atts.isDefined(HTML.Attribute.ID))
          {
            selector.append('#');
            selector.append(atts.getAttribute(HTML.Attribute.ID));
          }
        if (atts.isDefined(HTML.Attribute.CLASS))
          {
            selector.append('.');
            selector.append(atts.getAttribute(HTML.Attribute.CLASS));
          }
        if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
          {
            selector.append(':');
            selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
          }
        if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
          {
            selector.append(':');
            selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
          }
        selector.append(' ');
      }
    selector.append(t.toString());
    el = path.get(0);
    atts = el.getAttributes();
    // For leaf elements, we have to fetch the tag specific attributes.
    if (el.isLeaf())
      {
        Object o = atts.getAttribute(t);
        if (o instanceof AttributeSet)
          atts = (AttributeSet) o;
        else
          atts = null;
      }
    if (atts != null)
      {
        if (atts.isDefined(HTML.Attribute.ID))
          {
            selector.append('#');
            selector.append(atts.getAttribute(HTML.Attribute.ID));
          }
        if (atts.isDefined(HTML.Attribute.CLASS))
          {
            selector.append('.');
            selector.append(atts.getAttribute(HTML.Attribute.CLASS));
          }
        if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
          {
            selector.append(':');
            selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
          }
        if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
          {
            selector.append(':');
            selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
          }
      }
    return getResolvedStyle(selector.toString(), path, t);
  }

  /**
   * Fetches a resolved style. If there is no resolved style for the
   * specified selector, the resolve the style using
   * {@link #resolveStyle(String, List, HTML.Tag)}.
   *
   * @param selector the selector for which to resolve the style
   * @param path the Element path, used in the resolving algorithm
   * @param tag the tag for which to resolve
   *
   * @return the resolved style
   */
  private Style getResolvedStyle(String selector, List<Element> path, HTML.Tag tag)
  {
    Style style = resolvedStyles.get(selector);
    if (style == null)
      style = resolveStyle(selector, path, tag);
    return style;
  }

  /**
   * Resolves a style. This creates arrays that hold the tag names,
   * class and id attributes and delegates the work to
   * {@link #resolveStyle(String, String[], List<Map<String,String>>)}.
   *
   * @param selector the selector
   * @param path the Element path
   * @param tag the tag
   *
   * @return the resolved style
   */
  private Style resolveStyle(String selector, List<Element> path, HTML.Tag tag)
  {
    int count = path.size();
    String[] tags = new String[count];
    List<Map<String,String>> attributes =
      new ArrayList<Map<String,String>>(count);
    for (int i = 0; i < count; i++)
      {
        Element el = path.get(i);
        AttributeSet atts = el.getAttributes();
        if (i == 0 && el.isLeaf())
          {
            Object o = atts.getAttribute(tag);
            if (o instanceof AttributeSet)
              atts = (AttributeSet) o;
            else
              atts = null;
          }
        if (atts != null)
          {
            HTML.Tag t =
              (HTML.Tag) atts.getAttribute(StyleConstants.NameAttribute);
            if (t != null)
              tags[i] = t.toString();
            else
              tags[i] = null;
            attributes.add(attributeSetToMap(atts));
          }
        else
          {
            tags[i] = null;
            attributes.add(null);
          }
      }
    tags[0] = tag.toString();
    return resolveStyle(selector, tags, attributes);
  }

  /**
   * Performs style resolving.
   *
   * @param selector the selector
   * @param tags the tags
   * @param attributes the attributes of the tags
   *
   * @return the resolved style
   */
  private Style resolveStyle(String selector, String[] tags,
                             List<Map<String,String>> attributes)
  {
    // FIXME: This style resolver is not correct. But it works good enough for
    // the default.css.
    ArrayList<CSSStyle> styles = new ArrayList<CSSStyle>();
    for (CSSStyle style : css)
      {
        if (style.selector.matches(tags, attributes))
          styles.add(style);
      }

    // Add styles from linked stylesheets.
    if (linked != null)
      {
        for (int i = linked.size() - 1; i >= 0; i--)
          {
            StyleSheet ss = linked.get(i);
            for (int j = ss.css.size() - 1; j >= 0; j--)
              {
                CSSStyle style = ss.css.get(j);
                if (style.selector.matches(tags, attributes))
                  styles.add(style);
              }
          }
      }

    // Sort selectors.
    Collections.sort(styles);
    Style[] styleArray = styles.toArray(new Style[styles.size()]);
    Style resolved = new MultiStyle(selector, styleArray);
    resolvedStyles.put(selector, resolved);
    return resolved;
  }

  /**
   * Gets the rule that best matches the selector. selector is a space
   * separated String of element names. The attributes of the returned
   * Style will change as rules are added and removed.
   *
   * @param selector - the element names separated by spaces
   * @return the set of CSS attributes to use to render
   */
  public Style getRule(String selector)
  {
    CSSStyle best = null;
    for (Iterator<CSSStyle> i = css.iterator(); i.hasNext();)
      {
        CSSStyle style = i.next();
        if (style.compareTo(best) < 0)
          best = style;
      }
    return best;
  }

  /**
   * Adds a set of rules to the sheet. The rules are expected to be in valid
   * CSS format. This is called as a result of parsing a <style> tag
   *
   * @param rule - the rule to add to the sheet
   */
  public void addRule(String rule)
  {
    CSSStyleSheetParserCallback cb =
      new CSSStyleSheetParserCallback(CSSStyle.PREC_AUTHOR_NORMAL);
    // FIXME: Handle ref.
    StringReader in = new StringReader(rule);
    CSSParser parser = new CSSParser(in, cb);
    try
      {
        parser.parse();
      }
    catch (IOException ex)
      {
        // Shouldn't happen. And if, then don't let it bork the outside code.
      }
    // Clean up resolved styles cache so that the new styles are recognized
    // on next stylesheet request.
    resolvedStyles.clear();
  }

  /**
   * Translates a CSS declaration into an AttributeSet. This is called
   * as a result of encountering an HTML style attribute.
   *
   * @param decl - the declaration to get
   * @return the AttributeSet representing the declaration
   */
  public AttributeSet getDeclaration(String decl)
  {
    if (decl == null)
      return SimpleAttributeSet.EMPTY;
    // FIXME: Not implemented.
    return null;
  }

  /**
   * Loads a set of rules that have been specified in terms of CSS grammar.
   * If there are any conflicts with existing rules, the new rule is added.
   *
   * @param in - the stream to read the CSS grammar from.
   * @param ref - the reference URL. It is the location of the stream, it may
   * be null. All relative URLs specified in the stream will be based upon this
   * parameter.
   * @throws IOException - For any IO error while reading
   */
  public void loadRules(Reader in, URL ref)
    throws IOException
  {
    CSSStyleSheetParserCallback cb =
      new CSSStyleSheetParserCallback(CSSStyle.PREC_UA);
    // FIXME: Handle ref.
    CSSParser parser = new CSSParser(in, cb);
    parser.parse();
  }

  /**
   * Gets a set of attributes to use in the view. This is a set of
   * attributes that can be used for View.getAttributes
   *
   * @param v - the view to get the set for
   * @return the AttributeSet to use in the view.
   */
  public AttributeSet getViewAttributes(View v)
  {
    return new ViewAttributeSet(v, this);
  }

  /**
   * Removes a style previously added.
   *
   * @param nm - the name of the style to remove
   */
  public void removeStyle(String nm)
  {
    // FIXME: Not implemented.
    super.removeStyle(nm);
  }

  /**
   * Adds the rules from ss to those of the receiver. ss's rules will
   * override the old rules. An added StyleSheet will never override the rules
   * of the receiving style sheet.
   *
   * @param ss - the new StyleSheet.
   */
  public void addStyleSheet(StyleSheet ss)
  {
    if (linked == null)
      linked = new ArrayList<StyleSheet>();
    linked.add(ss);
  }

  /**
   * Removes ss from those of the receiver
   *
   * @param ss - the StyleSheet to remove.
   */
  public void removeStyleSheet(StyleSheet ss)
  {
    if (linked != null)
      {
        linked.remove(ss);
      }
  }

  /**
   * Returns an array of the linked StyleSheets. May return null.
   *
   * @return - An array of the linked StyleSheets.
   */
  public StyleSheet[] getStyleSheets()
  {
    StyleSheet[] linkedSS;
    if (linked != null)
      {
        linkedSS = new StyleSheet[linked.size()];
        linkedSS = linked.toArray(linkedSS);
      }
    else
      {
        linkedSS = null;
      }
    return linkedSS;
  }

  /**
   * Imports a style sheet from the url. The rules are directly added to the
   * receiver. This is usually called when a <link> tag is resolved in an
   * HTML document.
   *
   * @param url the URL to import the StyleSheet from
   */
  public void importStyleSheet(URL url)
  {
    try
      {
        InputStream in = url.openStream();
        Reader r = new BufferedReader(new InputStreamReader(in));
        CSSStyleSheetParserCallback cb =
          new CSSStyleSheetParserCallback(CSSStyle.PREC_AUTHOR_NORMAL);
        CSSParser parser = new CSSParser(r, cb);
        parser.parse();
      }
    catch (IOException ex)
      {
        // We can't do anything about it I guess.
      }
  }

  /**
   * Sets the base url. All import statements that are relative, will be
   * relative to base.
   *
   * @param base -
   *          the base URL.
   */
  public void setBase(URL base)
  {
    this.base = base;
  }

  /**
   * Gets the base url.
   *
   * @return - the base
   */
  public URL getBase()
  {
    return base;
  }

  /**
   * Adds a CSS attribute to the given set.
   *
   * @param attr - the attribute set
   * @param key - the attribute to add
   * @param value - the value of the key
   */
  public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key,
                              String value)
  {
    Object val = CSS.getValue(key, value);
    CSS.addInternal(attr, key, value);
    attr.addAttribute(key, val);
  }

  /**
   * Adds a CSS attribute to the given set.
   * This method parses the value argument from HTML based on key.
   * Returns true if it finds a valid value for the given key,
   * and false otherwise.
   *
   * @param attr - the attribute set
   * @param key - the attribute to add
   * @param value - the value of the key
   * @return true if a valid value was found.
   */
  public boolean addCSSAttributeFromHTML(MutableAttributeSet attr, CSS.Attribute key,
                                         String value)
  {
    // FIXME: Need to parse value from HTML based on key.
    attr.addAttribute(key, value);
    return attr.containsAttribute(key, value);
  }

  /**
   * Converts a set of HTML attributes to an equivalent set of CSS attributes.
   *
   * @param htmlAttrSet - the set containing the HTML attributes.
   * @return the set of CSS attributes
   */
  public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet)
  {
    AttributeSet cssAttr = htmlAttrSet.copyAttributes();

    // The HTML align attribute maps directly to the CSS text-align attribute.
    Object o = htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
    if (o != null)
      cssAttr = addAttribute(cssAttr, CSS.Attribute.TEXT_ALIGN, o);

    // The HTML width attribute maps directly to CSS width.
    o = htmlAttrSet.getAttribute(HTML.Attribute.WIDTH);
    if (o != null)
      cssAttr = addAttribute(cssAttr, CSS.Attribute.WIDTH,
                             new Length(o.toString()));

    // The HTML height attribute maps directly to CSS height.
    o = htmlAttrSet.getAttribute(HTML.Attribute.HEIGHT);
    if (o != null)
      cssAttr = addAttribute(cssAttr, CSS.Attribute.HEIGHT,
                             new Length(o.toString()));

    o = htmlAttrSet.getAttribute(HTML.Attribute.NOWRAP);
    if (o != null)
      cssAttr = addAttribute(cssAttr, CSS.Attribute.WHITE_SPACE, "nowrap");

    // Map cellspacing attr of tables to CSS border-spacing.
    o = htmlAttrSet.getAttribute(HTML.Attribute.CELLSPACING);
    if (o != null)
      cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_SPACING,
                             new Length(o.toString()));

    // For table cells and headers, fetch the cellpadding value from the
    // parent table and set it as CSS padding attribute.
    HTML.Tag tag = (HTML.Tag)
                   htmlAttrSet.getAttribute(StyleConstants.NameAttribute);
    if ((tag == HTML.Tag.TD || tag == HTML.Tag.TH)
        && htmlAttrSet instanceof Element)
      {
        Element el = (Element) htmlAttrSet;
        AttributeSet tableAttrs = el.getParentElement().getParentElement()
                                  .getAttributes();
        o = tableAttrs.getAttribute(HTML.Attribute.CELLPADDING);
        if (o != null)
          {
            Length l = new Length(o.toString());
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_BOTTOM, l);
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_LEFT, l);
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_RIGHT, l);
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_TOP, l);
          }
        o = tableAttrs.getAttribute(HTML.Attribute.BORDER);
        cssAttr = translateBorder(cssAttr, o);
      }

    // Translate border attribute.
    o = cssAttr.getAttribute(HTML.Attribute.BORDER);
    cssAttr = translateBorder(cssAttr, o);

    // TODO: Add more mappings.
    return cssAttr;
  }

  /**
   * Translates a HTML border attribute to a corresponding set of CSS
   * attributes.
   *
   * @param cssAttr the original set of CSS attributes to add to
   * @param o the value of the border attribute
   *
   * @return the new set of CSS attributes
   */
  private AttributeSet translateBorder(AttributeSet cssAttr, Object o)
  {
    if (o != null)
      {
        BorderWidth l = new BorderWidth(o.toString());
        if (l.getValue() > 0)
          {
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_WIDTH, l);
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_STYLE,
                                   "solid");
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_COLOR,
                                   new CSSColor("black"));
          }
      }
    return cssAttr;
  }

  /**
   * Adds an attribute to the given set and returns a new set. This is implemented
   * to convert StyleConstants attributes to CSS before forwarding them to the superclass.
   * The StyleConstants attribute do not have corresponding CSS entry, the attribute
   * is stored (but will likely not be used).
   *
   * @param old - the old set
   * @param key - the non-null attribute key
   * @param value - the attribute value
   * @return the updated set
   */
  public AttributeSet addAttribute(AttributeSet old, Object key,
                                   Object value)
  {
    // FIXME: Not implemented.
    return super.addAttribute(old, key, value);
  }

  /**
   * Adds a set of attributes to the element. If any of these attributes are
   * StyleConstants, they will be converted to CSS before forwarding to the
   * superclass.
   *
   * @param old - the old set
   * @param attr - the attributes to add
   * @return the updated attribute set
   */
  public AttributeSet addAttributes(AttributeSet old, AttributeSet attr)
  {
    // FIXME: Not implemented.
    return super.addAttributes(old, attr);
  }

  /**
   * Removes an attribute from the set. If the attribute is a
   * StyleConstants, it will be converted to CSS before forwarding to the
   * superclass.
   *
   * @param old - the old set
   * @param key - the non-null attribute key
   * @return the updated set
   */
  public AttributeSet removeAttribute(AttributeSet old, Object key)
  {
    // FIXME: Not implemented.
    return super.removeAttribute(old, key);
  }

  /**
   * Removes an attribute from the set. If any of the attributes are
   * StyleConstants, they will be converted to CSS before forwarding to the
   * superclass.
   *
   * @param old - the old set
   * @param attrs - the attributes to remove
   * @return the updated set
   */
  public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs)
  {
    // FIXME: Not implemented.
    return super.removeAttributes(old, attrs);
  }

  /**
   * Removes a set of attributes for the element. If any of the attributes is a
   * StyleConstants, they will be converted to CSS before forwarding to the
   * superclass.
   *
   * @param old - the old attribute set
   * @param names - the attribute names
   * @return the update attribute set
   */
  public AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names)
  {
    // FIXME: Not implemented.
    return super.removeAttributes(old, names);
  }

  /**
   * Creates a compact set of attributes that might be shared. This is a hook
   * for subclasses that want to change the behaviour of SmallAttributeSet.
   *
   * @param a - the set of attributes to be represented in the compact form.
   * @return the set of attributes created
   */
  protected StyleContext.SmallAttributeSet createSmallAttributeSet(AttributeSet a)
  {
    return super.createSmallAttributeSet(a);
  }

  /**
   * Creates a large set of attributes. This set is not shared. This is a hook
   * for subclasses that want to change the behaviour of the larger attribute
   * storage format.
   *
   * @param a - the set of attributes to be represented in the larger form.
   * @return the large set of attributes.
   */
  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
  {
    return super.createLargeAttributeSet(a);
  }

  /**
   * Gets the font to use for the given set.
   *
   * @param a - the set to get the font for.
   * @return the font for the set
   */
  public Font getFont(AttributeSet a)
  {
    int realSize = getFontSize(a);

    // Decrement size for subscript and superscript.
    Object valign = a.getAttribute(CSS.Attribute.VERTICAL_ALIGN);
    if (valign != null)
      {
        String v = valign.toString();
        if (v.contains("sup") || v.contains("sub"))
          realSize -= 2;
      }

    // TODO: Convert font family.
    String family = "SansSerif";

    int style = Font.PLAIN;
    FontWeight weight = (FontWeight) a.getAttribute(CSS.Attribute.FONT_WEIGHT);
    if (weight != null)
      style |= weight.getValue();
    FontStyle fStyle = (FontStyle) a.getAttribute(CSS.Attribute.FONT_STYLE);
    if (fStyle != null)
      style |= fStyle.getValue();
    return new Font(family, style, realSize);
  }

  /**
   * Determines the EM base value based on the specified attributes.
   *
   * @param atts the attibutes
   *
   * @return the EM base value
   */
  float getEMBase(AttributeSet atts)
  {
    Font font = getFont(atts);
    FontRenderContext ctx = new FontRenderContext(null, false, false);
    Rectangle2D bounds = font.getStringBounds("M", ctx);
    return (float) bounds.getWidth();
  }

  /**
   * Determines the EX base value based on the specified attributes.
   *
   * @param atts the attibutes
   *
   * @return the EX base value
   */
  float getEXBase(AttributeSet atts)
  {
    Font font = getFont(atts);
    FontRenderContext ctx = new FontRenderContext(null, false, false);
    Rectangle2D bounds = font.getStringBounds("x", ctx);
    return (float) bounds.getHeight();
  }

  /**
   * Resolves the fontsize for a given set of attributes.
   *
   * @param atts the attributes
   *
   * @return the resolved font size
   */
  private int getFontSize(AttributeSet atts)
  {
    int size = 12;
    if (atts.isDefined(CSS.Attribute.FONT_SIZE))
      {
        FontSize fs = (FontSize) atts.getAttribute(CSS.Attribute.FONT_SIZE);
        if (fs.isRelative())
          {
            int parSize = 12;
            AttributeSet resolver = atts.getResolveParent();
            if (resolver != null)
              parSize = getFontSize(resolver);
            size = fs.getValue(parSize);
          }
        else
          {
            size = fs.getValue();
          }
      }
    else
      {
        AttributeSet resolver = atts.getResolveParent();
        if (resolver != null)
          size = getFontSize(resolver);
      }
    return size;
  }

  /**
   * Takes a set of attributes and turns it into a foreground
   * color specification. This is used to specify things like, brigher, more hue
   * etc.
   *
   * @param a - the set to get the foreground color for
   * @return the foreground color for the set
   */
  public Color getForeground(AttributeSet a)
  {
    CSSColor c = (CSSColor) a.getAttribute(CSS.Attribute.COLOR);
    Color color = null;
    if (c != null)
      color = c.getValue();
    return color;
  }

  /**
   * Takes a set of attributes and turns it into a background
   * color specification. This is used to specify things like, brigher, more hue
   * etc.
   *
   * @param a - the set to get the background color for
   * @return the background color for the set
   */
  public Color getBackground(AttributeSet a)
  {
    CSSColor c = (CSSColor) a.getAttribute(CSS.Attribute.BACKGROUND_COLOR);
    Color color = null;
    if (c != null)
      color = c.getValue();
    return color;
  }

  /**
   * Gets the box formatter to use for the given set of CSS attributes.
   *
   * @param a - the given set
   * @return the box formatter
   */
  public BoxPainter getBoxPainter(AttributeSet a)
  {
    return new BoxPainter(a, this);
  }

  /**
   * Gets the list formatter to use for the given set of CSS attributes.
   *
   * @param a - the given set
   * @return the list formatter
   */
  public ListPainter getListPainter(AttributeSet a)
  {
    return new ListPainter(a, this);
  }

  /**
   * Sets the base font size between 1 and 7.
   *
   * @param sz - the new font size for the base.
   */
  public void setBaseFontSize(int sz)
  {
    if (sz <= 7 && sz >= 1)
      baseFontSize = sz;
  }

  /**
   * Sets the base font size from the String. It can either identify
   * a specific font size (between 1 and 7) or identify a relative
   * font size such as +1 or -2.
   *
   * @param size - the new font size as a String.
   */
  public void setBaseFontSize(String size)
  {
    size = size.trim();
    int temp = 0;
    try
      {
        if (size.length() == 2)
          {
            int i = new Integer(size.substring(1)).intValue();
            if (size.startsWith("+"))
              temp = baseFontSize + i;
            else if (size.startsWith("-"))
              temp = baseFontSize - i;
          }
        else if (size.length() == 1)
          temp = new Integer(size.substring(0)).intValue();

        if (temp <= 7 && temp >= 1)
          baseFontSize = temp;
      }
    catch (NumberFormatException nfe)
      {
        // Do nothing here
      }
  }

  /**
   * TODO
   *
   * @param pt - TODO
   * @return TODO
   */
  public static int getIndexOfSize(float pt)
  {
    // FIXME: Not implemented.
    return 0;
  }

  /**
   * Gets the point size, given a size index.
   *
   * @param index - the size index
   * @return the point size.
   */
  public float getPointSize(int index)
  {
    // FIXME: Not implemented.
    return 0;
  }

  /**
   * Given the string of the size, returns the point size value.
   *
   * @param size - the string representation of the size.
   * @return - the point size value.
   */
  public float getPointSize(String size)
  {
    // FIXME: Not implemented.
    return 0;
  }

  /**
   * Convert the color string represenation into java.awt.Color. The valid
   * values are like "aqua" , "#00FFFF" or "rgb(1,6,44)".
   *
   * @param colorName the color to convert.
   * @return the matching java.awt.color
   */
  public Color stringToColor(String colorName)
  {
    return CSSColor.convertValue(colorName);
  }

  /**
   * This class carries out some of the duties of CSS formatting. This enables views
   * to present the CSS formatting while not knowing how the CSS values are cached.
   *
   * This object is reponsible for the insets of a View and making sure
   * the background is maintained according to the CSS attributes.
   *
   * @author Lillian Angel (langel@redhat.com)
   */
  public static class BoxPainter extends Object implements Serializable
  {

    /**
     * The left inset.
     */
    private float leftInset;

    /**
     * The right inset.
     */
    private float rightInset;

    /**
     * The top inset.
     */
    private float topInset;

    /**
     * The bottom inset.
     */
    private float bottomInset;

    /**
     * The border of the box.
     */
    private Border border;

    private float leftPadding;
    private float rightPadding;
    private float topPadding;
    private float bottomPadding;

    /**
     * The background color.
     */
    private Color background;

    /**
     * Package-private constructor.
     *
     * @param as - AttributeSet for painter
     */
    BoxPainter(AttributeSet as, StyleSheet ss)
    {
      float emBase = ss.getEMBase(as);
      float exBase = ss.getEXBase(as);
      // Fetch margins.
      Length l = (Length) as.getAttribute(CSS.Attribute.MARGIN_LEFT);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          leftInset = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_RIGHT);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          rightInset = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_TOP);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          topInset = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_BOTTOM);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          bottomInset = l.getValue();
        }

      // Fetch padding.
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_LEFT);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          leftPadding = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_RIGHT);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          rightPadding = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_TOP);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          topPadding = l.getValue();
        }
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_BOTTOM);
      if (l != null)
        {
          l.setFontBases(emBase, exBase);
          bottomPadding = l.getValue();
        }

      // Determine border.
      border = new CSSBorder(as, ss);

      // Determine background.
      background = ss.getBackground(as);

    }


    /**
     * Gets the inset needed on a given side to account for the margin, border
     * and padding.
     *
     * @param size - the size of the box to get the inset for. View.TOP, View.LEFT,
     * View.BOTTOM or View.RIGHT.
     * @param v - the view making the request. This is used to get the AttributeSet,
     * amd may be used to resolve percentage arguments.
     * @return the inset
     * @throws IllegalArgumentException - for an invalid direction.
     */
    public float getInset(int size, View v)
    {
      float inset;
      switch (size)
        {
        case View.TOP:
          inset = topInset;
          if (border != null)
            inset += border.getBorderInsets(null).top;
          inset += topPadding;
          break;
        case View.BOTTOM:
          inset = bottomInset;
          if (border != null)
            inset += border.getBorderInsets(null).bottom;
          inset += bottomPadding;
          break;
        case View.LEFT:
          inset = leftInset;
          if (border != null)
            inset += border.getBorderInsets(null).left;
          inset += leftPadding;
          break;
        case View.RIGHT:
          inset = rightInset;
          if (border != null)
            inset += border.getBorderInsets(null).right;
          inset += rightPadding;
          break;
        default:
          inset = 0.0F;
      }
      return inset;
    }

    /**
     * Paints the CSS box according to the attributes given. This should
     * paint the border, padding and background.
     *
     * @param g - the graphics configuration
     * @param x - the x coordinate
     * @param y - the y coordinate
     * @param w - the width of the allocated area
     * @param h - the height of the allocated area
     * @param v - the view making the request
     */
    public void paint(Graphics g, float x, float y, float w, float h, View v)
    {
      int inX = (int) (x + leftInset);
      int inY = (int) (y + topInset);
      int inW = (int) (w - leftInset - rightInset);
      int inH = (int) (h - topInset - bottomInset);
      if (background != null)
        {
          g.setColor(background);
          g.fillRect(inX, inY, inW, inH);
        }
      if (border != null)
        {
          border.paintBorder(null, g, inX, inY, inW, inH);
        }
    }
  }

  /**
   * This class carries out some of the CSS list formatting duties. Implementations
   * of this class enable views to present the CSS formatting while not knowing anything
   * about how the CSS values are being cached.
   *
   * @author Lillian Angel (langel@redhat.com)
   */
  public static class ListPainter implements Serializable
  {

    /**
     * Attribute set for painter
     */
    private AttributeSet attributes;

    /**
     * The associated style sheet.
     */
    private StyleSheet styleSheet;

    /**
     * The bullet type.
     */
    private String type;

    /**
     * Package-private constructor.
     *
     * @param as - AttributeSet for painter
     */
    ListPainter(AttributeSet as, StyleSheet ss)
    {
      attributes = as;
      styleSheet = ss;
      type = (String) as.getAttribute(CSS.Attribute.LIST_STYLE_TYPE);
    }

    /**
     * Cached rectangle re-used in the paint method below.
     */
    private final Rectangle tmpRect = new Rectangle();

    /**
     * Paints the CSS list decoration according to the attributes given.
     *
     * @param g - the graphics configuration
     * @param x - the x coordinate
     * @param y - the y coordinate
     * @param w - the width of the allocated area
     * @param h - the height of the allocated area
     * @param v - the view making the request
     * @param item - the list item to be painted >=0.
     */
    public void paint(Graphics g, float x, float y, float w, float h, View v,
                      int item)
    {
      // FIXME: This is a very simplistic list rendering. We still need
      // to implement different bullet types (see type field) and custom
      // bullets via images.
      View itemView = v.getView(item);
      AttributeSet viewAtts = itemView.getAttributes();
      Object tag = viewAtts.getAttribute(StyleConstants.NameAttribute);
      // Only paint something here when the child view is an LI tag
      // and the calling view is some of the list tags then).
      if (tag != null && tag == HTML.Tag.LI)
        {
          g.setColor(Color.BLACK);
          int centerX = (int) (x - 12);
          int centerY = -1;
          // For paragraphs (almost all cases) center bullet vertically
          // in the middle of the first line.
          tmpRect.setBounds((int) x, (int) y, (int) w, (int) h);
          if (itemView.getViewCount() > 0)
            {
              View v1 = itemView.getView(0);
              if (v1 instanceof ParagraphView && v1.getViewCount() > 0)
                {
                  Shape a1 = itemView.getChildAllocation(0, tmpRect);
                  Rectangle r1 = a1 instanceof Rectangle ? (Rectangle) a1
                                                         : a1.getBounds();
                  ParagraphView par = (ParagraphView) v1;
                  Shape a = par.getChildAllocation(0, r1);
                  if (a != null)
                    {
                      Rectangle r = a instanceof Rectangle ? (Rectangle) a
                                                           : a.getBounds();
                      centerY = (int) (r.height / 2 + r.y);
                    }
                }
            }
          if (centerY == -1)
            {
              centerY =(int) (h / 2 + y);
            }
          g.fillOval(centerX - 3, centerY - 3, 6, 6);
        }
    }
  }

  /**
   * Converts an AttributeSet to a Map. This is used for CSS resolving.
   *
   * @param atts the attributes to convert
   *
   * @return the converted map
   */
  private Map<String,String> attributeSetToMap(AttributeSet atts)
  {
    HashMap<String,String> map = new HashMap<String,String>();
    Enumeration<?> keys = atts.getAttributeNames();
    while (keys.hasMoreElements())
      {
        Object key = keys.nextElement();
        Object value = atts.getAttribute(key);
        map.put(key.toString(), value.toString());
      }
    return map;
  }
}
