// Travis Furrer
// 6.837 Project 1
// September 28, 1998

import java.awt.*;

public class Sprite extends Raster {
    //This variable stores the name of this sprite, which is used to
    //identify the sprite when the middle mouse button is clicked over
    //a pixel.
    public String name = "";

    //These variables are used to keep track of the frames of an
    //animated sprite.  The sequence is just an array whose entries
    //identify frames of the image.
    public int numFrames = 0, curFrame = 0;
    public int[] sequence = {0};

    //This is a raster in which all frames of the image are stored.
    //The sprite itself only stores one frame at a time, which makes
    //things easier from the playfield's point of view.
    Raster allFrames = null;

    //Sprite will start out at a random location (this is kind of rough
    //coding because I assume the applet area will be at least 300 by 300.
    public Point location = new Point((int)(Math.random()*300),
				      (int)(Math.random()*300)),
	destination = location;


    //Create a nameless, inanimate sprite.
    Sprite(Image img) {
	super(img);
	numFrames = 1;
	allFrames = new Raster(img);
    }


    //Create a sprite with the given number of frames and the given name.
    Sprite(Image img, String name, int numFrames) {
	allFrames = new Raster(img);
	this.name = name;
	this.numFrames = numFrames;
	sequence = new int[numFrames];
	int i;
	for (i=0;i<numFrames;i++) {
	    sequence[i] = i;
	}
	width = allFrames.width / numFrames;
	height = allFrames.height;
	pixel = new int[width*height];
	updateFrame();
    }


    //Create a sprite which will be displayed with the given frame
    //sequence, which can be of any length (but can only reference
    //valid frame values).
    Sprite(Image img, String name, int numFrames, int[] sequence) {
	this(img,name,numFrames);
	this.sequence = sequence;	
    }


    //Go to the next frame in the sequence.
    public void nextFrame() {
	curFrame = (curFrame + 1) % sequence.length;
    }


    //Copy the current frame into the sprite and update the position
    //of the sprite.
    public void updateFrame() {
	//Copy current frame into sprite.
	int i,j;
	for (i=0; i<width; i++) {
	    for (j=0; j<height; j++) {
		pixel[j*width+i] = allFrames.pixel[j*allFrames.width + 
						  (i+width*sequence[curFrame])];
	    }
	}

	//Increment position of sprite.
	if (location.x < destination.x) {
	    location.x += (destination.x - location.x)/2 + 0.5;
	} else if (location.x > destination.x) {
	    location.x -= (location.x - destination.x)/2 - 0.5;
	}
	if (location.y < destination.y) {
	    location.y += (destination.y - location.y)/2 + 0.5;
	} else if (location.y > destination.y) {
	    location.y -= (location.y - destination.y)/2 - 0.5;
	}
    }


    //This is the required method that is used to query the sprite as
    //to whether a given pixel is inside a non-tranparent part of it.
    public boolean includesPixel(int x, int y) {
	int xrel = x-location.x,
            yrel = y-location.y;
	if ((xrel > 0) &&
	    (yrel > 0) &&
	    (xrel < width) &&
	    (yrel < height) &&
	    (pixel[yrel*width+xrel] < 8388607)) {  //alpha channel is zero
	    return(true);
	}
	return(false);
    }
}
