import java.util.*;
import java.awt.*;

/**Interesting feature is in Ball.java.
 * Makes n balls starting at center moving at a random speed between -s/2 
 * and s/2. Color randomly changes each time a ball is moved:
 * public static void myInMotion(int s,int n), 
 * Try Ballnbc5saf37.myInMotion(50,20); */

public class Ballnbc5saf37 extends Turtle{
  private int radius; // gives radius of ball
  private int vX; //Acceleration when ball is moved (xComponent)
  private int vY;//Acceleration when ball is moved (yComponent
  
  /** 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 Ballnbc5saf37(int x, int y, int vx, int vy, int r, int c){
    moveTo(x,y, 0);
    radius= r;
    vX= vx;
    vY= vy;
    tColor(c);
    fillCircle(2*r);
  }
  /**Constructor: a ball with radius r starting at (x,y)
   *  at angle 0, velocity (vx, vy), and Color c */
  public Ballnbc5saf37 (int x, int y, int vx, int vy, int r, Color c) {
    moveTo(x,y, 0);
    radius= r;
    vX= vx;
    vY= vy;
    setColor(c);
    fillCircle(2*r);  }
  
  /** 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 Ballnbc5saf37 (int vx, int vy, int r, int c) {
    super();
    vX= vx;
    vY= vy;
    radius= r;
    tColor(c);
    
  }
  /**Move the ball once based off of its acceleration*/
  public void moveBallOnce() {
    Color save= getColor(); // Color that the ball was before moving
    tColor(12);
    fillCircle(2*getRadius());
    // the new x value to which the turtle will be moved
    int newX= getX(); // local variable that holds the x position the ball will move to by the end of the function
    // the new y value to which the turtle will be moved     
    int newY= getY(); // local variable that holds the y position the ball will move to by the end of the function
    int k=0; // variable used to make progress towards termination of loop
    /**inv: newX contains the new x position of the ball if velocity were equal to k*/
    while (k<Math.abs(vX)){
      if (newX - getRadius()<=0 ){ // ball is colliding with left edge
        vX=Math.abs(vX);
      }
      if (newX+getRadius()>= getWidth()){ // ball is colliding with right edge
        vX= (-1)*Math.abs(vX);
      }
      if (vX>0){ //  ball is moving to right
        newX= newX+1;
      }
      else{ //  ball is moving to left
        newX= newX-1;
      }
      k=k+1;
    }
    k=0;
    /**Inv: newY contains the new y position of the ball if velocity were equal to k*/
    while (k<Math.abs(vY)) {
      if (newY - getRadius()<=0){ // ball is colliding with top edge
        vY=Math.abs(vY);
      }
      if (newY+getRadius()>= getHeight()){// ball is colliding with bottom edge
        vY=-1*(Math.abs(vY));
      }
      if (vY>0){ // ball is moving down
        newY= newY+1;
      }
      else{// ball is moving up
        newY= newY-1;
      }
      k= k+1;
    }
    
    moveTo(newX, newY ,0);
    setColor(save);
    fillCircle(2*getRadius());
  }
  
  /**make ball move at its velocity forever(or until stopped by closing program, reseting interactions 
   * or destroying computer)*/
  public void inMotion(){
    /**invarient: true is true*/
    while (true){
      moveBallOnce();
      pause(100);
    }
  }
  /**make 2 balls b1, b2 move at their velocity forever(or until stopped by closing program, reseting interactions 
   * or destroying computer)*/
  public static void inMotion(Ballnbc5saf37 b1, Ballnbc5saf37 b2){
    /**inv: true is true*/
    while (true){
      b1.moveBallOnce();
      b2.moveBallOnce();
      b1.pause(100);
    }
  }
  /**Makes n balls starting at center moving at a random speed between -s/2 and s/2. Color randomly changes each 
   * time a ball is moved*/
  public static void myInMotion(int s,int n){
    /**inv: true is true*/
    Vector v= new Vector(1,1); // Vector to contain all of the balls that we will create
    int k=0; // local variable to hold index of vector v to add the next ball to
    while(k<n){
      v.add(new Ballnbc5saf37((int)(s*Math.random()-s/2),(int)(s*Math.random()-s/2),16,0));
      k= k+1;
    }
    Ballnbc5saf37 b1= (Ballnbc5saf37)v.get(0); //  The ball that we are going to manipulate next
    /**inv: true is true*/
    while (true){
      int p=0; // the variable used to bring the loop to termination
      /**inv: ball that will be drawn next is v[p]*/
      while (p<v.size()){
        b1= (Ballnbc5saf37) v.get(p);
        b1.moveBallOnce();
        b1.tColor((int)(13*Math.random())); 
        p= p+1;
      }
      b1.pause(100);
    }
  }
  
  /**Returns the radius*/
  public int getRadius (){
    return radius;
  }
  /**Returns Acceleration when ball is moved (xComponent)*/
  public int getVX(){
    return vX;
  }
  /**Returns Acceleration when ball is moved (yComponent)*/
  public int getVY(){
    return vY;
  }
}