import java.awt.*;

/** The special method in ball, allInMotion, will set an arbitrary number of
balls into perpetual motion. Originally, I had used a vector to do this, but
that didn't work due to the limitations of the class. So, I read ahead and
learned arrays.  If you want to test the method painlessly, I included a
function  giveMeSomeBalls, which will make some balls in an array.
*/

/** An instance is a ball*/
public class Balljes239 extends Turtle {
  int radius;   //radius of the ball
  int vx;       //horizontal velocity
  int vy;       //vertical velocity
  
  
  /** Constructor: a ball with radius r starting at (x,y)
   *  at angle 0, velocity (vx, vy), and color c as given in Turtle.tColor */   
  public Balljes239(int x,int y,int sx,int sy,int r,int c){
    moveTo(x,y,0);
    tColor(c);
    fillCircle(r*2);
    radius = r;
    vx=sx;
    vy=sy;
  }
  
  /** Constructor: a ball with radius r starting at (x,y)
   *  at angle 0, velocity (vx, vy), and color c*/ 
  public Balljes239 (int x, int y, int sx, int sy, int r, Color c){
    moveTo(x,y,0);
    setColor(c);
    fillCircle(r*2);
    radius = r;
    vx=sx;
    vy=sy;
  }
  
  /** Constructor: a ball with radius r starting at the midpoint
   *  at angle 0, velocity (vx, vy), and color c as given in Turtle.tColor*/ 
    public Balljes239 (int sx, int sy, int r, int c){
    moveTo(250,250,0);
    tColor(c);
    fillCircle(r*2);
    radius = r;
    vx=sx;
    vy=sy;
  }
    
  
  /** Moves the ball once by turning it white it and drawing a new ball.*/
  public void moveBallOnce(){
    //makes the ball bounce off the sides of the window
    bounceOff();
    Color c=getColor();
    //Erase the ball
    eraseBall();
    //Draw a new ball
    redrawBall(c);
  }
  
  /** Draws a white ball in the current ball's place, effectively erasing it*/
  public void eraseBall(){
    setColor(Color.white);
    fillCircle(radius*2+2);   //For some reason, this greater radius is needed
  }
  
  /** Draws a new ball at the ball's incremented position*/
  public void redrawBall(Color c){
    moveTo(getX()+vx,getY()+vy,0);
    setColor(c);
    fillCircle(radius*2);
  }
  
  /**Adjusts the Ball's velocities so it will bounce off the walls*/
  public void bounceOff(){
    if((getY()+radius+vy >= 500 && vy > 0)   
         || (getY()-radius+vy <= 0 && vy <0))
      vy = -vy;
    if((getX()+radius+vx >= 500 && vx > 0) 
         || (getX()-radius+vx <= 0 && vx < 0))
      vx = -vx;
  }
  
  /** Sets the ball in motion perpetually.*/
  public void inMotion(){
    do {
      moveBallOnce();
      pause(100);
    } while(1==1);
  }
  
  /** Sets two balls in perpetual motion.
   * Ball b2 will overlap b1 if they cross one another.*/
  public static void inMotion(Balljes239 b1, Balljes239 b2){
    do{
      b1.bounceOff();
      b2.bounceOff();
      Color c1= b1.getColor();
      Color c2= b2.getColor();
      //Erases the balls at the same time, so when redrawn, they won't have white space
      b1.eraseBall();
      b2.eraseBall();
      //Redraws the balls.  b2 will always be on top.
      b1.redrawBall(c1);
      b2.redrawBall(c2);
      b1.pause(100);
      b2.pause(100);
    } while(1==1);
  }
  /**Returns the ball's radius*/
  public int getRadius(){
    return radius;
  }
  
  /**Returns the ball's vx (horizontal velocity)*/
  public int getVx(){
    return vx;
  }
  
  /**Returns the ball's vy (vertical velocity)*/
  public int getVy(){
    return vy;
  }
  
  /** Sets an arbitrary number of balls in perpetual motion.
   * Balls which come later the vector which gives the balls will always overlap earlier balls in the vector, should balls cross.
   Precondition: Array b is filled with at least one Ball object.*/
  public static void allInMotion(Balljes239[] b){
    Color[] c = new Color[b.length];       //vc stores the colors
    int i;                           //counting variable
    for(i=0;i<b.length;i++){     //i counts up to the number of Balls.
      c[i]= b[i].getColor();  //Stores the colors in vc.
    }
    do{
      for(i=0;i<b.length;i++)        //i counts    
        //Erases all the balls
        b[i].eraseBall();
      for(i=0;i<b.length;i++){
        //Ensures the balls will bounce
        b[i].bounceOff();        //i counts
        //Moves all the balls
        b[i].redrawBall(c[i]);
      }
      //pauses for a moment
      b[0].pause(100);
    } while(1==1);
  }
  
  /**Creates some balls and returns them in an array.
   * The user is encouraged to edit this method to their liking */
  public static Balljes239[] giveMeSomeBalls(){
    Balljes239[] b= new Balljes239[6];
    b[0]= new Balljes239(5,5,5,5,5,1);
    b[1]= new Balljes239(25,25,5,-5,5,2);
    b[2]= new Balljes239(50,50,-5,5,5,3);
    b[3]= new Balljes239(75,75,5,-5,5,4);
    b[4]= new Balljes239(100,100,1,5,10,5);
    b[5]= new Balljes239(300,300,5,-15,25,6);
    return b;
  }
  
}