/* Function prototypes originally from 6.837 website */

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

class Sprite extends Raster {
  /* A Sprite represents a graphical object. It can be positioned
   * anywhere on a playfield, and has a given width, height, and location
   * within a playfield.
   * A Sprite extends a Raster object, and so it has a raster Image
   * associated with it.
   */

  int x, y;           // current position of sprite on playfield
  /* The Raster object contains the width, height, and pixel array. */
  
  /***** Constructors *****/

  public Sprite ()
  {
  }

  /* This creates a new sprite based on a given image. */
  public Sprite (Image image)
  {
    super (image);

    /* We might as well initialize the location, even though it's
     * probably not going to end up at (0,0) when drawn.
     */
    x = 0;
    y = 0;
  }

  /***** Methods *****/

  /* Sets x-coord of sprite. */
  /* NOTE! Does not perform bounds-checking...that's why we clip. */
  public void setX (int new_x)
  {
    x = new_x;
  }

  /* Sets y-coord of sprite. */
  /* NOTE! Does not perform bounds-checking...that's why we clip. */
  public void setY (int new_y)
  {
    y = new_y;
  }

  /* Sets both coords of sprite. */
  /* NOTE! Does not perform bounds-checking...that's why we clip. */
  public void setCoordinates (int new_x, int new_y)
  {
    x = new_x;
    y = new_y;
  }
    
  /* This method checks if the non-transparent part of the Sprite
   * is currently over a given point on the Sprite's background.
    */
  public boolean hitTest (int test_x, int test_y)
  {
    int p;

    /* Make sure the point's inside the Sprite. */
    if ((test_x < x) || (test_x > (x + width)))
      return false;
    if ((test_y < y) || (test_y > (y + height)))
      return false;
    
    /* Now make sure that the pixel it's over is not transparent. */
    p = getPixel ((test_x - x), (test_y - y));
    if ((p & 0x00ffffff) == 0x00ffffff)
      return false;

    return true;
  }

  /* This is a mouse handler that is called when a mouseUp event
   * occurs over a non-transparent part of this sprite.
   */
  public void mouseUp (int up_x, int up_y)
  {
  }


  /* This method draws the Sprite on a given background at a location
   * specified by this.x and this.y. Transparent pixels in the Sprite
   * will show the bgnd through, and pixels in the Sprite that are
   * outside the bgnd are clipped.
   */
  public void Draw (Raster bgnd)
  {
    int bg_x_min, bg_x_max, bg_y_min, bg_y_max;
    int bg_x, bg_y, spr_x, spr_y;
    int pixel;
    
    /* Determine the clipping rectangle for the bgnd. */

    /* Horizontal Minimum clipping. */
    if (x < 0) 
      {
	bg_x_min = 0;
	spr_x = bg_x_min - x;
      }
    else
      {
	bg_x_min = x;
	spr_x = 0;
      }

    /* Vertical Minimum clipping. */
    if (y < 0)
      {
	bg_y_min = 0;
	spr_y = bg_y_min - y;
      }
    else
      {
	bg_y_min = y;
	spr_y = 0;
      }

    /* Horizontal Maximum clipping. */
    if (x + width > bgnd.width)
      bg_x_max = bgnd.width;
    else
      bg_x_max = x + width;

    /* Vertical Maximum clipping. */
    if (y + height > bgnd.height)
      bg_y_max = bgnd.height;
    else
      bg_y_max = y + height;
      
    /* Loop through all the rows in this and put the
     * pixels on the bgnd.
     */
    int start_x = spr_x;
    for (bg_y = bg_y_min; bg_y < bg_y_max; bg_y++)
      {
	/* Loop through the pixels in each row. */
	for (bg_x = bg_x_min; bg_x < bg_x_max; bg_x++)
	  {
	    pixel = getPixel (spr_x, spr_y);
	    if ((pixel & 0x00ffffff) != 0x00ffffff)
	      bgnd.setPixel (pixel, bg_x, bg_y);
	    spr_x++;
	  }
	spr_x = start_x;;
	spr_y++;
      }
  }
}


