import java.awt.*;
import java.util.*;

/** class AnimatedSprite extends Sprite
  *
  * class AnimatedSprite implements a multi-frame Sprite, which (much like
  * a Sprite, in fact exactly like a Sprite) may be drawn onto a Raster.
  *
  * The API is essentially the one suggested in lecture.  For a given
  * set of images, there are a number of 'tracks', orders in which to
  * run through the frames.
  *
  * I used a Hashtable for tracking tracks, so I changed the track naming
  * to strings from ints, so they're easier to follow.  Further, since I use
  * Vectors instead of Arrays, some interfaces are signficantly simpler. 
  */
class AnimatedSprite extends Sprite {
  Raster[] rasters;
  Hashtable tracks = new Hashtable();
  String currtrack = null;
  int currstate = 0;
  int currtick = 0;
  FrameInfo currframe;

  // Create a new AnimatedSprite; taking in an array of images.
  // We probably should expect these images to all be the same size.
  public AnimatedSprite(Image[] images) {
    // Init our internal raster to frame 0
    super(images[0]);

    rasters = new Raster[images.length];
    for (int i=0; i<images.length; i++)
      rasters[i] = new Raster(images[i]);
  }

  // AnimatedSprite.addState -- Add frames to a track for this sprite
  public void addState(String track, int frame, int ticks, int dx, int dy) {
    // Fetch track from hashtable, create a new one if it odesn't exist.
    Vector ctrack = (Vector)tracks.get(track);
    if (ctrack == null) ctrack = new Vector();
    
    // Add new frame to end of track, return to hashtable
    FrameInfo newframe = new FrameInfo(frame, ticks, dx, dy);
    ctrack.addElement(newframe);
    tracks.put(track, ctrack);
  }

  // The superclass impl. is sufficient.
  // public void Draw(Raster bgnd);

  // AnimatedSprite.Tick -- Process a tick, Advance to the next image 
  // on this track if it's time. (used to be nextState)
  public void Tick() {
    // Fetch the current track
    Vector ctrack = (Vector)tracks.get(currtrack);
    if (ctrack == null) return;

    currtick++;
    if (currtick == currframe.ticks) {
      // Fetch the next frame in this track
      currstate++;
      currtick = 0;
      setPos(x+currframe.dx, y+currframe.dy);
      if (currstate == ctrack.size()) currstate=0;
      currframe = (FrameInfo)ctrack.elementAt(currstate);
      pixel = rasters[currframe.frame].pixel;
    }

    // Apply sprite velocity
    setPos(x+xvel, y+yvel);
  }

  // AnimatedSprite.setTrack -- select new animation track for this sprite
  public void setTrack(String track) {
    currtrack = track;
    currstate = 0;
    currtick = 0;

    // Fetch the current track and frame
    Vector ctrack = (Vector)tracks.get(currtrack);
    if (ctrack == null) return;
    currframe = (FrameInfo)ctrack.elementAt(currstate);
    pixel = rasters[currframe.frame].pixel;
  }
}
