/*

   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.anim;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.batik.anim.dom.AnimationTarget;
import org.apache.batik.anim.dom.AnimationTargetListener;
import org.apache.batik.anim.timing.TimedDocumentRoot;
import org.apache.batik.anim.timing.TimedElement;
import org.apache.batik.anim.timing.TimegraphListener;
import org.apache.batik.anim.values.AnimatableValue;
import org.apache.batik.util.DoublyIndexedTable;

import org.w3c.dom.Document;

/**
 * An abstract base class for managing animation in a document.
 *
 * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
 * @version $Id$
 */
public abstract class AnimationEngine {

    // Constants to identify the type of animation.
    public static final short ANIM_TYPE_XML   = 0;
    public static final short ANIM_TYPE_CSS   = 1;
    public static final short ANIM_TYPE_OTHER = 2;

    /**
     * The document this AnimationEngine is managing animation for.
     */
    protected Document document;

    /**
     * The root time container for the document.
     */
    protected TimedDocumentRoot timedDocumentRoot;

    /**
     * The time at which the document was paused, or 0 if the document is not
     * paused.
     */
    protected long pauseTime;

    /**
     * Map of AnimationTargets to TargetInfo objects.
     */
    protected HashMap targets = new HashMap();

    /**
     * Map of AbstractAnimations to AnimationInfo objects.
     */
    protected HashMap animations = new HashMap();

    /**
     * The listener object for animation target base value changes.
     */
    protected Listener targetListener = new Listener();

    /**
     * Creates a new AnimationEngine for the given document.
     */
    public AnimationEngine(Document doc) {
        this.document = doc;
        timedDocumentRoot = createDocumentRoot();
    }

    /**
     * Disposes this animation engine.
     */
    public void dispose() {
        // Remove any target listeners that are registered.
        for (Object o : targets.entrySet()) {
            Map.Entry e = (Map.Entry) o;
            AnimationTarget target = (AnimationTarget) e.getKey();
            TargetInfo info = (TargetInfo) e.getValue();

            Iterator j = info.xmlAnimations.iterator();
            while (j.hasNext()) {
                DoublyIndexedTable.Entry e2 =
                        (DoublyIndexedTable.Entry) j.next();
                String namespaceURI = (String) e2.getKey1();
                String localName = (String) e2.getKey2();
                Sandwich sandwich = (Sandwich) e2.getValue();
                if (sandwich.listenerRegistered) {
                    target.removeTargetListener(namespaceURI, localName, false,
                            targetListener);
                }
            }

            j = info.cssAnimations.entrySet().iterator();
            while (j.hasNext()) {
                Map.Entry e2 = (Map.Entry) j.next();
                String propertyName = (String) e2.getKey();
                Sandwich sandwich = (Sandwich) e2.getValue();
                if (sandwich.listenerRegistered) {
                    target.removeTargetListener(null, propertyName, true,
                            targetListener);
                }
            }
        }
    }

    /**
     * Pauses the animations.
     */
    public void pause() {
        if (pauseTime == 0) {
            pauseTime = System.currentTimeMillis();
        }
    }

    /**
     * Unpauses the animations.
     */
    public void unpause() {
        if (pauseTime != 0) {
            Calendar begin = timedDocumentRoot.getDocumentBeginTime();
            int dt = (int) (System.currentTimeMillis() - pauseTime);
            begin.add(Calendar.MILLISECOND, dt);
            pauseTime = 0;
        }
    }

    /**
     * Returns whether animations are currently paused.
     */
    public boolean isPaused() {
        return pauseTime != 0;
    }

    /**
     * Returns the current document time.
     */
    public float getCurrentTime() {
        return timedDocumentRoot.getCurrentTime();
    }

    /**
     * Sets the current document time.
     */
    public float setCurrentTime(float t) {
        boolean p = pauseTime != 0;
        unpause();
        Calendar begin = timedDocumentRoot.getDocumentBeginTime();
        float now =
            timedDocumentRoot.convertEpochTime(System.currentTimeMillis());
        begin.add(Calendar.MILLISECOND, (int) ((now - t) * 1000));
        if (p) {
            pause();
        }
        return tick(t, true);
    }

