package breakout;

import cs101.awt.*;
import cs101.io.*;
import cs101.lang.*;
import java.awt.Point;
import java.awt.Color;
import java.awt.Graphics;

/*a player's own ball instantiated when the game begins
 *multiple balls created when a special Brick100 is hit
 *animate*/
public class ClassicBall implements BreakOutBall, Animate
{
	ScreenCanvas screen;
	BrickRepository brickrepos;
	BallRepository ballrepos;
	Point center = new Point(0,0);
	public double radius=6.0, xVel, yVel;
	private AnimatorThread anim;
	public int ballType;
	
	//constructor
	public ClassicBall (ScreenCanvas sc, BrickRepository brickrepos, 
							BallRepository ballrepos, int centerX,
							int centerY, double xVel, double yVel, 
							int ballType)
	{
		this.screen = sc;
		this.brickrepos = brickrepos;
		this.ballrepos = ballrepos;
		this.xVel = xVel;
		this.yVel = yVel;
		this.ballType = ballType;    //tells the ball if it can be deleted or not
		this.center.x = centerX;	
		this.center.y = centerY;    
		
		this.anim = new AnimatorThread(this,0,10); //allows the ball to become animate
		anim.startExecution();
	
	}
	
	
	public Point getCenter()
	{
		return this.center;
	}
	
	public double getRadius()
	{
		return this.radius;
	}
	
	public double getXvelocity()
	{
		return this.xVel;
	}
	
	public double getYvelocity()
	{
		return this.yVel;
	}
	
	public void changeXvelocity(double xVel)
	{
		this.xVel = xVel;
	}
	
	public void changeYvelocity(double yVel)
	{
		this.yVel = yVel;
	}
	
	
	//called by the ballrepository's paint method
	public void paintClassicBall(Graphics g)
	{
		double cornerx = this.center.getX() - radius;
		double cornery = this.center.getY() - radius;
		
		if (ballType == (Constants.KEEP_BALL))
		{
			this.screen.connection.send(this.center.x); //sent xCenter 
			this.screen.connection.send(this.center.y); //sent yCenter
		}
			
		g.setColor(Color.red.brighter());
		g.fillOval((int)cornerx, (int)cornery, (int)(2*radius), (int)(2*radius));
	}
	
	//moves the ball when game not paused, bouncing off the bricks and the walls
	public void act()
	{
			
		if (!this.screen.getPause())
		{
			if ( (this.center.x+this.radius) >= (this.screen.xMax) ) //hit right edge
			{
				this.xVel =  -Math.abs(this.xVel);
			}
			else if ( (this.center.x-this.radius) <= (this.screen.getMinX()) ) //hit left edge
			{
				this.xVel =  Math.abs(this.xVel);
			}
			else if ( (this.center.y+this.radius) >= (this.screen.getMaxY()) ) //hits bottom and sleeps for millis seconds
			{
				if (this.ballType == Constants.DEL_BALL)
				{
					this.ballrepos.deleteBall(this);
				}
				else{  //sleeps the ball if its a KEEP_BALL when it hits the bottom
					long millis = 2000; // delay for missing the paddle
					try
					{ 
						
						this.center.x = (this.screen.CanvasPaddleUL.x+this.screen.CanvasPaddleLR.x) / 2;
						this.center.y = this.screen.yMax - 32;
						this.screen.repaint();
						this.anim.sleep(millis);
						
					}
					catch (InterruptedException ie)
					{
						System.out.println("Exception occurred..in sleep method");
					}
					
					
					this.yVel =  -Math.abs(this.yVel);
				}
			}
			else if ( (this.center.y-this.radius) <= (this.screen.getMinY()) ) //hits top of screen
			{
				this.yVel =  Math.abs(this.yVel);
				
			}
			
			else if ( (this.center.y-this.radius) < 140) //checks to see if ball has hit bricks
														// only if in range of bricks
			{
				this.brickrepos.checkHitBrick(this);
				
			}
			
			else if ( (this.center.y+this.radius) > 460) //checks if ball has hit paddle if in 
															//range of paddle
			{
				this.screen.checkHitPaddle(this);
			}
			
			this.center.x += (this.xVel);//changes direction of xvelocity
			this.center.y += (this.yVel);//changes yvelocity direction
			
			this.screen.repaint();
			
			return;
		}	

	}
}