/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.bridge;

import java.awt.Color;
import java.awt.Paint;
import java.lang.ref.WeakReference;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Arrays;
import java.util.Set;

import org.apache.batik.anim.AnimationEngine;
import org.apache.batik.anim.AnimationException;
import org.apache.batik.anim.dom.AnimationTarget;
import org.apache.batik.anim.dom.SVGOMDocument;
import org.apache.batik.anim.dom.SVGOMElement;
import org.apache.batik.anim.dom.SVGStylableElement;
import org.apache.batik.anim.timing.TimedDocumentRoot;
import org.apache.batik.anim.timing.TimedElement;
import org.apache.batik.anim.values.AnimatableAngleValue;
import org.apache.batik.anim.values.AnimatableAngleOrIdentValue;
import org.apache.batik.anim.values.AnimatableBooleanValue;
import org.apache.batik.anim.values.AnimatableIntegerValue;
import org.apache.batik.anim.values.AnimatableLengthValue;
import org.apache.batik.anim.values.AnimatableLengthListValue;
import org.apache.batik.anim.values.AnimatableLengthOrIdentValue;
import org.apache.batik.anim.values.AnimatableNumberValue;
import org.apache.batik.anim.values.AnimatableNumberListValue;
import org.apache.batik.anim.values.AnimatableNumberOrPercentageValue;
import org.apache.batik.anim.values.AnimatablePathDataValue;
import org.apache.batik.anim.values.AnimatablePointListValue;
import org.apache.batik.anim.values.AnimatablePreserveAspectRatioValue;
import org.apache.batik.anim.values.AnimatableNumberOrIdentValue;
import org.apache.batik.anim.values.AnimatableRectValue;
import org.apache.batik.anim.values.AnimatableStringValue;
import org.apache.batik.anim.values.AnimatableValue;
import org.apache.batik.anim.values.AnimatableColorValue;
import org.apache.batik.anim.values.AnimatablePaintValue;
import org.apache.batik.css.engine.CSSEngine;
import org.apache.batik.css.engine.CSSStylableElement;
import org.apache.batik.css.engine.StyleMap;
import org.apache.batik.css.engine.value.FloatValue;
import org.apache.batik.css.engine.value.StringValue;
import org.apache.batik.css.engine.value.Value;
import org.apache.batik.css.engine.value.ValueManager;
import org.apache.batik.parser.DefaultPreserveAspectRatioHandler;
import org.apache.batik.parser.FloatArrayProducer;
import org.apache.batik.parser.DefaultLengthHandler;
import org.apache.batik.parser.LengthArrayProducer;
import org.apache.batik.parser.LengthHandler;
import org.apache.batik.parser.LengthListParser;
import org.apache.batik.parser.LengthParser;
import org.apache.batik.parser.NumberListParser;
import org.apache.batik.parser.PathArrayProducer;
import org.apache.batik.parser.PathParser;
import org.apache.batik.parser.PointsParser;
import org.apache.batik.parser.ParseException;
import org.apache.batik.parser.PreserveAspectRatioHandler;
import org.apache.batik.parser.PreserveAspectRatioParser;
import org.apache.batik.util.RunnableQueue;
import org.apache.batik.util.SMILConstants;
import org.apache.batik.constants.XMLConstants;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.css.CSSPrimitiveValue;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSValue;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.svg.SVGAngle;
import org.w3c.dom.svg.SVGLength;
import org.w3c.dom.svg.SVGPreserveAspectRatio;

/**
 * An AnimationEngine for SVG documents.
 *
 * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
 * @version $Id$
 */
public class SVGAnimationEngine extends AnimationEngine {

    /**
     * The BridgeContext to use for value parsing.
     */
    protected BridgeContext ctx;

    /**
     * The CSSEngine used for CSS value parsing.
     */
    protected CSSEngine cssEngine;

    /**
     * Whether animation processing has started.  This affects whether
     * animation element bridges add their animation on to the initial
     * bridge list, or process them immediately.
     */
    protected boolean started;

    /**
     * The Runnable that ticks the document.
     */
    protected AnimationTickRunnable animationTickRunnable;

    /**
     * The initial time that will be seeked to when the animation engine starts,
     * as set by {@link #setCurrentTime}.
     */
    protected float initialStartTime;

    /**
     * The factory for unparsed string values.
     */
    protected UncomputedAnimatableStringValueFactory
        uncomputedAnimatableStringValueFactory =
            new UncomputedAnimatableStringValueFactory();

    /**
     * The factory for length-or-ident values.
     */
    protected AnimatableLengthOrIdentFactory
        animatableLengthOrIdentFactory = new AnimatableLengthOrIdentFactory();

    /**
     * The factory for number-or-ident values.
     */
    protected AnimatableNumberOrIdentFactory
        animatableNumberOrIdentFactory =
            new AnimatableNumberOrIdentFactory(false);