    /**
     * Adds an animation to the document.
     * @param target the target element of the animation
     * @param type the type of animation (must be one of the
     *             <code>ANIM_TYPE_*</code> constants defined in this class
     * @param ns the namespace URI of the attribute being animated, if
     *           <code>type == </code>{@link #ANIM_TYPE_XML}
     * @param an the attribute name if <code>type == </code>{@link
     *           #ANIM_TYPE_XML}, the property name if <code>type == </code>
     *           {@link #ANIM_TYPE_CSS}, and the animation type otherwise
     * @param anim the animation
     */
    public void addAnimation(AnimationTarget target, short type, String ns,
                             String an, AbstractAnimation anim) {
        // org.apache.batik.anim.timing.Trace.enter(this, "addAnimation", new Object[] { target, new Short[type], ns, an, anim } ); try {
        timedDocumentRoot.addChild(anim.getTimedElement());

        AnimationInfo animInfo = getAnimationInfo(anim);
        animInfo.type = type;
        animInfo.attributeNamespaceURI = ns;
        animInfo.attributeLocalName = an;
        animInfo.target = target;
        animations.put(anim, animInfo);

        Sandwich sandwich = getSandwich(target, type, ns, an);
        if (sandwich.animation == null) {
            anim.lowerAnimation = null;
            anim.higherAnimation = null;
        } else {
            sandwich.animation.higherAnimation = anim;
            anim.lowerAnimation = sandwich.animation;
            anim.higherAnimation = null;
        }
        sandwich.animation = anim;
        if (anim.lowerAnimation == null) {
            sandwich.lowestAnimation = anim;
        }
        // } finally { org.apache.batik.anim.timing.Trace.exit(); }
    }

