// Sprite class
//
// Sprites are objects which can be displayed
//

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


/////////////////////////////////////////////////////////////////
abstract class SquareSprite {
	boolean hasMaxXSpeed = false;
	boolean hasMaxYSpeed = false;

	boolean collideTop, collideBottom, 
		collideLeft, collideRight;
	int boundaryTop, boundaryBottom, 
	    boundaryLeft, boundaryRight;
	double bounceTop, bounceBottom, 
	       bounceLeft, bounceRight;

	double xPos,yPos;
	int xSize, ySize;
	double xSpeed, ySpeed;
	double maxXSpeed, maxYSpeed;


	public String debugMessage;

	// abstract methods:
	abstract void paint (Graphics g, ImageObserver a);

	//two line segments DONT overlap if 
	//the coordinates of one are both less than
	//the least of the two coordinates of the other
	//or if both the coordinates of the one are greater
	//than the greatest of the other
	//otherwise, they overlap-- think about it.

	boolean overlap1D(int min1, int max1, int min2, int max2){
		if((min1 < min2 && max1 < min2) ||
		   (min1 > max2 && max1 > max2)) {
			return false;
		} 
		return true;
	}


	//
	//two rectangles overlap if they 
	//overlap both horizontally and vertically

	public boolean overlap(int left,int top,
				 int width,int height) {
		int xPosInt = new Double(xPos).intValue();
		int yPosInt = new Double(yPos).intValue();
		if(overlap1D(xPosInt,xPosInt+xSize,left,left+width) &&
		   overlap1D(yPosInt,yPosInt+ySize,top,top+height))
			return true;
		return false;


	}


	public boolean overlap(SquareSprite other) {
		int left = other.getXPos();
		int top = other.getYPos();
		int width = other.getXSize();
		int height = other.getYSize();
		int xPosInt = new Double(xPos).intValue();
		int yPosInt = new Double(yPos).intValue();
		if(overlap1D(xPosInt,xPosInt+xSize,left,left+width) &&
		   overlap1D(yPosInt,yPosInt+ySize,top,top+height))
			return true;
		return false;


	}




    	public void updatePosition(){
		xPos += xSpeed;
		checkHorizCollides();
		yPos += ySpeed;
		checkVertCollides();
		throttle();
	}
  

	
    	public void setXSpeed(double X){ xSpeed = X; throttle();}
    	public void changeXSpeed(double X){ xSpeed += X; throttle();}
    	public void setYSpeed(double Y){ySpeed = Y;  throttle();}
    	public void changeYSpeed(double Y){ySpeed += Y;  throttle();}

    	public void setXPos(int X){ xPos = X;}
    	public void setYPos(int Y){ yPos = Y;}


    	public int getXSize(){ return xSize;}
    	public int getYSize(){ return ySize;}
    	public int getXPos(){ return (int)xPos;}
    	public int getYPos(){ return (int)yPos;}
    	public double getXSpeed(){ return xSpeed;}
    	public double getYSpeed(){ return ySpeed;}


	public void setMaxXSpeed(double speed){
		hasMaxXSpeed = true;		
		maxXSpeed = speed;
	}

	public void setMaxYSpeed(double speed){
		hasMaxYSpeed = true;		
		maxYSpeed = speed;
	}


	private void throttle(){
		if(hasMaxXSpeed){
			if(abs(xSpeed) > maxXSpeed){
				if(xSpeed > 0.0) {
					xSpeed = maxXSpeed;
				} else {
					xSpeed = -1.0 * maxXSpeed;
				}

			}
		}


		if(hasMaxYSpeed){
			if(abs(ySpeed) > maxYSpeed){
				if(ySpeed > 0.0) {
					ySpeed = maxYSpeed;
				} else {
					ySpeed = -1.0 * maxYSpeed;
				}

			}
		}



	}


	double abs(double val){
		if(val > 0) return val;
		return -1.0 * val;
	}



	private boolean checkHorizCollides(){
		if(collideLeft) {
			if(xPos < boundaryLeft){
				xPos = boundaryLeft;
				xSpeed = xSpeed * -1.0 * bounceLeft;
				return true;
			}
		}		
		if(collideRight) {
			if(xPos+xSize > boundaryRight){
				xPos = boundaryRight-xSize;
				xSpeed = xSpeed * -1.0 * bounceRight;
				return true;
			}
		}		
		return false;

	}


	private boolean checkVertCollides(){
	
		if(collideTop) {
			if(yPos < boundaryTop){
				yPos = boundaryTop;
				ySpeed = ySpeed * -1.0 * bounceTop;
				return true;
			}
		}		
		if(collideBottom) {

			if(yPos+ySize > boundaryBottom){

				yPos = boundaryBottom-ySize;
				ySpeed = ySpeed * -1.0 * bounceBottom;
				return true;
			}
		}		
		return false;

	}

	public void setTopCollide(double val,int where){ 
		collideTop = true; 
		bounceTop = val;
		boundaryTop = where;
	}
	public void setBottomCollide(double val,int where){ 
		collideBottom = true; 
		bounceBottom = val;
		boundaryBottom = where;
	}
	public void setLeftCollide(double val,int where){ 
		collideLeft = true; 
		bounceLeft = val;
		boundaryLeft = where;
	}
	public void setRightCollide(double val,int where){ 
		collideRight = true; 
		bounceRight = val;
		boundaryRight = where;
	}




}