    /**
     * Factories for {@link AnimatableValue} parsing.
     */
    protected Factory[] factories = {
        null, // TYPE_UNKNOWN
            new AnimatableIntegerValueFactory(), // TYPE_INTEGER
            new AnimatableNumberValueFactory(), // TYPE_NUMBER
            new AnimatableLengthValueFactory(), // TYPE_LENGTH
        null, // TYPE_NUMBER_OPTIONAL_NUMBER
        new AnimatableAngleValueFactory(), // TYPE_ANGLE
        new AnimatableColorValueFactory(), // TYPE_COLOR
        new AnimatablePaintValueFactory(), // TYPE_PAINT
        null, // TYPE_PERCENTAGE
        null, // TYPE_TRANSFORM_LIST
        uncomputedAnimatableStringValueFactory, // TYPE_URI
        null, // TYPE_FREQUENCY
        null, // TYPE_TIME
            new AnimatableNumberListValueFactory(), // TYPE_NUMBER_LIST
            new AnimatableLengthListValueFactory(), // TYPE_LENGTH_LIST
        uncomputedAnimatableStringValueFactory, // TYPE_IDENT
        uncomputedAnimatableStringValueFactory, // TYPE_CDATA
        animatableLengthOrIdentFactory, // TYPE_LENGTH_OR_INHERIT
        uncomputedAnimatableStringValueFactory, // TYPE_IDENT_LIST
        uncomputedAnimatableStringValueFactory, // TYPE_CLIP_VALUE
        uncomputedAnimatableStringValueFactory, // TYPE_URI_OR_IDENT
        uncomputedAnimatableStringValueFactory, // TYPE_CURSOR_VALUE
            new AnimatablePathDataFactory(), // TYPE_PATH_DATA
        uncomputedAnimatableStringValueFactory, // TYPE_ENABLE_BACKGROUND_VALUE
        null, // TYPE_TIME_VALUE_LIST
        animatableNumberOrIdentFactory, // TYPE_NUMBER_OR_INHERIT
        uncomputedAnimatableStringValueFactory, // TYPE_FONT_FAMILY_VALUE
        null, // TYPE_FONT_FACE_FONT_SIZE_VALUE
        new AnimatableNumberOrIdentFactory(true), // TYPE_FONT_WEIGHT_VALUE
        new AnimatableAngleOrIdentFactory(), // TYPE_ANGLE_OR_IDENT
        null, // TYPE_KEY_SPLINES_VALUE
            new AnimatablePointListValueFactory(), // TYPE_POINTS_VALUE
            new AnimatablePreserveAspectRatioValueFactory(), // TYPE_PRESERVE_ASPECT_RATIO_VALUE
        null, // TYPE_URI_LIST
        uncomputedAnimatableStringValueFactory, // TYPE_LENGTH_LIST_OR_IDENT
        null, // TYPE_CHARACTER_OR_UNICODE_RANGE_LIST
        null, // TYPE_UNICODE_RANGE_LIST
        null, // TYPE_FONT_VALUE
        null, // TYPE_FONT_DECSRIPTOR_SRC_VALUE
        animatableLengthOrIdentFactory, // TYPE_FONT_SIZE_VALUE
        animatableLengthOrIdentFactory, // TYPE_BASELINE_SHIFT_VALUE
        animatableLengthOrIdentFactory, // TYPE_KERNING_VALUE
        animatableLengthOrIdentFactory, // TYPE_SPACING_VALUE
        animatableLengthOrIdentFactory, // TYPE_LINE_HEIGHT_VALUE
        animatableNumberOrIdentFactory, // TYPE_FONT_SIZE_ADJUST_VALUE
        null, // TYPE_LANG_VALUE
        null, // TYPE_LANG_LIST_VALUE
            new AnimatableNumberOrPercentageValueFactory(), // TYPE_NUMBER_OR_PERCENTAGE
        null, // TYPE_TIMING_SPECIFIER_LIST
            new AnimatableBooleanValueFactory(), // TYPE_BOOLEAN
            new AnimatableRectValueFactory() // TYPE_RECT
    };

    /**
     * Whether the document is an SVG 1.2 document.
     */
    protected boolean isSVG12;

    /**
     * List of bridges that will be initialized when the document is started.
     */
    protected LinkedList initialBridges = new LinkedList();

    /**
     * A StyleMap used by the {@link Factory}s when computing CSS values.
     */
    protected StyleMap dummyStyleMap;

    /**
     * The thread that ticks the animation engine.
     */
    protected AnimationThread animationThread;

    /**
     * The animation limiting mode.
     */
    protected int animationLimitingMode;

    /**
     * The amount of animation limiting.
     */
    protected float animationLimitingAmount;

    /**
     * Set of SMIL animation event names for SVG 1.1.
     */
    protected static final Set animationEventNames11 = new HashSet();

    /**
     * Set of SMIL animation event names for SVG 1.2.
     */
    protected static final Set animationEventNames12 = new HashSet();

    static {
        String[] eventNamesCommon = {
            "click", "mousedown", "mouseup", "mouseover", "mousemove",
            "mouseout", "beginEvent", "endEvent"
        };
        String[] eventNamesSVG11 = {
            "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
            "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
            "DOMAttrModified", "DOMCharacterDataModified", "SVGLoad",
            "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
            "repeatEvent"
        };
        String[] eventNamesSVG12 = {
            "load", "resize", "scroll", "zoom"
        };
        for (String anEventNamesCommon : eventNamesCommon) {
            animationEventNames11.add(anEventNamesCommon);
            animationEventNames12.add(anEventNamesCommon);
        }
        for (String anEventNamesSVG11 : eventNamesSVG11) {
            animationEventNames11.add(anEventNamesSVG11);
        }
        for (String anEventNamesSVG12 : eventNamesSVG12) {
            animationEventNames12.add(anEventNamesSVG12);
        }
    }

    /**
     * Creates a new SVGAnimationEngine.
     */
    public SVGAnimationEngine(Document doc, BridgeContext ctx) {
        super(doc);
        this.ctx = ctx;
        SVGOMDocument d = (SVGOMDocument) doc;
        cssEngine = d.getCSSEngine();
        dummyStyleMap = new StyleMap(cssEngine.getNumberOfProperties());
        isSVG12 = d.isSVG12();
    }

    /**
     * Disposes this animation engine.
     */
    public void dispose() {
        synchronized (this) {
            pause();
            super.dispose();
        }
    }

    /**
     * Adds an animation element bridge to the list of bridges that
     * require initializing when the document is started.
     */
    public void addInitialBridge(SVGAnimationElementBridge b) {
        if (initialBridges != null) {
            initialBridges.add(b);
        }
    }

    /**
     * Returns whether animation processing has begun.
     */
    public boolean hasStarted() {
        return started;
    }