    /**
     * Removes an animation from the document.
     */
    public void removeAnimation(AbstractAnimation anim) {
        // org.apache.batik.anim.timing.Trace.enter(this, "removeAnimation", new Object[] { anim } ); try {
        timedDocumentRoot.removeChild(anim.getTimedElement());
        AbstractAnimation nextHigher = anim.higherAnimation;
        if (nextHigher != null) {
            nextHigher.markDirty();
        }
        moveToBottom(anim);
        if (anim.higherAnimation != null) {
            anim.higherAnimation.lowerAnimation = null;
        }
        AnimationInfo animInfo = getAnimationInfo(anim);
        Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
                                        animInfo.attributeNamespaceURI,
                                        animInfo.attributeLocalName);
        if (sandwich.animation == anim) {
            sandwich.animation = null;
            sandwich.lowestAnimation = null;
            sandwich.shouldUpdate = true;
        }
        // } finally { org.apache.batik.anim.timing.Trace.exit(); }
    }

    /**
     * Returns the Sandwich for the given animation type/attribute.
     */
    protected Sandwich getSandwich(AnimationTarget target, short type,
                                   String ns, String an) {
        TargetInfo info = getTargetInfo(target);
        Sandwich sandwich;
        if (type == ANIM_TYPE_XML) {
            sandwich = (Sandwich) info.xmlAnimations.get(ns, an);
            if (sandwich == null) {
                sandwich = new Sandwich();
                info.xmlAnimations.put(ns, an, sandwich);
            }
        } else if (type == ANIM_TYPE_CSS) {
            sandwich = (Sandwich) info.cssAnimations.get(an);
            if (sandwich == null) {
                sandwich = new Sandwich();
                info.cssAnimations.put(an, sandwich);
            }
        } else {
            sandwich = (Sandwich) info.otherAnimations.get(an);
            if (sandwich == null) {
                sandwich = new Sandwich();
                info.otherAnimations.put(an, sandwich);
            }
        }
        return sandwich;
    }

    /**
     * Returns the TargetInfo for the given AnimationTarget.
     */
    protected TargetInfo getTargetInfo(AnimationTarget target) {
        TargetInfo info = (TargetInfo) targets.get(target);
        if (info == null) {
            info = new TargetInfo();
            targets.put(target, info);
        }
        return info;
    }

    /**
     * Returns the AnimationInfo for the given AbstractAnimation.
     */
    protected AnimationInfo getAnimationInfo(AbstractAnimation anim) {
        AnimationInfo info = (AnimationInfo) animations.get(anim);
        if (info == null) {
            info = new AnimationInfo();
            animations.put(anim, info);
        }
        return info;
    }

    protected static final Map.Entry[] MAP_ENTRY_ARRAY = new Map.Entry[0];

    /**
     * Updates the animations in the document to the given document time.
     * @param time the document time to sample at
     * @param hyperlinking whether the document should be seeked to the given
     *                     time, as with hyperlinking
     */
    protected float tick(float time, boolean hyperlinking) {
        float waitTime = timedDocumentRoot.seekTo(time, hyperlinking);
        Map.Entry[] targetEntries =
            (Map.Entry[]) targets.entrySet().toArray(MAP_ENTRY_ARRAY);
        for (Map.Entry e : targetEntries) {
            AnimationTarget target = (AnimationTarget) e.getKey();
            TargetInfo info = (TargetInfo) e.getValue();

            // Update the XML animations.
            Iterator j = info.xmlAnimations.iterator();
            while (j.hasNext()) {
                DoublyIndexedTable.Entry e2 =
                        (DoublyIndexedTable.Entry) j.next();
                String namespaceURI = (String) e2.getKey1();
                String localName = (String) e2.getKey2();
                Sandwich sandwich = (Sandwich) e2.getValue();
                if (sandwich.shouldUpdate ||
                        sandwich.animation != null
                                && sandwich.animation.isDirty) {
                    AnimatableValue av = null;
                    boolean usesUnderlying = false;
                    AbstractAnimation anim = sandwich.animation;
                    if (anim != null) {
                        av = anim.getComposedValue();
                        usesUnderlying =
                                sandwich.lowestAnimation.usesUnderlyingValue();
                        anim.isDirty = false;
                    }
                    if (usesUnderlying && !sandwich.listenerRegistered) {
                        target.addTargetListener(namespaceURI, localName, false,
                                targetListener);
                        sandwich.listenerRegistered = true;
                    } else if (!usesUnderlying && sandwich.listenerRegistered) {
                        target.removeTargetListener(namespaceURI, localName,
                                false, targetListener);
                        sandwich.listenerRegistered = false;
                    }
                    target.updateAttributeValue(namespaceURI, localName, av);
                    sandwich.shouldUpdate = false;
                }
            }

            // Update the CSS animations.
            j = info.cssAnimations.entrySet().iterator();
            while (j.hasNext()) {
                Map.Entry e2 = (Map.Entry) j.next();
                String propertyName = (String) e2.getKey();
                Sandwich sandwich = (Sandwich) e2.getValue();
                if (sandwich.shouldUpdate ||
                        sandwich.animation != null
                                && sandwich.animation.isDirty) {
                    AnimatableValue av = null;
                    boolean usesUnderlying = false;
                    AbstractAnimation anim = sandwich.animation;
                    if (anim != null) {
                        av = anim.getComposedValue();
                        usesUnderlying =
                                sandwich.lowestAnimation.usesUnderlyingValue();
                        anim.isDirty = false;
                    }
                    if (usesUnderlying && !sandwich.listenerRegistered) {
                        target.addTargetListener(null, propertyName, true,
                                targetListener);
                        sandwich.listenerRegistered = true;
                    } else if (!usesUnderlying && sandwich.listenerRegistered) {
                        target.removeTargetListener(null, propertyName, true,
                                targetListener);
                        sandwich.listenerRegistered = false;
                    }
                    if (usesUnderlying) {
                        target.updatePropertyValue(propertyName, null);
                    }
                    if (!(usesUnderlying && av == null)) {
                        target.updatePropertyValue(propertyName, av);
                    }
                    sandwich.shouldUpdate = false;
                }
            }

            // Update the other animations.
            j = info.otherAnimations.entrySet().iterator();
            while (j.hasNext()) {
                Map.Entry e2 = (Map.Entry) j.next();
                String type = (String) e2.getKey();
                Sandwich sandwich = (Sandwich) e2.getValue();
                if (sandwich.shouldUpdate ||
                        sandwich.animation != null
                                && sandwich.animation.isDirty) {
                    AnimatableValue av = null;
                    AbstractAnimation anim = sandwich.animation;
                    if (anim != null) {
                        av = sandwich.animation.getComposedValue();
                        anim.isDirty = false;
                    }
                    target.updateOtherValue(type, av);
                    sandwich.shouldUpdate = false;
                }
            }
        }
        return waitTime;
    }

    /**
     * Invoked to indicate an animation became active at the specified time.
     *
     * @param anim the animation
     * @param begin the time the element became active, in document simple time
     */
    public void toActive(AbstractAnimation anim, float begin) {
        moveToTop(anim);
        anim.isActive = true;
        anim.beginTime = begin;
        anim.isFrozen = false;
        // Move the animation down, in case it began at the same time as another
        // animation in the sandwich and it's earlier in document order.
        pushDown(anim);
        anim.markDirty();
    }

    /**
     * Moves the animation down the sandwich such that it is in the right
     * position according to begin time and document order.
     */
    protected void pushDown(AbstractAnimation anim) {
        TimedElement e = anim.getTimedElement();
        AbstractAnimation top = null;
        boolean moved = false;
        while (anim.lowerAnimation != null
                && (anim.lowerAnimation.isActive
                    || anim.lowerAnimation.isFrozen)
                && (anim.lowerAnimation.beginTime > anim.beginTime
                    || anim.lowerAnimation.beginTime == anim.beginTime
                        && e.isBefore(anim.lowerAnimation.getTimedElement()))) {
            AbstractAnimation higher = anim.higherAnimation;
            AbstractAnimation lower = anim.lowerAnimation;
            AbstractAnimation lowerLower = lower.lowerAnimation;
            if (higher != null) {
                higher.lowerAnimation = lower;
            }
            if (lowerLower != null) {
                lowerLower.higherAnimation = anim;
            }
            lower.lowerAnimation = anim;
            lower.higherAnimation = higher;
            anim.lowerAnimation = lowerLower;
            anim.higherAnimation = lower;
            if (!moved) {
                top = lower;
                moved = true;
            }
        }
        if (moved) {
            AnimationInfo animInfo = getAnimationInfo(anim);
            Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
                                            animInfo.attributeNamespaceURI,
                                            animInfo.attributeLocalName);
            if (sandwich.animation == anim) {
                sandwich.animation = top;
            }
            if (anim.lowerAnimation == null) {
                sandwich.lowestAnimation = anim;
            }
        }
    }

    /**
     * Invoked to indicate that this timed element became inactive.
     *
     * @param anim the animation
     * @param isFrozen whether the element is frozen or not
     */
    public void toInactive(AbstractAnimation anim, boolean isFrozen) {
        anim.isActive = false;
        anim.isFrozen = isFrozen;
        anim.markDirty();
        if (!isFrozen) {
            anim.value = null;
            anim.beginTime = Float.NEGATIVE_INFINITY;
            moveToBottom(anim);
        }
    }

    /**
     * Invoked to indicate that this timed element has had its fill removed.
     */
    public void removeFill(AbstractAnimation anim) {
        anim.isActive = false;
        anim.isFrozen = false;
        anim.value = null;
        anim.markDirty();
        moveToBottom(anim);
    }

    /**
     * Moves the given animation to the top of the sandwich.
     */
    protected void moveToTop(AbstractAnimation anim) {
        AnimationInfo animInfo = getAnimationInfo(anim);
        Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
                                        animInfo.attributeNamespaceURI,
                                        animInfo.attributeLocalName);
        sandwich.shouldUpdate = true;
        if (anim.higherAnimation == null) {
            return;
        }
        if (anim.lowerAnimation == null) {
            sandwich.lowestAnimation = anim.higherAnimation;
        } else {
            anim.lowerAnimation.higherAnimation = anim.higherAnimation;
        }
        anim.higherAnimation.lowerAnimation = anim.lowerAnimation;
        if (sandwich.animation != null) {
            sandwich.animation.higherAnimation = anim;
        }
        anim.lowerAnimation = sandwich.animation;
        anim.higherAnimation = null;
        sandwich.animation = anim;
    }

    /**
     * Moves the given animation to the bottom of the sandwich.
     */
    protected void moveToBottom(AbstractAnimation anim) {
        if (anim.lowerAnimation == null) {
            return;
        }
        AnimationInfo animInfo = getAnimationInfo(anim);
        Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
                                        animInfo.attributeNamespaceURI,
                                        animInfo.attributeLocalName);
        AbstractAnimation nextLower = anim.lowerAnimation;
        nextLower.markDirty();
        anim.lowerAnimation.higherAnimation = anim.higherAnimation;
        if (anim.higherAnimation != null) {
            anim.higherAnimation.lowerAnimation = anim.lowerAnimation;
        } else {
            sandwich.animation = nextLower;
            sandwich.shouldUpdate = true;
        }
        sandwich.lowestAnimation.lowerAnimation = anim;
        anim.higherAnimation = sandwich.lowestAnimation;
        anim.lowerAnimation = null;
        sandwich.lowestAnimation = anim;
        if (sandwich.animation.isDirty) {
            sandwich.shouldUpdate = true;
        }
    }

    /**
     * Adds a {@link TimegraphListener} to the document.
     */
    public void addTimegraphListener(TimegraphListener l) {
        timedDocumentRoot.addTimegraphListener(l);
    }

    /**
     * Removes a {@link TimegraphListener} from the document.
     */
    public void removeTimegraphListener(TimegraphListener l) {
        timedDocumentRoot.removeTimegraphListener(l);
    }

    /**
     * Invoked to indicate that this timed element has been sampled at the given
     * time.
     *
     * @param anim the animation
     * @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
     */
    public void sampledAt(AbstractAnimation anim, float simpleTime,
                          float simpleDur, int repeatIteration) {
        anim.sampledAt(simpleTime, simpleDur, 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.
     */
    public void sampledLastValue(AbstractAnimation anim, int repeatIteration) {
        anim.sampledLastValue(repeatIteration);
    }

    /**
     * Creates a new returns a new TimedDocumentRoot object for the document.
     */
    protected abstract TimedDocumentRoot createDocumentRoot();

    /**
     * Listener class for changes to base values on a target element.
     */
    protected class Listener implements AnimationTargetListener {

        /**
         * Invoked to indicate that base value of the specified attribute
         * or property has changed.
         */
        public void baseValueChanged(AnimationTarget t, String ns, String ln,
                                     boolean isCSS) {
            short type = isCSS ? ANIM_TYPE_CSS : ANIM_TYPE_XML;
            Sandwich sandwich = getSandwich(t, type, ns, ln);
            sandwich.shouldUpdate = true;
            AbstractAnimation anim = sandwich.animation;
            while (anim.lowerAnimation != null) {
                anim = anim.lowerAnimation;
            }
            anim.markDirty();
        }
    }

    /**
     * Class to hold XML and CSS animations for a target element.
     */
    protected static class TargetInfo {

        /**
         * Map of XML attribute names to the corresponding {@link Sandwich}
         * objects.
         */
        public DoublyIndexedTable xmlAnimations = new DoublyIndexedTable();

        /**
         * Map of CSS attribute names to the corresponding {@link Sandwich}
         * objects.
         */
        public HashMap cssAnimations = new HashMap();

        /**
         * Map of other animation types to the corresponding {@link Sandwich}
         * objects.
         */
        public HashMap otherAnimations = new HashMap();
    }

    /**
     * Class to hold an animation sandwich for a particular attribute.
     */
    protected static class Sandwich {

        /**
         * The top-most animation in the sandwich.
         */
        public AbstractAnimation animation;

        /**
         * The bottom-most animation in the sandwich.
         */
        public AbstractAnimation lowestAnimation;

        /**
         * Whether the animation needs to have its value copied into the
         * document.
         */
        public boolean shouldUpdate;

        /**
         * Whether an {@link AnimationTargetListener} has been registered to
         * listen for changes to the base value.
         */
        public boolean listenerRegistered;
    }

    /**
     * Class to hold target information of an animation.
     */
    protected static class AnimationInfo {

        /**
         * The target of the animation.
         */
        public AnimationTarget target;

        /**
         * The type of animation.  Must be one of the <code>ANIM_TYPE_*</code>
         * constants defined in {@link AnimationEngine}.
         */
        public short type;

        /**
         * The namespace URI of the attribute to animate, if this is an XML
         * attribute animation.
         */
        public String attributeNamespaceURI;

        /**
         * The local name of the attribute or the name of the CSS property to
         * animate.
         */
        public String attributeLocalName;
    }
}
