import java.awt.*;
import java.lang.*;

/**
  *This class implements the Puck that bounces around the 
  *PlayingField
  */
public class Puck extends MovablePiece{
	protected static int _radius = 20;
      protected static int _halfradius = 10;
	protected Dimension _playingFieldDimension;
	protected boolean _kaput;
	protected Paddle tmpPaddle;
	protected BrickPile tmpBrickPile;

	/**
	  *This default constructor provides the Puck with an initial velocity and location
	  *It also initializes the bounding box and the leadingPoint that is the
	  *corner of the bounding box in the direction of travel
	  *The Puck is not sited in any field nor does it have a bitmap
	  */
	public Puck(){
		super(null, new Point(150,90), new Velocity(8,225));
		_extent = new Dimension(_radius,_radius);
		_boundingBox = new Rectangle(_currentPosition,_extent);
		_leadingPoint = new Point(_currentPosition.x,_currentPosition.y);
		newLeadingPoint();
	}

	/**
	  *This constructor provides the Puck with an initial velocity and location
	  *It also initializes the bounding box and the leadingPoint that is the
	  *corner of the bounding box in the direction of travel
	  *The constructed Puck is in a PlayingField
	  */
	public Puck(PlayingField fieldPtr){
		//This sets the initial position of a new puck
		super(fieldPtr, new Point(150,90), new Velocity(8,225));
		_fieldPtr = fieldPtr;
		_theView = ((BricklesPlayingField)_fieldPtr).getView();
		tmpPaddle = _theView.getPaddle();
		tmpBrickPile = _theView.getBrickPile();
		_extent = new Dimension(_radius,_radius);
		_boundingBox = new Rectangle(_currentPosition,_extent);
		_leadingPoint = new Point(_currentPosition.x,_currentPosition.y);
		newLeadingPoint();
		_bitmap = _theView.getImage(_theView.getCodeBase(),"images/puck.gif");
		if(_bitmap == null)
			_theView.showStatus("BitMap not loaded");
		_kaput = false;
	}

	/**
	  *This method calculates which corner of the bounding box is in the
	  *direction of travel of the Puck 
	  */
	public void newLeadingPoint(){
		int direction = _currentVelocity.getDirection();
		if(direction >=0 && direction <90){
			_leadingPoint.y = _currentPosition.y;
			_leadingPoint.x = _currentPosition.x+_radius;
		}
		else
		if(direction >=90 && direction <180){
			_leadingPoint.x = _currentPosition.x;
			_leadingPoint.y = _currentPosition.y;
		}
		else
		if(direction >=180 && direction <270){
			_leadingPoint.y = _currentPosition.y + _radius;
			_leadingPoint.x = _currentPosition.x;
		}
		else
		if(direction >=270 && direction <360){
			_leadingPoint.x = _currentPosition.x+_radius;
			_leadingPoint.y = _currentPosition.y+_radius;
		}
	}


	/**
	  *This method calculates the new position of the Puck after a move
	  *post: the Puck's position has been updated and if the game has
	  *been won a dialog box has been displayed
	  *
	  */
	public void move(){
      	int hitbrickcount = 0;
      	GameOverDialog wonDialog;

        	if (_kaput == true)
           		_fieldPtr.deleted(this);  
        	_playingFieldDimension = _theView.getSize();
		_currentPosition.x = _currentPosition.x+ _currentVelocity.getSpeedX();
		_currentPosition.y = _currentPosition.y - _currentVelocity.getSpeedY();
		newLeadingPoint();
	
		for(int i=0;i<tmpBrickPile.getSize();i++){
        		Brick tmpBrick = tmpBrickPile.getBrickAt(i);
			     if (tmpBrick.isHit()){ 
          			hitbrickcount++;
			}
      	}    

		newLeadingPoint();
		_boundingBox = new Rectangle(_currentPosition,_extent);
   	
      	if (hitbrickcount == tmpBrickPile.getSize())
           		wonDialog = new GameOverDialog(new Frame(), "You Won!", false);
	}

	/**
	  *This is the general collision method that is invoked when an ArcadeGamePiece
	  *reports a collision
	  *@param aPiece the ArcadeGamePiece that has collided with the Puck
	  *@param aPoint where the collision occurred
	  */
	public void collideWith(ArcadeGamePiece aPiece, Point aPoint){
		aPiece.collideWithPuck(this,_leadingPoint);
		if(_kaput == true){
			_fieldPtr.deleted(this);
		}
	}

	/**
	  *This method handles the behavior of colliding with the Paddle
	  *@param aPaddle the Paddle that caused the collision
	  *@param aPoint the location of the collision
	  */
	public void collideWithPaddle(Paddle aPaddle,Point aPoint){
		aPaddle.reverseY();
	}

	/**
	  *Since the Puck cannot collide with itself, the behavior is a no-op
	  */
	public void collideWithPuck(Puck aPuck,Point aPoint){}

	/**
	  *This method is invoked when the Puck has been deleted
	  *This will usually be from hitting the floor
	  */
	public void deleted(){
		_kaput = true;
	}

}
