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

/**
 *  Sprite, AnimatedSprite, and Playfield
 *
 *  @author Stephen J. Rhee
 *  @version 1.0
 */

class Sprite extends Raster {
  int x, y;

  public Sprite() {
  }

  public Sprite(int w, int h) {
    super(w, h);
    x = 0; y = 0;
  }

  public Sprite(Image image) { 
    super(image);
    x = 0; y = 0;
  }
}

class AnimatedSprite extends Sprite {
  Raster rasters;
  int frames;
  int state;

  public AnimatedSprite(Image image) {
    super(image);
    frames = 1; state = 1;
    rasters = new Raster(image);
  }

  public AnimatedSprite(Image images, int frames) {
    rasters = new Raster(images);
    x = 0; y = 0; state = 1;
    this.frames = frames;
    this.width = rasters.getWidth()/frames;
    this.height = rasters.getHeight();
    this.pixel = new int[this.width*this.height];
    for (int i = 0; i < this.getWidth(); i++)
      for (int j = 0; j < this.getHeight(); j++)
	this.setPixel(rasters.getPixel(i, j), i, j);
  }

  public void nextState() {
    this.state++;
    if (this.state > this.frames) this.state = 1;
    for (int i = 0; i < this.getWidth(); i++)
      for (int j = 0; j < this.getHeight(); j++)
	this.setPixel(rasters.getPixel(i+(state-1)*this.getWidth(), j), i, j);
  }
}

class Playfield extends Raster {
  Raster background;
  AnimatedSprite sprite[];
  int n;

  public Playfield(Image bgnd, int numSprites) {
    super(bgnd);
    n = numSprites;
    sprite = new AnimatedSprite[n];
    background = new Raster(bgnd);
  }

  public void addSprite(int i, AnimatedSprite s) {
    sprite[i] = s;
  }

  public void Draw() {
    for (int i = 0; i < width; i++)
      for (int j = 0; j < height; j++)
	pixel[j*width+i] = background.pixel[j*background.getWidth()+i];
    for (int k = 0; k < n; k++)
      for (int i = 0; i < sprite[k].getWidth(); i++)
	for (int j = 0; j < sprite[k].getHeight(); j++)
	  if (((sprite[k].x+i) < background.getWidth()) &&
	      ((sprite[k].x+i) >= 0) && ((sprite[k].y+j) >= 0) &&
	      ((sprite[k].y+j) < background.getHeight()))
	    if ((sprite[k].pixel[j*sprite[k].getWidth()+i]) < 0)
	      this.setPixel(sprite[k].getPixel(i, j),
			    sprite[k].x+i, sprite[k].y+j);
  }

  public void moveSprite(int l, int ox, int oy) {
    for (int i = 0; i < sprite[l].getWidth(); i++)
      for (int j = 0; j < sprite[l].getHeight(); j++)
	if ((ox+i >= 0) && (ox+i < background.getWidth()) &&
	    (oy+j >= 0) && (oy+j < background.getHeight()))
	  pixel[(oy+j)*width+ox+i] = 
	    background.pixel[(oy+j)*background.getWidth()+ox+i];
    for (int k = 0; k < n; k++)
      for (int i = 0; i < sprite[k].getWidth(); i++)
	for (int j = 0; j < sprite[k].getHeight(); j++)
	  if (((sprite[k].x+i) < background.getWidth()) &&
	      ((sprite[k].x+i) >= 0) && ((sprite[k].y+j) >= 0) &&
	      ((sprite[k].y+j) < background.getHeight()))
	    if ((sprite[k].pixel[j*sprite[k].getWidth()+i]) < 0)
	      this.setPixel(sprite[k].getPixel(i, j),
			    sprite[k].x+i, sprite[k].y+j);
  }

  public int isSprite(int x, int y) {
    int found = -1;
    int found2 = -1;
    for (int k = 0; k < n; k++) {
      if ((x>=sprite[k].x) && (x<sprite[k].x+sprite[k].getWidth()) &&
	  (y>=sprite[k].y) && (y<sprite[k].y+sprite[k].getHeight()))
	if (sprite[k].pixel[(y-sprite[k].y)*sprite[k].getWidth()+x-sprite[k].x]
	    < 0)
	  found = k;
	else found2 = -2;
    }
    if (found != -1)
      return found;
    else return found2;
  }
}
