import java.awt.*;
import java.util.Vector;

/** The call

     Balldac69.coolThings(20,30,  -40, 70, 8);
     
    starts two balls going with velocities (20,30) and (-40,70),
    both colored 8. When the balls collide, they split into
    smaller balls.
    
    */
public class Balldac69 extends Turtle {
  private int radius;
  private int vx;
  private int vy;
  
  
  /*turtle starts at (x, y), 
   * has acceleration (vx, vy), 
   * has radius r, 
   * and is drawn with color c*/
  public Balldac69(int x,int y,int vx,int vy,int r,Color c) {
    setColor(c);
    moveTo(x,y,0);
    radius= r;
    fillCircle(2*r);
    this.vx= vx;
    this.vy= vy;
  }
  
  /** Constructor: a ball with radius r starting at midpoint of the window
     *  at angle 0, velocity (vx, vy), and color black */
  public Balldac69(int vx,int vy,int r) {
    this(width/2,height/2,vx,vy,r,Color.black);
  }
  
  /** 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 Balldac69 (int x, int y, int vx, int vy, int r, int c) {
    tColor(c);
    moveTo(x,y,0);
    radius= r;
    fillCircle(2*r);
    this.vx= vx;
    this.vy= vy;
  }

/** 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 Balldac69 (int vx, int vy, int r, int c) {
    this(width/2,height/2,vx,vy,r,c);
  }
  
  //returns radius
  public int getRadius() {
    return radius;
  }
  
  //returns x-coord velocity
  public int getXVelocity() {
    return vx;
  }
  
  //returns y-coord velocity
  public int getYVelocity() {
    return vy;
  }
  
  /*erases the current position,
   * moves the position based on vx and vy,
   * and redraws it
   * in addition, it tests for collisions with walls*/
  public void moveBallOnce() {
 
    Color save= getColor();
    setColor(Color.white);
    fillCircle(2*radius);
    moveTo(getX()+vx,getY()+vy,0);
    setColor(save);
    fillCircle(2*radius);
    if(getX()+radius > getWidth() && vx >= 0)
      vx= -vx;
    if(getX()-radius < 0 && vx <= 0)
      vx= -vx;
    if(getY()+radius > getHeight() && vy >= 0)
      vy= -vy;
    if(getY()-radius < 0 && vy <= 0)
      vy= -vy;
  }
  
  /*erases the current position,
   * moves the position based on vx and vy,
   * and redraws it
   * in addition, it tests for collisions with walls
   * also adjusts motion and one collision based on gravity*/
  public void moveBallOnce(int ay) {
 
    Color save= getColor();
    setColor(Color.white);
    fillCircle(2*radius);
    moveTo(getX()+vx,getY()+vy,0);
    setColor(save);
    fillCircle(2*radius);
    if(getX()+radius > getWidth() && vx >= 0)
      vx= -vx;
    if(getX()-radius < 0 && vx <= 0)
      vx= -vx;
    if(getY()+radius > getHeight() && vy >= 0) {
      if(vy < ay)
        vy = -ay;
      else
        vy= -vy;
    }
    if(getY()-radius < 0 && vy <= 0)
      vy= -vy;
    
    vy= vy +ay;
  }
  /*this makes a ball stay in motion indefinately*/
  public void inMotion() {
    while(true) {
      moveBallOnce();
      pause(100);
    }
  }
  
  /*this makes two balls stay in motion indefinately*/
   public static void inMotion(Balldac69 b1, Balldac69 b2) {
     while(true) {
       b1.moveBallOnce();
       b2.moveBallOnce();
       b1.pause(100);
     }
    }
  
    /* this creates two new balls removing the bigger one,
     * giving velocities based upon relation to b2
     * the end result should look like one ball splits into two
     * precondition: b1, b2 are in v*/
    public static void twoBallCollide(Balldac69 b1,Balldac69 b2, Vector v) {
      //erase one ball, and add two others using Vector
      if(b1.getRadius() >= b2.getRadius()) {
      //large one splits into two
        if(b1.getRadius() > 4) {
        Color save= b1.getColor();
        b1.setColor(Color.white);
        b1.fillCircle(2*b1.getRadius());
        if(b1.getY() >= b2.getY()) {
          v.add(new Balldac69(b1.getX() + b1.getRadius(),b1.getY() + b1.getRadius()/2,
                         b1.getXVelocity() + 5, b2.getYVelocity(), 
                         b1.getRadius()/2, save));
          v.add(new Balldac69(b1.getX() - b1.getRadius(),b1.getY() + b1.getRadius()/2,
                         b1.getXVelocity() - 5, b2.getYVelocity(), 
                         b1.getRadius()/2, save));
           }
        if(b1.getY() < b2.getY()) {
          v.add(new Balldac69(b1.getX() + b1.getRadius(),b1.getY() - b1.getRadius()/2,
                         b1.getXVelocity() + 5, -(b1.getYVelocity()), 
                         b1.getRadius()/2, save));
          v.add(new Balldac69(b1.getX() - b1.getRadius(),b1.getY() - b1.getRadius()/2,
                         b1.getXVelocity() - 5, -(b1.getYVelocity()), 
                         b1.getRadius()/2, save));
           }
        v.remove(b1);
        }
    }
  else
    twoBallCollide(b2,b1,v);
  }
    
    /*this function creates two balls at (40,40) and the midpoint, 
     * gives them velocities x1v,y1v and x2v, y2v
     * and checks for collision.
     * if collision occurs, they split in two until the radius is less than or equal to 4*/
    static void coolThings(int x1v,int y1v,int x2v, int y2v, int color) {
      Vector v= new Vector();
      v.add(new Balldac69(40,40,x1v,y1v,30,color));
      v.add(new Balldac69(x2v,y2v,30,color));
      
      Balldac69 b1;
      Balldac69 b2;
      while(true) {
        int j= 0;
        int k= 0;
  
        b1= (Balldac69) v.get(j); //This is to make sure b1.pause(100) works
        while(j<v.size()) {
          b1= (Balldac69) v.get(j);
          while(k<v.size()) {
            b2= (Balldac69) v.get(k);
            if(j!=k
                 && (b1.getX() + b1.getRadius() >= b2.getX() - b2.getRadius())
                 && (b1.getX() - b1.getRadius() <= b2.getX() + b2.getRadius())
                 && (b1.getY() + b1.getRadius() >= b2.getY() - b2.getRadius())
                 && (b1.getY() + b1.getRadius() <= b2.getY() + b2.getRadius())) 
                twoBallCollide(b1,b2, v);
            k= k+1;
            }
          b1.moveBallOnce(3);
          j= j+1;
          k= 0;
          }
         b1.pause(100);
        }
      }
       
  
}