001    /*
002     * TrackManager.java
003     *
004     *  The Salamander Project - 2D and 3D graphics libraries in Java
005     *  Copyright (C) 2004 Mark McKay
006     *
007     *  This library is free software; you can redistribute it and/or
008     *  modify it under the terms of the GNU Lesser General Public
009     *  License as published by the Free Software Foundation; either
010     *  version 2.1 of the License, or (at your option) any later version.
011     *
012     *  This library is distributed in the hope that it will be useful,
013     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
014     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     *  Lesser General Public License for more details.
016     *
017     *  You should have received a copy of the GNU Lesser General Public
018     *  License along with this library; if not, write to the Free Software
019     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020     *
021     *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
022     *  projects can be found at http://www.kitfox.com
023     *
024     * Created on August 15, 2004, 11:34 PM
025     */
026    
027    package com.kitfox.svg.animation;
028    
029    import java.util.*;
030    
031    import com.kitfox.svg.*;
032    import java.io.Serializable;
033    
034    /**
035     * Every element contains tracks, which manage the animation.  There is one track
036     * for every parameter with animation, and each track in turn is composed of
037     * many events.
038     *
039     * @author Mark McKay
040     * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
041     */
042    public class TrackManager implements Serializable
043    {
044        public static final long serialVersionUID = 0;
045        
046        static class TrackKey
047        {
048            String name;
049            int type;
050            
051            TrackKey(AnimationElement base)
052            {
053                this(base.getAttribName(), base.getAttribType());
054            }
055            
056            TrackKey(String name, int type)
057            {
058                this.name = name;
059                this.type = type;
060            }
061            
062            public int hashCode()
063            {
064                int hash = name == null ? 0 : name.hashCode();
065                hash = hash * 97 + type;
066                return hash;
067            }
068    
069            public boolean equals(Object obj) 
070            {
071                if (!(obj instanceof TrackKey)) return false;
072                TrackKey key = (TrackKey)obj;
073                return key.type == type && key.name.equals(name);
074            }
075        }
076        
077        HashMap tracks = new HashMap();
078        
079        /** Creates a new instance of TrackManager */
080        public TrackManager()
081        {
082        }
083        
084        /**
085         * Adds a new animation element to this track
086         */
087        public void addTrackElement(AnimationElement element) throws SVGElementException
088        {
089            TrackKey key = new TrackKey(element);
090            
091            TrackBase track = (TrackBase)tracks.get(key);
092            
093            if (track == null)
094            {
095                //Create a track for this element
096                if (element instanceof Animate)
097                {
098                    switch (((Animate)element).getDataType())
099                    {
100                        case Animate.DT_REAL:
101                            track = new TrackDouble(element);
102                            break;
103                        case Animate.DT_COLOR:
104                            track = new TrackColor(element);
105                            break;
106                        case Animate.DT_PATH:
107                            track = new TrackPath(element);
108                            break;
109                        default:
110                            throw new RuntimeException("");
111                    }
112                }
113                else if (element instanceof AnimateColor)
114                {
115                    track = new TrackColor(element);
116                }
117                else if (element instanceof AnimateTransform || element instanceof AnimateMotion)
118                {
119                    track = new TrackTransform(element);
120                }
121                
122                tracks.put(key, track);
123            }
124      
125            track.addElement(element);
126        }
127        
128        public TrackBase getTrack(String name, int type)
129        {
130            //Handle AUTO, which will match either CSS or XML (in that order)
131            if (type == AnimationElement.AT_AUTO)
132            {
133                TrackBase t = getTrack(name, AnimationElement.AT_CSS);
134                if (t != null) return t;
135                t = getTrack(name, AnimationElement.AT_XML);
136                if (t != null) return t;
137                return null;
138            }
139            
140            //Get requested attribute
141            TrackKey key = new TrackKey(name, type);
142            TrackBase t = (TrackBase)tracks.get(key);
143            if (t != null) return t;
144            
145            //If that didn't exist, see if one exists of type AUTO
146            key = new TrackKey(name, AnimationElement.AT_AUTO);
147            return (TrackBase)tracks.get(key);
148        }
149        
150        public int getNumTracks()
151        {
152            return tracks.size();
153        }
154        
155        public Iterator iterator()
156        {
157            return tracks.values().iterator();
158        }
159    }