    /**
     * Parses an AnimatableValue.
     */
    public AnimatableValue parseAnimatableValue(Element animElt,
                                                AnimationTarget target,
                                                String ns, String ln,
                                                boolean isCSS,
                                                String s) {
        SVGOMElement elt = (SVGOMElement) target.getElement();
        int type;
        if (isCSS) {
            type = elt.getPropertyType(ln);
        } else {
            type = elt.getAttributeType(ns, ln);
        }
        Factory factory = factories[type];
        if (factory == null) {
            String an = ns == null ? ln : '{' + ns + '}' + ln;
            throw new BridgeException
                (ctx, animElt, "attribute.not.animatable",
                 new Object[] { target.getElement().getNodeName(), an });
        }
        return factories[type].createValue(target, ns, ln, isCSS, s);
    }

    /**
     * Returns an AnimatableValue for the underlying value of a CSS property.
     */
    public AnimatableValue getUnderlyingCSSValue(Element animElt,
                                                 AnimationTarget target,
                                                 String pn) {
        ValueManager[] vms = cssEngine.getValueManagers();
        int idx = cssEngine.getPropertyIndex(pn);
        if (idx != -1) {
            int type = vms[idx].getPropertyType();
            Factory factory = factories[type];
            if (factory == null) {
                throw new BridgeException
                    (ctx, animElt, "attribute.not.animatable",
                     new Object[] { target.getElement().getNodeName(), pn });
            }
            SVGStylableElement e = (SVGStylableElement) target.getElement();
            CSSStyleDeclaration over = e.getOverrideStyle();
            String oldValue = over.getPropertyValue(pn);
            if (oldValue != null) {
                over.removeProperty(pn);
            }
            Value v = cssEngine.getComputedStyle(e, null, idx);
            if (oldValue != null && !oldValue.equals("")) {
                over.setProperty(pn, oldValue, null);
            }
            return factories[type].createValue(target, pn, v);
        }
        // XXX Doesn't handle shorthands.
        return null;
    }

    /**
     * Pauses the animations.
     */
    public void pause() {
        super.pause();
        UpdateManager um = ctx.getUpdateManager();
        if (um != null) {
            um.getUpdateRunnableQueue().setIdleRunnable(null);
        }
    }

    /**
     * Pauses the animations.
     */
    public void unpause() {
        super.unpause();
        UpdateManager um = ctx.getUpdateManager();
        if (um != null) {
            um.getUpdateRunnableQueue().setIdleRunnable(animationTickRunnable);
        }
    }

    /**
     * Returns the current document time.
     */
    public float getCurrentTime() {
        boolean p = pauseTime != 0;
        unpause();
        float t = timedDocumentRoot.getCurrentTime();
        if (p) {
            pause();
        }
        return Float.isNaN(t) ? 0 : t;
    }

    /**
     * Sets the current document time.
     */
    public float setCurrentTime(float t) {
        if (started) {
            float ret = super.setCurrentTime(t);
            if (animationTickRunnable != null) {
                animationTickRunnable.resume();
            }
            return ret;
        } else {
            initialStartTime = t;
            return 0;
        }
    }

    /**
     * Creates a new returns a new TimedDocumentRoot object for the document.
     */
    protected TimedDocumentRoot createDocumentRoot() {
        return new AnimationRoot();
    }

    /**
     * Starts the animation engine.
     */
    public void start(long documentStartTime) {
        if (started) {
            return;
        }
        started = true;
        try {
            try {
                Calendar cal = Calendar.getInstance();
                cal.setTime(new Date(documentStartTime));
                timedDocumentRoot.resetDocument(cal);
                Object[] bridges = initialBridges.toArray();
                initialBridges = null;
                for (Object bridge2 : bridges) {
                    SVGAnimationElementBridge bridge =
                            (SVGAnimationElementBridge) bridge2;
                    bridge.initializeAnimation();
                }
                for (Object bridge1 : bridges) {
                    SVGAnimationElementBridge bridge =
                            (SVGAnimationElementBridge) bridge1;
                    bridge.initializeTimedElement();
                }

                // tick(0, false);
                // animationThread = new AnimationThread();
                // animationThread.start();
                UpdateManager um = ctx.getUpdateManager();
                if (um != null) {
                    RunnableQueue q = um.getUpdateRunnableQueue();
                    animationTickRunnable = new AnimationTickRunnable(q, this);
                    q.setIdleRunnable(animationTickRunnable);
                    if (initialStartTime != 0) {
                        setCurrentTime(initialStartTime);
                    }
                }
            } catch (AnimationException ex) {
                throw new BridgeException(ctx, ex.getElement().getElement(),
                                          ex.getMessage());
            }
        } catch (Exception ex) {
            if (ctx.getUserAgent() == null) {
                ex.printStackTrace();
            } else {
                ctx.getUserAgent().displayError(ex);
            }
        }
    }

    /**
     * Sets the animation limiting mode to "none".
     */
    public void setAnimationLimitingNone() {
        animationLimitingMode = 0;
    }

    /**
     * Sets the animation limiting mode to a percentage of CPU.
     * @param pc the maximum percentage of CPU to use (0 &lt; pc ≤ 1)
     */
    public void setAnimationLimitingCPU(float pc) {
        animationLimitingMode = 1;
        animationLimitingAmount = pc;
    }

    /**
     * Sets the animation limiting mode to a number of frames per second.
     * @param fps the maximum number of frames per second (fps &gt; 0)
     */
    public void setAnimationLimitingFPS(float fps) {
        animationLimitingMode = 2;
        animationLimitingAmount = fps;
    }

    /**
     * A class for the root time container.
     */
    protected class AnimationRoot extends TimedDocumentRoot {

        /**
         * Creates a new AnimationRoot object.
         */
        public AnimationRoot() {
            super(!isSVG12, isSVG12);
        }

        /**
         * Returns the namespace URI of the event that corresponds to the given
         * animation event name.
         */
        protected String getEventNamespaceURI(String eventName) {
            if (!isSVG12) {
                return null;
            }
            if (eventName.equals("focusin")
                    || eventName.equals("focusout")
                    || eventName.equals("activate")
                    || animationEventNames12.contains(eventName)) {
                return XMLConstants.XML_EVENTS_NAMESPACE_URI;
            }
            return null;
        }

