/* Function prototypes originally from 6.837 website */

import Raster;
import Sprite;
import AnimatedSprite;
import java.awt.*;
import java.awt.image.*;

class Playfield {
  /* The Playfield represents an area to be displayed on the screen
   * and all the objects contained within it in the display,
   * including the background raster and a given number of Sprites.
   * The Playfield will respond to mouse clicks and display a given
   * number of Sprites on the background Raster.
   */
  Image background;           // background image
  int sprites;                // max number of sprites
  AnimatedSprite sprite[];    // list of sprites on this playfield
  boolean visible [];         // list of if the sprites are visible
  int bottom_sprite;          // the bottom sprite on the playfield
  int top_sprite;             // the top sprite on the playfield
  boolean sprite_added;       // has a sprite been added yet?

  /***** Constructors *****/

  public Playfield(Image bgnd, int numSprites)
  {
    background = bgnd;
    sprite = new AnimatedSprite [numSprites];
    visible = new boolean [numSprites];
    sprites = numSprites;
    bottom_sprite = 0;
    top_sprite = 0;
    sprite_added = false;
  }

  /***** Methods *****/
 
  /* Inserts a Sprite onto the top of the playfield if there is
   * room for an additional sprite.
   */
  public void addSprite(AnimatedSprite s)
  {
    // If we have just as many sprites as the max, then exit.
    if ((sprite_added) && (bottom_sprite == top_sprite))
      return;
    if ((top_sprite == 0) && (bottom_sprite == sprites))
      return;

    sprite [bottom_sprite] = s;
    visible [bottom_sprite] = true;
    bottom_sprite++;
    sprite_added = true;
    if (bottom_sprite > sprites)
      bottom_sprite = 0;
   }

  /* Removes the bottom Sprite from the playfield if there is one. */
  public void removeSprite ()
  {
    if (! sprite_added)
      return;
    if (bottom_sprite == top_sprite)
      return;

    bottom_sprite--;
    if (bottom_sprite < 0)
      bottom_sprite = sprites;

    if (bottom_sprite == top_sprite)
      sprite_added = false;
  }

  /* Returns an raster of all of the sprites in the image on the background. */
  public Raster toRaster ()
  {
    int i;
    Raster field;

    /* Create a raster image from the background. */
    field = new Raster (background);
    
    /* Now draw all of the visible sprites on the background. */
    for (i = bottom_sprite; i != top_sprite;)
	{
	  i--;
	  if (visible [i])
	    {
	      if (i < 0)
		i = (sprites - 1);
	      sprite [i].Draw (field);
	    }
	}

    /* Finally, return the full playfield in raster form. */
    return field;
  }

  /* Passes a mouseUp to whichever Sprite the mouse was over. */
  public void mouseUp (int x, int y)
  {
    int i;

    if (! sprite_added)
      return;

    for (i = top_sprite; i != bottom_sprite; i++)
      {
	if (sprite [i].hitTest (x, y))
	  {
	    /* We make the sprite invisible when hit. */
	    visible [i] = false;
	    sprite [i].mouseUp (x, y);
	    return;
	  }
	if (i == sprites)
	  i = -1;
      }
  }

  /* Passes a tick along to all of the animated sprites. */
  public void nextTick ()
  {
    int i;
    
    if (! sprite_added)
      return;

    for (i = top_sprite; i != bottom_sprite; i++)
      {
        sprite [i].nextTick ();
	if (i == sprites)
	  i = -1;
      }
  }

}
   
