/*
 * Copyright 2003-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing.plaf.synth;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.PatternSyntaxException;

import javax.swing.ImageIcon;
import javax.swing.JSplitPane;
import javax.swing.SwingConstants;
import javax.swing.UIDefaults;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.DimensionUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.UIResource;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.AttributeList;
import org.xml.sax.HandlerBase;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.sun.beans.ObjectHandler;

class SynthParser extends HandlerBase {
    //
    // Known element names
    //
    private static final String ELEMENT_SYNTH = "synth";
    private static final String ELEMENT_STYLE = "style";
    private static final String ELEMENT_STATE = "state";
    private static final String ELEMENT_FONT = "font";
    private static final String ELEMENT_COLOR = "color";
    private static final String ELEMENT_IMAGE_PAINTER = "imagePainter";
    private static final String ELEMENT_PAINTER = "painter";
    private static final String ELEMENT_PROPERTY = "property";
    private static final String ELEMENT_SYNTH_GRAPHICS = "graphicsUtils";
    private static final String ELEMENT_IMAGE_ICON = "imageIcon";
    private static final String ELEMENT_BIND = "bind";
    private static final String ELEMENT_BIND_KEY = "bindKey";
    private static final String ELEMENT_INSETS = "insets";
    private static final String ELEMENT_OPAQUE = "opaque";
    private static final String ELEMENT_DEFAULTS_PROPERTY =
                                        "defaultsProperty";
    private static final String ELEMENT_INPUT_MAP = "inputMap";

    //
    // Known attribute names
    //
    private static final String ATTRIBUTE_ACTION = "action";
    private static final String ATTRIBUTE_ID = "id";
    private static final String ATTRIBUTE_IDREF = "idref";
    private static final String ATTRIBUTE_CLONE = "clone";
    private static final String ATTRIBUTE_VALUE = "value";
    private static final String ATTRIBUTE_NAME = "name";
    private static final String ATTRIBUTE_STYLE = "style";
    private static final String ATTRIBUTE_SIZE = "size";
    private static final String ATTRIBUTE_TYPE = "type";
    private static final String ATTRIBUTE_TOP = "top";
    private static final String ATTRIBUTE_LEFT = "left";
    private static final String ATTRIBUTE_BOTTOM = "bottom";
    private static final String ATTRIBUTE_RIGHT = "right";
    private static final String ATTRIBUTE_KEY = "key";
    private static final String ATTRIBUTE_SOURCE_INSETS = "sourceInsets";
    private static final String ATTRIBUTE_DEST_INSETS = "destinationInsets";
    private static final String ATTRIBUTE_PATH = "path";
    private static final String ATTRIBUTE_STRETCH = "stretch";
    private static final String ATTRIBUTE_PAINT_CENTER = "paintCenter";
    private static final String ATTRIBUTE_METHOD = "method";
    private static final String ATTRIBUTE_DIRECTION = "direction";
    private static final String ATTRIBUTE_CENTER = "center";

    /**
     * Lazily created, used for anything we don't understand.
     */
    private ObjectHandler _handler;

    /**
     * Indicates the depth of how many elements we've encountered but don't
     * understand. This is used when forwarding to beans persistance to know
     * when we hsould stop forwarding.
     */
    private int _depth;

    /**
     * Factory that new styles are added to.
     */
    private DefaultSynthStyleFactory _factory;

    /**
     * Array of state infos for the current style. These are pushed to the
     * style when </style> is received.
     */
    private java.util.List _stateInfos;

    /**
     * Current style.
     */
    private ParsedSynthStyle _style;

    /**
     * Current state info.
     */
    private ParsedSynthStyle.StateInfo _stateInfo;

    /**
     * Bindings for the current InputMap
     */
    private java.util.List _inputMapBindings;

    /**
     * ID for the input map. This is cached as
     * the InputMap is created AFTER the inputMapProperty has ended.
     */
    private String _inputMapID;

    /**
     * Object references outside the scope of persistance.
     */
    private Map<String,Object> _mapping;

    /**
     * Based URL used to resolve paths.
     */
    private URL _urlResourceBase;

    /**
     * Based class used to resolve paths.
     */
    private Class<?> _classResourceBase;

    /**
     * List of ColorTypes. This is populated in startColorType.
     */
    private java.util.List _colorTypes;

    /**
     * defaultsPropertys are placed here.
     */
    private Map _defaultsMap;

    /**
     * List of SynthStyle.Painters that will be applied to the current style.
     */
    private java.util.List _stylePainters;

    /**
     * List of SynthStyle.Painters that will be applied to the current state.
     */
    private java.util.List _statePainters;

    SynthParser() {
        _mapping = new HashMap<String,Object>();
        _stateInfos = new ArrayList();
        _colorTypes = new ArrayList();
        _inputMapBindings = new ArrayList();
        _stylePainters = new ArrayList();
        _statePainters = new ArrayList();
    }

    /**
     * Parses a set of styles from <code>inputStream</code>, adding the
     * resulting styles to the passed in DefaultSynthStyleFactory.
     * Resources are resolved either from a URL or from a Class. When calling
     * this method, one of the URL or the Class must be null but not both at
     * the same time.
     *
     * @param inputStream XML document containing the styles to read
     * @param factory DefaultSynthStyleFactory that new styles are added to
     * @param urlResourceBase the URL used to resolve any resources, such as Images
     * @param classResourceBase the Class used to resolve any resources, such as Images
     * @param defaultsMap Map that UIDefaults properties are placed in
     */
    public void parse(InputStream inputStream,
                      DefaultSynthStyleFactory factory,
                      URL urlResourceBase, Class<?> classResourceBase,
                      Map defaultsMap)
                      throws ParseException, IllegalArgumentException {
        if (inputStream == null || factory == null ||
            (urlResourceBase == null && classResourceBase == null)) {
            throw new IllegalArgumentException(
                "You must supply an InputStream, StyleFactory and Class or URL");
        }

        assert(!(urlResourceBase != null && classResourceBase != null));

        _factory = factory;
        _classResourceBase = classResourceBase;
        _urlResourceBase = urlResourceBase;
        _defaultsMap = defaultsMap;
        try {
            try {
                SAXParser saxParser = SAXParserFactory.newInstance().
                                                   newSAXParser();
                saxParser.parse(new BufferedInputStream(inputStream), this);
            } catch (ParserConfigurationException e) {
                throw new ParseException("Error parsing: " + e, 0);
            }
            catch (SAXException se) {
                throw new ParseException("Error parsing: " + se + " " +
                                         se.getException(), 0);
            }
            catch (IOException ioe) {
                throw new ParseException("Error parsing: " + ioe, 0);
            }
        } finally {
            reset();
        }
    }

    /**
     * Returns the path to a resource.
     */
    private URL getResource(String path) {
        if (_classResourceBase != null) {
            return _classResourceBase.getResource(path);
        } else {
            try {
                return new URL(_urlResourceBase, path);
            } catch (MalformedURLException mue) {
                return null;
            }
        }
    }

    /**
     * Clears our internal state.
     */
    private void reset() {
        _handler = null;
        _depth = 0;
        _mapping.clear();
        _stateInfos.clear();
        _colorTypes.clear();
        _statePainters.clear();
        _stylePainters.clear();
    }

    /**
     * Returns true if we are forwarding to persistance.
     */
    private boolean isForwarding() {
        return (_depth > 0);
    }

    /**
     * Handles beans persistance.
     */
    private ObjectHandler getHandler() {
        if (_handler == null) {
            if (_urlResourceBase != null) {
                // getHandler() is never called before parse() so it is safe
                // to create a URLClassLoader with _resourceBase.
                //
                // getResource(".") is called to ensure we have the directory
                // containing the resources in the case the resource base is a
                // .class file.
                URL[] urls = new URL[] { getResource(".") };
                ClassLoader parent = Thread.currentThread().getContextClassLoader();
                ClassLoader urlLoader = new URLClassLoader(urls, parent);
                _handler = new ObjectHandler(null, urlLoader);
            } else {
                _handler = new ObjectHandler(null,
                    _classResourceBase.getClassLoader());
            }

            for (String key : _mapping.keySet()) {
                _handler.register(key, _mapping.get(key));
            }
        }
        return _handler;
    }

    /**
     * If <code>value</code> is an instance of <code>type</code> it is
     * returned, otherwise a SAXException is thrown.
     */
    private Object checkCast(Object value, Class type) throws SAXException {
        if (!type.isInstance(value)) {
            throw new SAXException("Expected type " + type + " got " +
                                   value.getClass());
        }
        return value;
    }

    /**
     * Returns an object created with id=key. If the object is not of
     * type type, this will throw an exception.
     */
    private Object lookup(String key, Class type) throws SAXException {
        Object value = null;
        if (_handler != null) {
            if ((value = _handler.lookup(key)) != null) {
                return checkCast(value, type);
            }
        }
        value = _mapping.get(key);
        if (value == null) {
            throw new SAXException("ID " + key + " has not been defined");
        }
        return checkCast(value, type);
    }

    /**
     * Registers an object by name. This will throw an exception if an
     * object has already been registered under the given name.
     */
    private void register(String key, Object value) throws SAXException {
        if (key != null) {
            if (_mapping.get(key) != null ||
                     (_handler != null && _handler.lookup(key) != null)) {
                throw new SAXException("ID " + key + " is already defined");
            }
            if (_handler != null) {
                _handler.register(key, value);
            }
            else {
                _mapping.put(key, value);
            }
        }
    }

    /**
     * Convenience method to return the next int, or throw if there are no
     * more valid ints.
     */
    private int nextInt(StringTokenizer tok, String errorMsg) throws
                   SAXException {
        if (!tok.hasMoreTokens()) {
            throw new SAXException(errorMsg);
        }
        try {
            return Integer.parseInt(tok.nextToken());
        } catch (NumberFormatException nfe) {
            throw new SAXException(errorMsg);
        }
    }

    /**
     * Convenience method to return an Insets object.
     */
    private Insets parseInsets(String insets, String errorMsg) throws
                        SAXException {
        StringTokenizer tokenizer = new StringTokenizer(insets);
        return new Insets(nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg));
    }



    //
    // The following methods are invoked from startElement/stopElement
    //

    private void startStyle(AttributeList attributes) throws SAXException {
        String id = null;

        _style = null;
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_CLONE)) {
                _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup(
                         attributes.getValue(i), ParsedSynthStyle.class)).
                         clone();
            }
            else if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
        }
        if (_style == null) {
            _style = new ParsedSynthStyle();
        }
        register(id, _style);
    }

    private void endStyle() throws SAXException {
        int size = _stylePainters.size();
        if (size > 0) {
            _style.setPainters((ParsedSynthStyle.PainterInfo[])
                  _stylePainters.toArray(new ParsedSynthStyle.
                  PainterInfo[size]));
            _stylePainters.clear();
        }
        size = _stateInfos.size();
        if (size > 0) {
            _style.setStateInfo((ParsedSynthStyle.StateInfo[])_stateInfos.
                 toArray(new ParsedSynthStyle.StateInfo[size]));
            _stateInfos.clear();
        }
        _style = null;
    }

    private void startState(AttributeList attributes) throws SAXException {
        ParsedSynthStyle.StateInfo stateInfo = null;
        int state = 0;
        String id = null;

        _stateInfo = null;
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                _stateInfo = (ParsedSynthStyle.StateInfo)lookup(
                   attributes.getValue(i), ParsedSynthStyle.StateInfo.class);
            }
            else if (key.equals(ATTRIBUTE_CLONE)) {
                _stateInfo = (ParsedSynthStyle.StateInfo)((ParsedSynthStyle.
                             StateInfo)lookup(attributes.getValue(i),
                             ParsedSynthStyle.StateInfo.class)).clone();
            }
            else if (key.equals(ATTRIBUTE_VALUE)) {
                StringTokenizer tokenizer = new StringTokenizer(
                                   attributes.getValue(i));
                while (tokenizer.hasMoreTokens()) {
                    String stateString = tokenizer.nextToken().toUpperCase().
                                                   intern();
                    if (stateString == "ENABLED") {
                        state |= SynthConstants.ENABLED;
                    }
                    else if (stateString == "MOUSE_OVER") {
                        state |= SynthConstants.MOUSE_OVER;
                    }
                    else if (stateString == "PRESSED") {
                        state |= SynthConstants.PRESSED;
                    }
                    else if (stateString == "DISABLED") {
                        state |= SynthConstants.DISABLED;
                    }
                    else if (stateString == "FOCUSED") {
                        state |= SynthConstants.FOCUSED;
                    }
                    else if (stateString == "SELECTED") {
                        state |= SynthConstants.SELECTED;
                    }
                    else if (stateString == "DEFAULT") {
                        state |= SynthConstants.DEFAULT;
                    }
                    else if (stateString != "AND") {
                        throw new SAXException("Unknown state: " + state);
                    }
                }
            }
        }
        if (_stateInfo == null) {
            _stateInfo = new ParsedSynthStyle.StateInfo();
        }
        _stateInfo.setComponentState(state);
        register(id, _stateInfo);
        _stateInfos.add(_stateInfo);
    }

    private void endState() throws SAXException {
        int size = _statePainters.size();
        if (size > 0) {
            _stateInfo.setPainters((ParsedSynthStyle.PainterInfo[])
                  _statePainters.toArray(new ParsedSynthStyle.
                  PainterInfo[size]));
            _statePainters.clear();
        }
        _stateInfo = null;
    }

    private void startFont(AttributeList attributes) throws SAXException {
        Font font = null;
        int style = Font.PLAIN;
        int size = 0;
        String id = null;
        String name = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                font = (Font)lookup(attributes.getValue(i), Font.class);
            }
            else if (key.equals(ATTRIBUTE_NAME)) {
                name = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_SIZE)) {
                try {
                    size = Integer.parseInt(attributes.getValue(i));
                } catch (NumberFormatException nfe) {
                    throw new SAXException("Invalid font size: " +
                                           attributes.getValue(i));
                }
            }
            else if (key.equals(ATTRIBUTE_STYLE)) {
                StringTokenizer tok = new StringTokenizer(
                                                attributes.getValue(i));
                while (tok.hasMoreTokens()) {
                    String token = tok.nextToken().intern();
                    if (token == "BOLD") {
                        style = ((style | Font.PLAIN) ^ Font.PLAIN) |
                                Font.BOLD;
                    }
                    else if (token == "ITALIC") {
                        style |= Font.ITALIC;
                    }
                }
            }
        }
        if (font == null) {
            if (name == null) {
                throw new SAXException("You must define a name for the font");
            }
            if (size == 0) {
                throw new SAXException("You must define a size for the font");
            }
            font = new FontUIResource(name, style, size);
        }
        else if (name != null || size != 0 || style != Font.PLAIN) {
            throw new SAXException("Name, size and style are not for use " +
                                   "with idref");
        }
        register(id, font);
        if (_stateInfo != null) {
            _stateInfo.setFont(font);
        }
        else if (_style != null) {
            _style.setFont(font);
        }
    }

    private void startColor(AttributeList attributes) throws SAXException {
        Color color = null;
        String id = null;

        _colorTypes.clear();
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                color = (Color)lookup(attributes.getValue(i), Color.class);
            }
            else if (key.equals(ATTRIBUTE_NAME)) {
            }
            else if (key.equals(ATTRIBUTE_VALUE)) {
                String value = attributes.getValue(i);

                if (value.startsWith("#")) {
                    try {
                        int argb;
                        boolean hasAlpha;

                        int length = value.length();
                        if (length < 8) {
                            // Just RGB, or some portion of it.
                            argb = Integer.decode(value);
                            hasAlpha = false;
                        } else if (length == 8) {
                            // Single character alpha: #ARRGGBB.
                            argb = Integer.decode(value);
                            hasAlpha = true;
                        } else if (length == 9) {
                            // Color has alpha and is of the form
                            // #AARRGGBB.
                            // The following split decoding is mandatory due to
                            // Integer.decode() behavior which won't decode
                            // hexadecimal values higher than #7FFFFFFF.
                            // Thus, when an alpha channel is detected, it is
                            // decoded separately from the RGB channels.
                            int rgb = Integer.decode('#' +
                                                     value.substring(3, 9));
                            int a = Integer.decode(value.substring(0, 3));
                            argb = (a << 24) | rgb;
                            hasAlpha = true;
                        } else {
                            throw new SAXException("Invalid Color value: "
                                + value);
                        }

                        color = new ColorUIResource(new Color(argb, hasAlpha));
                    } catch (NumberFormatException nfe) {
                        throw new SAXException("Invalid Color value: " +value);
                    }
                }
                else {
                    try {
                        color = new ColorUIResource((Color)Color.class.
                              getField(value.toUpperCase()).get(Color.class));
                    } catch (NoSuchFieldException nsfe) {
                        throw new SAXException("Invalid color name: " + value);
                    } catch (IllegalAccessException iae) {
                        throw new SAXException("Invalid color name: " + value);
                    }
                }
            }
            else if (key.equals(ATTRIBUTE_TYPE)) {
                StringTokenizer tokenizer = new StringTokenizer(
                                   attributes.getValue(i));
                while (tokenizer.hasMoreTokens()) {
                    String typeName = tokenizer.nextToken();
                    int classIndex = typeName.lastIndexOf('.');
                    Class typeClass;

                    if (classIndex == -1) {
                        typeClass = ColorType.class;
                        classIndex = 0;
                    }
                    else {
                        try {
                            typeClass = Class.forName(typeName.substring(
                                                      0, classIndex));
                        } catch (ClassNotFoundException cnfe) {
                            throw new SAXException("Unknown class: " +
                                      typeName.substring(0, classIndex));
                        }
                        classIndex++;
                    }
                    try {
                        _colorTypes.add((ColorType)checkCast(typeClass.
                              getField(typeName.substring(classIndex,
                              typeName.length() - classIndex)).
                              get(typeClass), ColorType.class));
                    } catch (NoSuchFieldException nsfe) {
                        throw new SAXException("Unable to find color type: " +
                                               typeName);
                    } catch (IllegalAccessException iae) {
                        throw new SAXException("Unable to find color type: " +
                                               typeName);
                    }
                }
            }
        }
        if (color == null) {
            throw new SAXException("color: you must specificy a value");
        }
        register(id, color);
        if (_stateInfo != null && _colorTypes.size() > 0) {
            Color[] colors = _stateInfo.getColors();
            int max = 0;
            for (int counter = _colorTypes.size() - 1; counter >= 0;
                     counter--) {
                max = Math.max(max, ((ColorType)_colorTypes.get(counter)).
                               getID());
            }
            if (colors == null || colors.length <= max) {
                Color[] newColors = new Color[max + 1];
                if (colors != null) {
                    System.arraycopy(colors, 0, newColors, 0, colors.length);
                }
                colors = newColors;
            }
            for (int counter = _colorTypes.size() - 1; counter >= 0;
                     counter--) {
                colors[((ColorType)_colorTypes.get(counter)).getID()] = color;
            }
            _stateInfo.setColors(colors);
        }
    }

    private void startProperty(AttributeList attributes,
                               Object property) throws SAXException {
        Object value = null;
        Object key = null;
        // Type of the value: 0=idref, 1=boolean, 2=dimension, 3=insets,
        // 4=integer,5=string
        int iType = 0;
        String aValue = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String aName = attributes.getName(i);
            if (aName.equals(ATTRIBUTE_TYPE)) {
                String type = attributes.getValue(i).toUpperCase();
                if (type.equals("IDREF")) {
                    iType = 0;
                }
                else if (type.equals("BOOLEAN")) {
                    iType = 1;
                }
                else if (type.equals("DIMENSION")) {
                    iType = 2;
                }
                else if (type.equals("INSETS")) {
                    iType = 3;
                }
                else if (type.equals("INTEGER")) {
                    iType = 4;
                }
                else if (type.equals("STRING")) {
                    iType = 5;
                }
                else {
                    throw new SAXException(property + " unknown type, use" +
                        "idref, boolean, dimension, insets or integer");
                }
            }
            else if (aName.equals(ATTRIBUTE_VALUE)) {
                aValue = attributes.getValue(i);
            }
            else if (aName.equals(ATTRIBUTE_KEY)) {
                key = attributes.getValue(i);
            }
        }
        if (aValue != null) {
            switch (iType) {
            case 0: // idref
                value = lookup(aValue, Object.class);
                break;
            case 1: // boolean
                if (aValue.toUpperCase().equals("TRUE")) {
                    value = Boolean.TRUE;
                }
                else {
                    value = Boolean.FALSE;
                }
                break;
            case 2: // dimension
                StringTokenizer tok = new StringTokenizer(aValue);
                value = new DimensionUIResource(
                    nextInt(tok, "Invalid dimension"),
                    nextInt(tok, "Invalid dimension"));
                break;
            case 3: // insets
                value = parseInsets(aValue, property + " invalid insets");
                break;
            case 4: // integer
                try {
                    value = new Integer(Integer.parseInt(aValue));
                } catch (NumberFormatException nfe) {
                    throw new SAXException(property + " invalid value");
                }
                break;
            case 5: //string
                value = aValue;
                break;
            }
        }
        if (value == null || key == null) {
            throw new SAXException(property + ": you must supply a " +
                                   "key and value");
        }
        if (property == ELEMENT_DEFAULTS_PROPERTY) {
            _defaultsMap.put(key, value);
        }
        else if (_stateInfo != null) {
            if (_stateInfo.getData() == null) {
                _stateInfo.setData(new HashMap());
            }
            _stateInfo.getData().put(key, value);
        }
        else if (_style != null) {
            if (_style.getData() == null) {
                _style.setData(new HashMap());
            }
            _style.getData().put(key, value);
        }
    }

    private void startGraphics(AttributeList attributes) throws SAXException {
        SynthGraphicsUtils graphics = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_IDREF)) {
                graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i),
                                                 SynthGraphicsUtils.class);
            }
        }
        if (graphics == null) {
            throw new SAXException("graphicsUtils: you must supply an idref");
        }
        if (_style != null) {
            _style.setGraphicsUtils(graphics);
        }
    }

    private void startInsets(AttributeList attributes) throws SAXException {
        int top = 0;
        int bottom = 0;
        int left = 0;
        int right = 0;
        Insets insets = null;
        String id = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            try {
                if (key.equals(ATTRIBUTE_IDREF)) {
                    insets = (Insets)lookup(attributes.getValue(i),
                                                   Insets.class);
                }
                else if (key.equals(ATTRIBUTE_ID)) {
                    id = attributes.getValue(i);
                }
                else if (key.equals(ATTRIBUTE_TOP)) {
                    top = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_LEFT)) {
                    left = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_BOTTOM)) {
                    bottom = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_RIGHT)) {
                    right = Integer.parseInt(attributes.getValue(i));
                }
            } catch (NumberFormatException nfe) {
                throw new SAXException("insets: bad integer value for " +
                                       attributes.getValue(i));
            }
        }
        if (insets == null) {
            insets = new InsetsUIResource(top, left, bottom, right);
        }
        register(id, insets);
        if (_style != null) {
            _style.setInsets(insets);
        }
    }

    private void startBind(AttributeList attributes) throws SAXException {
        ParsedSynthStyle style = null;
        String path = null;
        int type = -1;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            if (key.equals(ATTRIBUTE_STYLE)) {
                style = (ParsedSynthStyle)lookup(attributes.getValue(i),
                                                  ParsedSynthStyle.class);
            }
            else if (key.equals(ATTRIBUTE_TYPE)) {
                String typeS = attributes.getValue(i).toUpperCase();

                if (typeS.equals("NAME")) {
                    type = DefaultSynthStyleFactory.NAME;
                }
                else if (typeS.equals("REGION")) {
                    type = DefaultSynthStyleFactory.REGION;
                }
                else {
                    throw new SAXException("bind: unknown type " + typeS);
                }
            }
            else if (key.equals(ATTRIBUTE_KEY)) {
                path = attributes.getValue(i);
            }
        }
        if (style == null || path == null || type == -1) {
            throw new SAXException("bind: you must specify a style, type " +
                                   "and key");
        }
        try {
            _factory.addStyle(style, path, type);
        } catch (PatternSyntaxException pse) {
            throw new SAXException("bind: " + path + " is not a valid " +
                                   "regular expression");
        }
    }

    private void startPainter(AttributeList attributes, String type) throws SAXException {
        Insets sourceInsets = null;
        Insets destInsets = null;
        String path = null;
        boolean paintCenter = true;
        boolean stretch = true;
        SynthPainter painter = null;
        String method = null;
        String id = null;
        int direction = -1;
        boolean center = false;

        boolean stretchSpecified = false;
        boolean paintCenterSpecified = false;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            String value = attributes.getValue(i);

            if (key.equals(ATTRIBUTE_ID)) {
                id = value;
            }
            else if (key.equals(ATTRIBUTE_METHOD)) {
                method = value.toLowerCase(Locale.ENGLISH);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                painter = (SynthPainter)lookup(value, SynthPainter.class);
            }
            else if (key.equals(ATTRIBUTE_PATH)) {
                path = value;
            }
            else if (key.equals(ATTRIBUTE_SOURCE_INSETS)) {
                sourceInsets = parseInsets(value, type +
                   ": sourceInsets must be top left bottom right");
            }
            else if (key.equals(ATTRIBUTE_DEST_INSETS)) {
                destInsets = parseInsets(value, type +
                  ": destinationInsets must be top left bottom right");
            }
            else if (key.equals(ATTRIBUTE_PAINT_CENTER)) {
                paintCenter = value.toLowerCase().equals("true");
                paintCenterSpecified = true;
            }
            else if (key.equals(ATTRIBUTE_STRETCH)) {
                stretch = value.toLowerCase().equals("true");
                stretchSpecified = true;
            }
            else if (key.equals(ATTRIBUTE_DIRECTION)) {
                value = value.toUpperCase().intern();
                if (value == "EAST") {
                    direction = SwingConstants.EAST;
                }
                else if (value == "NORTH") {
                    direction = SwingConstants.NORTH;
                }
                else if (value == "SOUTH") {
                    direction = SwingConstants.SOUTH;
                }
                else if (value == "WEST") {
                    direction = SwingConstants.WEST;
                }
                else if (value == "TOP") {
                    direction = SwingConstants.TOP;
                }
                else if (value == "LEFT") {
                    direction = SwingConstants.LEFT;
                }
                else if (value == "BOTTOM") {
                    direction = SwingConstants.BOTTOM;
                }
                else if (value == "RIGHT") {
                    direction = SwingConstants.RIGHT;
                }
                else if (value == "HORIZONTAL") {
                    direction = SwingConstants.HORIZONTAL;
                }
                else if (value == "VERTICAL") {
                    direction = SwingConstants.VERTICAL;
                }
                else if (value == "HORIZONTAL_SPLIT") {
                    direction = JSplitPane.HORIZONTAL_SPLIT;
                }
                else if (value == "VERTICAL_SPLIT") {
                    direction = JSplitPane.VERTICAL_SPLIT;
                }
                else {
                    throw new SAXException(type + ": unknown direction");
                }
            }
            else if (key.equals(ATTRIBUTE_CENTER)) {
                center = value.toLowerCase().equals("true");
            }
        }
        if (painter == null) {
            if (type == ELEMENT_PAINTER) {
                throw new SAXException(type +
                             ": you must specify an idref");
            }
            if (sourceInsets == null && !center) {
                throw new SAXException(
                             "property: you must specify sourceInsets");
            }
            if (path == null) {
                throw new SAXException("property: you must specify a path");
            }
            if (center && (sourceInsets != null || destInsets != null ||
                           paintCenterSpecified || stretchSpecified)) {
                throw new SAXException("The attributes: sourceInsets, " +
                                       "destinationInsets, paintCenter and stretch " +
                                       " are not legal when center is true");
            }
            painter = new ImagePainter(!stretch, paintCenter,
                     sourceInsets, destInsets, getResource(path), center);
        }
        register(id, painter);
        if (_stateInfo != null) {
            addPainterOrMerge(_statePainters, method, painter, direction);
        }
        else if (_style != null) {
            addPainterOrMerge(_stylePainters, method, painter, direction);
        }
    }

    private void addPainterOrMerge(java.util.List painters, String method,
                                   SynthPainter painter, int direction) {
        ParsedSynthStyle.PainterInfo painterInfo;
        painterInfo = new ParsedSynthStyle.PainterInfo(method,
                                                       painter,
                                                       direction);

        for (Object infoObject: painters) {
            ParsedSynthStyle.PainterInfo info;
            info = (ParsedSynthStyle.PainterInfo) infoObject;

            if (painterInfo.equalsPainter(info)) {
                info.addPainter(painter);
                return;
            }
        }

        painters.add(painterInfo);
    }

    private void startImageIcon(AttributeList attributes) throws SAXException {
        String path = null;
        String id = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_PATH)) {
                path = attributes.getValue(i);
            }
        }
        if (path == null) {
            throw new SAXException("imageIcon: you must specify a path");
        }
        register(id, new LazyImageIcon(getResource(path)));
       }

    private void startOpaque(AttributeList attributes) throws
                      SAXException {
        if (_style != null) {
            _style.setOpaque(true);
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String key = attributes.getName(i);

                if (key.equals(ATTRIBUTE_VALUE)) {
                    _style.setOpaque("true".equals(attributes.getValue(i).
                                                   toLowerCase()));
                }
            }
        }
    }

    private void startInputMap(AttributeList attributes) throws SAXException {
        _inputMapBindings.clear();
        _inputMapID = null;
        if (_style != null) {
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String key = attributes.getName(i);

                if (key.equals(ATTRIBUTE_ID)) {
                    _inputMapID = attributes.getValue(i);
                }
            }
        }
    }

    private void endInputMap() throws SAXException {
        if (_inputMapID != null) {
            register(_inputMapID, new UIDefaults.LazyInputMap(
                     _inputMapBindings.toArray(new Object[_inputMapBindings.
                     size()])));
        }
        _inputMapBindings.clear();
        _inputMapID = null;
    }

    private void startBindKey(AttributeList attributes) throws SAXException {
        if (_inputMapID == null) {
            // Not in an inputmap, bail.
            return;
        }
        if (_style != null) {
            String key = null;
            String value = null;
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String aKey = attributes.getName(i);

                if (aKey.equals(ATTRIBUTE_KEY)) {
                    key = attributes.getValue(i);
                }
                else if (aKey.equals(ATTRIBUTE_ACTION)) {
                    value = attributes.getValue(i);
                }
            }
            if (key == null || value == null) {
                throw new SAXException(
                    "bindKey: you must supply a key and action");
            }
            _inputMapBindings.add(key);
            _inputMapBindings.add(value);
        }
    }

    //
    // SAX methods, these forward to the ObjectHandler if we don't know
    // the element name.
    //

    public InputSource resolveEntity(String publicId, String systemId)
                              throws SAXException {
        if (isForwarding()) {
            return getHandler().resolveEntity(publicId, systemId);
        }
        return null;
    }

    public void notationDecl(String name, String publicId, String systemId) {
        if (isForwarding()) {
            getHandler().notationDecl(name, publicId, systemId);
        }
    }

    public void unparsedEntityDecl(String name, String publicId,
                                   String systemId, String notationName) {
        if (isForwarding()) {
            getHandler().unparsedEntityDecl(name, publicId, systemId,
                                            notationName);
        }
    }

    public void setDocumentLocator(Locator locator) {
        if (isForwarding()) {
            getHandler().setDocumentLocator(locator);
        }
    }

    public void startDocument() throws SAXException {
        if (isForwarding()) {
            getHandler().startDocument();
        }
    }

    public void endDocument() throws SAXException {
        if (isForwarding()) {
            getHandler().endDocument();
        }
    }

    public void startElement(String name, AttributeList attributes)
                     throws SAXException {
        name = name.intern();
        if (name == ELEMENT_STYLE) {
            startStyle(attributes);
        }
        else if (name == ELEMENT_STATE) {
            startState(attributes);
        }
        else if (name == ELEMENT_FONT) {
            startFont(attributes);
        }
        else if (name == ELEMENT_COLOR) {
            startColor(attributes);
        }
        else if (name == ELEMENT_PAINTER) {
            startPainter(attributes, name);
        }
        else if (name == ELEMENT_IMAGE_PAINTER) {
            startPainter(attributes, name);
        }
        else if (name == ELEMENT_PROPERTY) {
            startProperty(attributes, ELEMENT_PROPERTY);
        }
        else if (name == ELEMENT_DEFAULTS_PROPERTY) {
            startProperty(attributes, ELEMENT_DEFAULTS_PROPERTY);
        }
        else if (name == ELEMENT_SYNTH_GRAPHICS) {
            startGraphics(attributes);
        }
        else if (name == ELEMENT_INSETS) {
            startInsets(attributes);
        }
        else if (name == ELEMENT_BIND) {
            startBind(attributes);
        }
        else if (name == ELEMENT_BIND_KEY) {
            startBindKey(attributes);
        }
        else if (name == ELEMENT_IMAGE_ICON) {
            startImageIcon(attributes);
        }
        else if (name == ELEMENT_OPAQUE) {
            startOpaque(attributes);
        }
        else if (name == ELEMENT_INPUT_MAP) {
            startInputMap(attributes);
        }
        else if (name != ELEMENT_SYNTH) {
            if (_depth++ == 0) {
                getHandler().reset();
            }
            getHandler().startElement(name, attributes);
        }
    }

    public void endElement(String name) throws SAXException {
        if (isForwarding()) {
            getHandler().endElement(name);
            _depth--;
            if (!isForwarding()) {
                getHandler().reset();
            }
        }
        else {
            name = name.intern();
            if (name == ELEMENT_STYLE) {
                endStyle();
            }
            else if (name == ELEMENT_STATE) {
                endState();
            }
            else if (name == ELEMENT_INPUT_MAP) {
                endInputMap();
            }
        }
    }

    public void characters(char ch[], int start, int length)
                           throws SAXException {
        if (isForwarding()) {
            getHandler().characters(ch, start, length);
        }
    }

    public void ignorableWhitespace (char ch[], int start, int length)
        throws SAXException {
        if (isForwarding()) {
            getHandler().ignorableWhitespace(ch, start, length);
        }
    }

    public void processingInstruction(String target, String data)
                                     throws SAXException {
        if (isForwarding()) {
            getHandler().processingInstruction(target, data);
        }
    }

    public void warning(SAXParseException e) throws SAXException {
        if (isForwarding()) {
            getHandler().warning(e);
        }
    }

    public void error(SAXParseException e) throws SAXException {
        if (isForwarding()) {
            getHandler().error(e);
        }
    }


    public void fatalError(SAXParseException e) throws SAXException {
        if (isForwarding()) {
            getHandler().fatalError(e);
        }
        throw e;
    }


    /**
     * ImageIcon that lazily loads the image until needed.
     */
    private static class LazyImageIcon extends ImageIcon implements UIResource {
        private URL location;

        public LazyImageIcon(URL location) {
            super();
            this.location = location;
        }

        public void paintIcon(Component c, Graphics g, int x, int y) {
            if (getImage() != null) {
                super.paintIcon(c, g, x, y);
            }
        }

        public int getIconWidth() {
            if (getImage() != null) {
                return super.getIconWidth();
            }
            return 0;
        }

        public int getIconHeight() {
            if (getImage() != null) {
                return super.getIconHeight();
            }
            return 0;
        }

        public Image getImage() {
            if (location != null) {
                setImage(Toolkit.getDefaultToolkit().getImage(location));
                location = null;
            }
            return super.getImage();
        }
    }
}