        /**
         * Returns the type of the event that corresponds to the given
         * animation event name.
         */
        protected String getEventType(String eventName) {
            if (eventName.equals("focusin")) {
                return "DOMFocusIn";
            } else if (eventName.equals("focusout")) {
                return "DOMFocusOut";
            } else if (eventName.equals("activate")) {
                return "DOMActivate";
            }
            if (isSVG12) {
                if (animationEventNames12.contains(eventName)) {
                    return eventName;
                }
            } else {
                if (animationEventNames11.contains(eventName)) {
                    return eventName;
                }
            }
            return null;
        }

        /**
         * Returns the name of the repeat event.
         * @return "repeatEvent" for SVG
         */
        protected String getRepeatEventName() {
            return SMILConstants.SMIL_REPEAT_EVENT_NAME;
        }

        /**
         * Fires a TimeEvent of the given type on this element.
         * @param eventType the type of TimeEvent ("beginEvent", "endEvent"
         *                  or "repeatEvent"/"repeat").
         * @param time the timestamp of the event object
         */
        protected void fireTimeEvent(String eventType, Calendar time,
                                     int detail) {
            AnimationSupport.fireTimeEvent
                ((EventTarget) document, eventType, time, detail);
        }

        /**
         * Invoked to indicate this timed element became active at the
         * specified time.
         * @param begin the time the element became active, in document simple time
         */
        protected void toActive(float begin) {
        }

        /**
         * Invoked to indicate that this timed element became inactive.
         * @param stillActive if true, indicates that the element is still
         *                    actually active, but between the end of the
         *                    computed repeat duration and the end of the
         *                    interval
         * @param isFrozen whether the element is frozen or not
         */
        protected void toInactive(boolean stillActive, boolean isFrozen) {
        }

        /**
         * Invoked to indicate that this timed element has had its fill removed.
         */
        protected void removeFill() {
        }

        /**
         * Invoked to indicate that this timed element has been sampled at the
         * given time.
         * @param simpleTime the sample time in local simple time
         * @param simpleDur the simple duration of the element
         * @param repeatIteration the repeat iteration during which the element
         *                        was sampled
         */
        protected void sampledAt(float simpleTime, float simpleDur,
                                 int repeatIteration) {
        }

        /**
         * Invoked to indicate that this timed element has been sampled
         * at the end of its active time, at an integer multiple of the
         * simple duration.  This is the "last" value that will be used
         * for filling, which cannot be sampled normally.
         */
        protected void sampledLastValue(int repeatIteration) {
        }

        /**
         * Returns the timed element with the given ID.
         */
        protected TimedElement getTimedElementById(String id) {
            return AnimationSupport.getTimedElementById(id, document);
        }

        /**
         * Returns the event target with the given ID.
         */
        protected EventTarget getEventTargetById(String id) {
            return AnimationSupport.getEventTargetById(id, document);
        }

        /**
         * Returns the target of this animation as an {@link EventTarget}.  Used
         * for eventbase timing specifiers where the element ID is omitted.
         */
        protected EventTarget getAnimationEventTarget() {
            return null;
        }

        /**
         * Returns the event target that should be listened to for
         * access key events.
         */
        protected EventTarget getRootEventTarget() {
            return (EventTarget) document;
        }

        /**
         * Returns the DOM element that corresponds to this timed element, if
         * such a DOM element exists.
         */
        public Element getElement() {
            return null;
        }

        /**
         * Returns whether this timed element comes before the given timed
         * element in document order.
         */
        public boolean isBefore(TimedElement other) {
            return false;
        }

        /**
         * Invoked by timed elements in this document to indicate that the
         * current interval will be re-evaluated at the next sample.
         */
        protected void currentIntervalWillUpdate() {
            if (animationTickRunnable != null) {
                animationTickRunnable.resume();
            }
        }
    }

    /**
     * Idle runnable to tick the animation, that reads times from System.in.
     */
    protected static class DebugAnimationTickRunnable extends AnimationTickRunnable {

        float t = 0f;

        public DebugAnimationTickRunnable(RunnableQueue q, SVGAnimationEngine eng) {
            super(q, eng);
            waitTime = Long.MAX_VALUE;
            new Thread() {
                public void run() {
                    java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
                    System.out.println("Enter times.");
                    for (;;) {
                        String s;
                        try {
                            s = r.readLine();
                        } catch (java.io.IOException e) {
                            s = null;
                        }
                        if (s == null) {
                            System.exit(0);
                        }
                        t = Float.parseFloat(s);
                        DebugAnimationTickRunnable.this.resume();
                    }
                }
            }.start();
        }

        public void resume() {
            waitTime = 0;
            Object lock = q.getIteratorLock();
            synchronized (lock) {
                lock.notify();
            }
        }

        public long getWaitTime() {
            long wt = waitTime;
            waitTime = Long.MAX_VALUE;
            return wt;
        }

        public void run() {
            SVGAnimationEngine eng = getAnimationEngine();
            synchronized (eng) {
                try {
                    try {
                        eng.tick(t, false);
                    } catch (AnimationException ex) {
                        throw new BridgeException
                            (eng.ctx, ex.getElement().getElement(),
                             ex.getMessage());
                    }
                } catch (Exception ex) {
                    if (eng.ctx.getUserAgent() == null) {
                        ex.printStackTrace();
                    } else {
                        eng.ctx.getUserAgent().displayError(ex);
                    }
                }
            }
        }
    }

