import java.util.Vector;

/** The PlayField class is a type of Raster that is designed to hold a
    set of Sprites.  It registers itself to listen to each Sprite's
    actions, tracking when Sprites leave the field so that it knows to
    stop updating them.  It tracks time through a tick() method that
    is supposed to be called on each time step.
*/
public class PlayField extends Raster implements SpriteListener {

  private Vector sprites;
  
  /** PlayField constructor for playfield of size w * h
    */
  public PlayField(int w, int h) {
    super(w, h);
    sprites = new Vector();
  }
  
  /** Adds Sprite to this playfield.
      registers this playfield as a listener of this sprite's
      actions. 
    */
  public void addSprite(Sprite s) {
    sprites.addElement(s);
    s.addSpriteListener(this);
  }
  
  /** tick method for updating Sprites on playfield.
      Clears the background for each sprite, then
      calls tick on each Sprite on the field.
  */
  public void tick(Raster bufferRaster) {
    for (int i=0; i< sprites.size(); i++) {
      Sprite f = (Sprite) sprites.elementAt(i);
      // System.out.println("stepping " + f);
      f.clear(bufferRaster, this);
    }
    for (int i=0; i< sprites.size(); i++) {
      Sprite f = (Sprite) sprites.elementAt(i);
      // System.out.println("stepping " + f);
      f.tick();
      f.draw(bufferRaster);
    }      
  }
  
  /** SpriteListener locationChanged method.
      Currently checks if the Sprite is moving below and to the right
      of the lower-right-hand corner of the playfield, in which case
      it removes the Sprite from the playfield entirely.
      @see SpriteListener#locationChanged
  */
  public void locationChanged(Sprite s, Point oldPoint, Point newPoint) {
    if (newPoint.getX() > getWidth() &&
	newPoint.getY() > getHeight()) {
      sprites.removeElement(s);
      s.removeSpriteListener(this);
      // System.out.println("Removed " + s + " from PlayField.");
    }
  }

  /** Touch method for PlayField.
      Designed to handle user interaction with the playfield.
      This implementation calls touch(x,y) on all the sprites
      (modifying x and y for each sprite's relative location) and if
      any number of the sprites returned true, returns true itself.
      Returns false otherwise.
  */
  public boolean touch(int x, int y) {
    boolean foundOne = false;
    for (int i=0; i<sprites.size(); i++) {
      Sprite s = (Sprite) sprites.elementAt(i);
      if (s.touch(x - s.getLocation().getX(),
		  y - s.getLocation().getY()))
	foundOne = true;
    }
    return foundOne;
  }

}
