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

class Playfield extends Raster {
  Raster background;          // background image
  Sprite sprite[];    // list of sprites on this playfield
  int numSprites;
  Rectangle invalidRgn[]; // invalid region to be repainted with background
  final int TRANSPARENT = Color.black.getRGB();
  int spritePixel[] = null;
  Sprite s = null;

  public Playfield(Image bgnd, int numSprites) {
    super(bgnd);
    background = new Raster(bgnd);
    sprite = new Sprite[numSprites];
    invalidRgn = new Rectangle[numSprites];
    for(int n=0; n<numSprites; n++)
      invalidRgn[n] = new Rectangle(0, 0, 1, 1);
    this.numSprites = numSprites;
  }


  public void addSprite(int i, Sprite s) {
    // effects:  adds a sprite to the playfield
    sprite[i] = s;

  }


  public void draw() {
    // effects:  draws each sprite on the background
    
    int i;
    int spriteX;
    int spriteY;
    int spriteWidth;
    int spriteHeight;
    int clipX;
    int clipY;

    // invalidate the previous sprite rectangles
    for(i=0; i<numSprites; i++)
        invalidateRect(invalidRgn[i]);
    
    // draw each sprite on playfield
    for(i=0; i<numSprites; i++) {
      s = sprite[i];
      spritePixel = s.pixel;

      // make local copies of dimensions and point so we don't have to dereference 
      // the member variables every loop iteration below.  Much faster (trust me, I tried both ways!)
      spriteX = s.x;
      spriteY = s.y;
      spriteWidth = s.width;
      spriteHeight = s.height;

      // get clipping dimensions (relative to sprite dimensions)
      clipX = (spriteX+spriteWidth < width ? spriteWidth : width-spriteX);
      clipY = (spriteY+spriteHeight < height ? spriteHeight : height-spriteY);

      // (DEBUG) System.err.println("clipX: "+ clipX + "clipY: " + clipY);
    
      // draw the actual pixels, accounting for clipping
      for(int x=(spriteX<0 ? (0-spriteX) : 0); x<clipX; x++) 
	for(int y=(spriteY<0 ? (0-spriteY) : 0); y<clipY; y++) {
	  if(spritePixel[y*spriteWidth+x] != TRANSPARENT) 
	    // (we only need to draw the non-transparent pixels)
	    setPixel(spritePixel[y*spriteWidth+x], x+spriteX, y+spriteY);
	 
	}
      
      // set the invalid region to the current sprite rectangles
      invalidRgn[i] = new Rectangle(new Point(spriteX, spriteY), 
				    new Dimension(clipX, clipY));
      
    }
  }

  private void invalidateRect(Rectangle r) {
    // effects:  "erases" playfield to background bitmap in the region defined by r
    for(int x=r.x; x<r.x+r.width; x++)
      for(int y=r.y; y<r.y+r.height; y++)
	setPixel(background.getPixel(x, y), x, y);
  }



}