    /**
     * Idle runnable to tick the animation.
     */
    protected static class AnimationTickRunnable
            implements RunnableQueue.IdleRunnable {

        /**
         * Calendar instance used for passing current time values to the
         * animation timing system.
         */
        protected Calendar time = Calendar.getInstance();

//         /**
//          * The current document time in seconds, truncated.
//          */
//         protected double second = -1.;

//         /**
//          * The number of frames that have been ticked so far this second.
//          */
//         protected int frames;

        /**
         * The number of milliseconds to wait until the next animation tick.
         * This is returned by {@link #getWaitTime()}.
         */
        protected long waitTime;

        /**
         * The RunnableQueue in which this is the
         * {@link RunnableQueue.IdleRunnable}.
         */
        protected RunnableQueue q;

        /**
         * The number of past tick times to keep, for computing the average
         * time per tick.
         */
        private static final int NUM_TIMES = 8;

        /**
         * The past tick times.
         */
        protected long[] times = new long[NUM_TIMES];

        /**
         * The sum of the times in {@link #times}.
         */
        protected long sumTime;

        /**
         * The current index into {@link #times}.
         */
        protected int timeIndex;

        /**
         * A weak reference to the SVGAnimationEngine this AnimationTickRunnable
         * is for.  We make this a WeakReference so that a ticking animation
         * engine does not prevent from being GCed.
         */
        protected WeakReference engRef;

        /**
         * The maximum number of consecutive exceptions to allow before
         * stopping the report of them.
         */
        protected static final int MAX_EXCEPTION_COUNT = 10;

        /**
         * The number of consecutive exceptions that have been thrown.  This is
         * used to detect when exceptions are occurring every tick, and to stop
         * reporting them when this happens.
         */
        protected int exceptionCount;

        /**
         * Creates a new AnimationTickRunnable.
         */
        public AnimationTickRunnable(RunnableQueue q, SVGAnimationEngine eng) {
            this.q = q;
            this.engRef = new WeakReference(eng);
            // Initialize the past times to 100ms.
            Arrays.fill(times, 100);
            sumTime = 100 * NUM_TIMES;
        }

        /**
         * Forces an animation update, if the {@link RunnableQueue} is
         * currently waiting.
         */
        public void resume() {
            waitTime = 0;
            Object lock = q.getIteratorLock();
            synchronized (lock) {
                lock.notify();
            }
        }

        /**
         * Returns the system time that can be safely waited until before this
         * {@link Runnable} is run again.
         *
         * @return time to wait until, <code>0</code> if no waiting can
         *         be done, or {@link Long#MAX_VALUE} if the {@link Runnable}
         *         should not be run again at this time
         */
        public long getWaitTime() {
            return waitTime;
        }

        /**
         * Performs one tick of the animation.
         */
        public void run() {
            SVGAnimationEngine eng = getAnimationEngine();
            synchronized (eng) {
                int animationLimitingMode = eng.animationLimitingMode;
                float animationLimitingAmount = eng.animationLimitingAmount;
                try {
                    try {
                        long before = System.currentTimeMillis();
                        time.setTime(new Date(before));
                        float t = eng.timedDocumentRoot.convertWallclockTime(time);
//                         if (Math.floor(t) > second) {
//                             second = Math.floor(t);
//                             System.err.println("fps: " + frames);
//                             frames = 0;
//                         }
                        float t2 = eng.tick(t, false);
                        long after = System.currentTimeMillis();
                        long dur = after - before;
                        if (dur == 0) {
                            dur = 1;
                        }
                        sumTime -= times[timeIndex];
                        sumTime += dur;
                        times[timeIndex] = dur;
                        timeIndex = (timeIndex + 1) % NUM_TIMES;

                        if (t2 == Float.POSITIVE_INFINITY) {
                            waitTime = Long.MAX_VALUE;
                        } else {
                            waitTime = before + (long) (t2 * 1000) - 1000;
                            if (waitTime < after) {
                                waitTime = after;
                            }
                            if (animationLimitingMode != 0) {
                                float ave = (float) sumTime / NUM_TIMES;
                                float delay;
                                if (animationLimitingMode == 1) {
                                    // %cpu
                                    delay = ave / animationLimitingAmount - ave;
                                } else {
                                    // fps
                                    delay = 1000f / animationLimitingAmount - ave;
                                }
                                long newWaitTime = after + (long) delay;
                                if (newWaitTime > waitTime) {
                                    waitTime = newWaitTime;
                                }
                            }
                        }
//                         frames++;
                    } catch (AnimationException ex) {
                        throw new BridgeException
                            (eng.ctx, ex.getElement().getElement(),
                             ex.getMessage());
                    }
                    exceptionCount = 0;
                } catch (Exception ex) {
                    if (++exceptionCount < MAX_EXCEPTION_COUNT) {
                        if (eng.ctx.getUserAgent() == null) {
                            ex.printStackTrace();
                        } else {
                            eng.ctx.getUserAgent().displayError(ex);
                        }
                    }
                }

                if (animationLimitingMode == 0) {
                    // so we don't steal too much time from the Swing thread
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException ie) {
                    }
                }
            }
        }

        /**
         * Returns the SVGAnimationEngine this AnimationTickRunnable is for.
         */
        protected SVGAnimationEngine getAnimationEngine() {
            return (SVGAnimationEngine) engRef.get();
        }
    }

    /**
     * The thread that ticks the animation.
     */
    protected class AnimationThread extends Thread {

        /**
         * The current time.
         */
        protected Calendar time = Calendar.getInstance();

        /**
         * The RunnableQueue to perform the animation in.
         */
        protected RunnableQueue runnableQueue =
            ctx.getUpdateManager().getUpdateRunnableQueue();

        /**
         * The animation ticker Runnable.
         */
        protected Ticker ticker = new Ticker();

        /**
         * Ticks the animation over as fast as possible.
         */
        public void run() {
            if (true) {
                for (;;) {
                    time.setTime(new Date());
                    ticker.t = timedDocumentRoot.convertWallclockTime(time);
                    try {
                        runnableQueue.invokeAndWait(ticker);
                    } catch (InterruptedException e) {
                        return;
                    }
                }
            } else {
                ticker.t = 1;
                while (ticker.t < 10) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ie) {
                    }
                    try {
                        runnableQueue.invokeAndWait(ticker);
                    } catch (InterruptedException e) {
                        return;
                    }
                    ticker.t++;
                }
            }
        }

        /**
         * A runnable that ticks the animation engine.
         */
        protected class Ticker implements Runnable {

            /**
             * The document time to tick at next.
             */
            protected float t;

            /**
             * Ticks the animation over.
             */
            public void run() {
                tick(t, false);
            }
        }
    }

    // AnimatableValue factories

    /**
     * Interface for AnimatableValue factories.
     */
    protected interface Factory {

        /**
         * Creates a new AnimatableValue from a string.
         */
        AnimatableValue createValue(AnimationTarget target, String ns,
                                    String ln, boolean isCSS, String s);

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        AnimatableValue createValue(AnimationTarget target, String pn, Value v);
    }

    /**
     * Factory class for AnimatableValues for CSS properties.
     * XXX Shorthand properties are not supported.
     */
    protected abstract class CSSValueFactory implements Factory {

        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            // XXX Always parsing as a CSS value.
            return createValue(target, ln, createCSSValue(target, ln, s));
        }

        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            CSSStylableElement elt = (CSSStylableElement) target.getElement();
            v = computeValue(elt, pn, v);
            return createAnimatableValue(target, pn, v);
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}, after
         * computation and inheritance.
         */
        protected abstract AnimatableValue createAnimatableValue
            (AnimationTarget target, String pn, Value v);

        /**
         * Creates a new CSS {@link Value} from a string.
         */
        protected Value createCSSValue(AnimationTarget t, String pn, String s) {
            CSSStylableElement elt = (CSSStylableElement) t.getElement();
            Value v = cssEngine.parsePropertyValue(elt, pn, s);
            return computeValue(elt, pn, v);
        }

        /**
         * Computes a CSS {@link Value} and performance inheritance if the
         * specified value is 'inherit'.
         */
        protected Value computeValue(CSSStylableElement elt, String pn,
                                     Value v) {
            ValueManager[] vms = cssEngine.getValueManagers();
            int idx = cssEngine.getPropertyIndex(pn);
            if (idx != -1) {
                if (v.getCssValueType() == CSSValue.CSS_INHERIT) {
                    elt = CSSEngine.getParentCSSStylableElement(elt);
                    if (elt != null) {
                        return cssEngine.getComputedStyle(elt, null, idx);
                    }
                    return vms[idx].getDefaultValue();
                }
                v = vms[idx].computeValue(elt, null, cssEngine, idx,
                                          dummyStyleMap, v);
            }
            return v;
        }
    }

    /**
     * Factory class for {@link AnimatableBooleanValue}s.
     */
    protected static class AnimatableBooleanValueFactory implements Factory {

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            return new AnimatableBooleanValue(target, "true".equals(s));
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return new AnimatableBooleanValue(target,
                                              "true".equals(v.getCssText()));
        }
    }

    /**
     * Factory class for {@link AnimatableIntegerValue}s.
     */
    protected static class AnimatableIntegerValueFactory implements Factory {

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            return new AnimatableIntegerValue(target, Integer.parseInt(s));
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return new AnimatableIntegerValue(target,
                                              Math.round(v.getFloatValue()));
        }
    }

    /**
     * Factory class for {@link AnimatableNumberValue}s.
     */
    protected static class AnimatableNumberValueFactory implements Factory {

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            return new AnimatableNumberValue(target, Float.parseFloat(s));
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return new AnimatableNumberValue(target, v.getFloatValue());
        }
    }

    /**
     * Factory class for {@link AnimatableNumberOrPercentageValue}s.
     */
    protected static class AnimatableNumberOrPercentageValueFactory
            implements Factory {

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            float v;
            boolean pc;
            if (s.charAt(s.length() - 1) == '%') {
                v = Float.parseFloat(s.substring(0, s.length() - 1));
                pc = true;
            } else {
                v = Float.parseFloat(s);
                pc = false;
            }
            return new AnimatableNumberOrPercentageValue(target, v, pc);
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            switch (v.getPrimitiveType()) {
                case CSSPrimitiveValue.CSS_PERCENTAGE:
                    return new AnimatableNumberOrPercentageValue
                        (target, v.getFloatValue(), true);
                case CSSPrimitiveValue.CSS_NUMBER:
                    return new AnimatableNumberOrPercentageValue
                        (target, v.getFloatValue());
            }
            // XXX Do something better than returning null.
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatablePreserveAspectRatioValue}s.
     */
    protected static class AnimatablePreserveAspectRatioValueFactory implements Factory {

        /**
         * The parsed 'align' value.
         */
        protected short align;

        /**
         * The parsed 'meetOrSlice' value.
         */
        protected short meetOrSlice;

        /**
         * Parser for preserveAspectRatio values.
         */
        protected PreserveAspectRatioParser parser =
            new PreserveAspectRatioParser();

        /**
         * Handler for the preserveAspectRatio parser.
         */
        protected DefaultPreserveAspectRatioHandler handler =
            new DefaultPreserveAspectRatioHandler() {

            /**
             * Implements {@link
             * PreserveAspectRatioHandler#startPreserveAspectRatio()}.
             */
            public void startPreserveAspectRatio() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_UNKNOWN;
                meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_UNKNOWN;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#none()}.
             */
            public void none() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMaxYMax()}.
             */
            public void xMaxYMax() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMaxYMid()}.
             */
            public void xMaxYMid() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMaxYMin()}.
             */
            public void xMaxYMin() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMidYMax()}.
             */
            public void xMidYMax() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMidYMid()}.
             */
            public void xMidYMid() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMidYMin()}.
             */
            public void xMidYMin() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMinYMax()}.
             */
            public void xMinYMax() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMinYMid()}.
             */
            public void xMinYMid() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#xMinYMin()}.
             */
            public void xMinYMin() throws ParseException {
                align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#meet()}.
             */
            public void meet() throws ParseException {
                meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
            }

            /**
             * Implements {@link PreserveAspectRatioHandler#slice()}.
             */
            public void slice() throws ParseException {
                meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE;
            }
        };

        /**
         * Creates a new AnimatablePreserveAspectRatioValueFactory.
         */
        public AnimatablePreserveAspectRatioValueFactory() {
            parser.setPreserveAspectRatioHandler(handler);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                parser.parse(s);
                return new AnimatablePreserveAspectRatioValue(target, align,
                                                              meetOrSlice);
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since preserveAspectRatio values aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatableLengthValue}s.
     */
    protected static class AnimatableLengthValueFactory implements Factory {

        /**
         * The parsed length unit type.
         */
        protected short type;

        /**
         * The parsed length value.
         */
        protected float value;

        /**
         * Parser for lengths.
         */
        protected LengthParser parser = new LengthParser();

        /**
         * Handler for the length parser.
         */
        protected LengthHandler handler = new DefaultLengthHandler() {
            public void startLength() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_NUMBER;
            }
            public void lengthValue(float v) throws ParseException {
                value = v;
            }
            public void em() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_EMS;
            }
            public void ex() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_EXS;
            }
            public void in() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_IN;
            }
            public void cm() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_CM;
            }
            public void mm() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_MM;
            }
            public void pc() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_PC;
            }
            public void pt() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_PT;
            }
            public void px() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_PX;
            }
            public void percentage() throws ParseException {
                type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE;
            }
            public void endLength() throws ParseException {
            }
        };

        /**
         * Creates a new AnimatableLengthValueFactory.
         */
        public AnimatableLengthValueFactory() {
            parser.setLengthHandler(handler);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            short pcInterp = target.getPercentageInterpretation(ns, ln, isCSS);
            try {
                parser.parse(s);
                return new AnimatableLengthValue
                    (target, type, value, pcInterp);
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return new AnimatableIntegerValue(target,
                                              Math.round(v.getFloatValue()));
        }
    }

    /**
     * Factory class for {@link AnimatableLengthListValue}s.
     */
    protected static class AnimatableLengthListValueFactory implements Factory {

        /**
         * Parser for length lists.
         */
        protected LengthListParser parser = new LengthListParser();

        /**
         * The producer class that accumulates the lengths.
         */
        protected LengthArrayProducer producer = new LengthArrayProducer();

        /**
         * Creates a new AnimatableLengthListValueFactory.
         */
        public AnimatableLengthListValueFactory() {
            parser.setLengthListHandler(producer);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                short pcInterp = target.getPercentageInterpretation
                    (ns, ln, isCSS);
                parser.parse(s);
                return new AnimatableLengthListValue
                    (target, producer.getLengthTypeArray(),
                     producer.getLengthValueArray(),
                     pcInterp);
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since point lists aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatableNumberListValue}s.
     */
    protected static class AnimatableNumberListValueFactory implements Factory {

        /**
         * Parser for number lists.
         */
        protected NumberListParser parser = new NumberListParser();

        /**
         * The producer class that accumulates the numbers.
         */
        protected FloatArrayProducer producer = new FloatArrayProducer();

        /**
         * Creates a new AnimatableNumberListValueFactory.
         */
        public AnimatableNumberListValueFactory() {
            parser.setNumberListHandler(producer);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                parser.parse(s);
                return new AnimatableNumberListValue(target,
                                                     producer.getFloatArray());
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since number lists aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatableNumberListValue}s.
     */
    protected static class AnimatableRectValueFactory implements Factory {

        /**
         * Parser for number lists.
         */
        protected NumberListParser parser = new NumberListParser();

        /**
         * The producer class that accumulates the numbers.
         */
        protected FloatArrayProducer producer = new FloatArrayProducer();

        /**
         * Creates a new AnimatableNumberListValueFactory.
         */
        public AnimatableRectValueFactory() {
            parser.setNumberListHandler(producer);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                parser.parse(s);
                float[] r = producer.getFloatArray();
                if (r.length != 4) {
                    // XXX Do something better than returning null.
                    return null;
                }
                return new AnimatableRectValue(target, r[0], r[1], r[2], r[3]);
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since rects aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatablePointListValue}s.
     */
    protected static class AnimatablePointListValueFactory implements Factory {

        /**
         * Parser for point lists.
         */
        protected PointsParser parser = new PointsParser();

        /**
         * The producer class that accumulates the points.
         */
        protected FloatArrayProducer producer = new FloatArrayProducer();

        /**
         * Creates a new AnimatablePointListValueFactory.
         */
        public AnimatablePointListValueFactory() {
            parser.setPointsHandler(producer);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                parser.parse(s);
                return new AnimatablePointListValue(target,
                                                    producer.getFloatArray());
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since point lists aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatablePathDataValue}s.
     */
    protected static class AnimatablePathDataFactory implements Factory {

        /**
         * Parser for path data.
         */
        protected PathParser parser = new PathParser();

        /**
         * The producer class that accumulates the path segments.
         */
        protected PathArrayProducer producer = new PathArrayProducer();

        /**
         * Creates a new AnimatablePathDataFactory.
         */
        public AnimatablePathDataFactory() {
            parser.setPathHandler(producer);
        }

        /**
         * Creates a new AnimatableValue from a string.
         */
        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            try {
                parser.parse(s);
                return new AnimatablePathDataValue
                    (target, producer.getPathCommands(),
                     producer.getPathParameters());
            } catch (ParseException e) {
                // XXX Do something better than returning null.
                return null;
            }
        }

        /**
         * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
         * since point lists aren't used in CSS values.
         */
        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatableStringValue}s.
     */
    protected static class UncomputedAnimatableStringValueFactory implements Factory {

        public AnimatableValue createValue(AnimationTarget target, String ns,
                                           String ln, boolean isCSS, String s) {
            return new AnimatableStringValue(target, s);
        }

        public AnimatableValue createValue(AnimationTarget target, String pn,
                                           Value v) {
            return new AnimatableStringValue(target, v.getCssText());
        }
    }

    /**
     * Factory class for {@link AnimatableLengthOrIdentValue}s.
     */
    protected class AnimatableLengthOrIdentFactory extends CSSValueFactory {

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            if (v instanceof StringValue) {
                return new AnimatableLengthOrIdentValue(target,
                                                        v.getStringValue());
            }
            short pcInterp = target.getPercentageInterpretation(null, pn, true);
            FloatValue fv = (FloatValue) v;
            return new AnimatableLengthOrIdentValue
                (target, fv.getPrimitiveType(), fv.getFloatValue(), pcInterp);
        }
    }

    /**
     * Factory class for {@link AnimatableNumberOrIdentValue}s.
     */
    protected class AnimatableNumberOrIdentFactory extends CSSValueFactory {

        /**
         * Whether numbers are actually numeric keywords, as with the
         * font-weight property.
         */
        protected boolean numericIdents;

        public AnimatableNumberOrIdentFactory(boolean numericIdents) {
            this.numericIdents = numericIdents;
        }

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            if (v instanceof StringValue) {
                return new AnimatableNumberOrIdentValue(target,
                                                        v.getStringValue());
            }
            FloatValue fv = (FloatValue) v;
            return new AnimatableNumberOrIdentValue(target, fv.getFloatValue(),
                                                    numericIdents);
        }
    }

    /**
     * Factory class for {@link AnimatableAngleValue}s.
     */
    protected class AnimatableAngleValueFactory extends CSSValueFactory {

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            FloatValue fv = (FloatValue) v;
            short unit;
            switch (fv.getPrimitiveType()) {
                case CSSPrimitiveValue.CSS_NUMBER:
                case CSSPrimitiveValue.CSS_DEG:
                    unit = SVGAngle.SVG_ANGLETYPE_DEG;
                    break;
                case CSSPrimitiveValue.CSS_RAD:
                    unit = SVGAngle.SVG_ANGLETYPE_RAD;
                    break;
                case CSSPrimitiveValue.CSS_GRAD:
                    unit = SVGAngle.SVG_ANGLETYPE_GRAD;
                    break;
                default:
                    // XXX Do something better than returning null.
                    return null;
            }
            return new AnimatableAngleValue(target, fv.getFloatValue(), unit);
        }
    }

    /**
     * Factory class for {@link AnimatableAngleOrIdentValue}s.
     */
    protected class AnimatableAngleOrIdentFactory extends CSSValueFactory {

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            if (v instanceof StringValue) {
                return new AnimatableAngleOrIdentValue(target,
                                                       v.getStringValue());
            }
            FloatValue fv = (FloatValue) v;
            short unit;
            switch (fv.getPrimitiveType()) {
                case CSSPrimitiveValue.CSS_NUMBER:
                case CSSPrimitiveValue.CSS_DEG:
                    unit = SVGAngle.SVG_ANGLETYPE_DEG;
                    break;
                case CSSPrimitiveValue.CSS_RAD:
                    unit = SVGAngle.SVG_ANGLETYPE_RAD;
                    break;
                case CSSPrimitiveValue.CSS_GRAD:
                    unit = SVGAngle.SVG_ANGLETYPE_GRAD;
                    break;
                default:
                    // XXX Do something better than returning null.
                    return null;
            }
            return new AnimatableAngleOrIdentValue(target, fv.getFloatValue(),
                                                   unit);
        }
    }

    /**
     * Factory class for {@link AnimatableColorValue}s.
     */
    protected class AnimatableColorValueFactory extends CSSValueFactory {

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            Paint p = PaintServer.convertPaint
                (target.getElement(), null, v, 1.0f, ctx);
            if (p instanceof Color) {
                Color c = (Color) p;
                return new AnimatableColorValue(target,
                                                c.getRed() / 255f,
                                                c.getGreen() / 255f,
                                                c.getBlue() / 255f);
            }
            // XXX Indicate that the parsed value wasn't a Color?
            return null;
        }
    }

    /**
     * Factory class for {@link AnimatablePaintValue}s.
     */
    protected class AnimatablePaintValueFactory extends CSSValueFactory {

        /**
         * Creates a new {@link AnimatablePaintValue} from a {@link Color}
         * object.
         */
        protected AnimatablePaintValue createColorPaintValue(AnimationTarget t,
                                                             Color c) {
            return AnimatablePaintValue.createColorPaintValue
                (t, c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f);

        }

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
                switch (v.getPrimitiveType()) {
                    case CSSPrimitiveValue.CSS_IDENT:
                        return AnimatablePaintValue.createNonePaintValue(target);
                    case CSSPrimitiveValue.CSS_RGBCOLOR: {
                        Paint p = PaintServer.convertPaint
                            (target.getElement(), null, v, 1.0f, ctx);
                        return createColorPaintValue(target, (Color) p);
                    }
                    case CSSPrimitiveValue.CSS_URI:
                        return AnimatablePaintValue.createURIPaintValue
                            (target, v.getStringValue());
                }
            } else {
                Value v1 = v.item(0);
                switch (v1.getPrimitiveType()) {
                    case CSSPrimitiveValue.CSS_RGBCOLOR: {
                        Paint p = PaintServer.convertPaint
                            (target.getElement(), null, v, 1.0f, ctx);
                        return createColorPaintValue(target, (Color) p);
                    }
                    case CSSPrimitiveValue.CSS_URI: {
                        Value v2 = v.item(1);
                        switch (v2.getPrimitiveType()) {
                            case CSSPrimitiveValue.CSS_IDENT:
                                return AnimatablePaintValue.createURINonePaintValue
                                    (target, v1.getStringValue());
                            case CSSPrimitiveValue.CSS_RGBCOLOR: {
                                Paint p = PaintServer.convertPaint
                                    (target.getElement(), null, v.item(1), 1.0f, ctx);
                                return createColorPaintValue(target, (Color) p);
                            }
                        }
                    }
                }
            }
            // XXX Indicate that the specified Value wasn't a Color?
            return null;
        }
    }

    /**
     * Factory class for computed CSS {@link AnimatableStringValue}s.
     */
    protected class AnimatableStringValueFactory extends CSSValueFactory {

        protected AnimatableValue createAnimatableValue(AnimationTarget target,
                                                        String pn, Value v) {
            return new AnimatableStringValue(target, v.getCssText());
        }
    }
}
