// 4.5 hours
import java.awt.*;
import java.util.*;

/** Every instance is a ball */
public class Ball extends YourTurtle{
  
  private int radius; // the radius of the ball
  private int vx;     // the horizontal speed of the ball
  private int vy;     // the vertical speed of the ball
  private int x,y;    // the x,y coordinates of the ball
  
  /** = radius */
  public int getRad(){
    return radius;
  }
  /** = horizontal speed */
  public int getVX(){
    return vx;
  }
  /** = vertical speed */
  public int getVY(){
    return vy;
  }
  /** Constructor: creates a new Ball with position (x,y)
   *  Horizontal speed: vx, Vertical speed: vy, Radius r, Color c */
  public Ball( int x, int y, int vx, int vy, int r, Color c){
    moveTo(x,y,0);
    this.x=x;
    this.y=y;
    this.vx= vx;
    this.vy= vy;
    radius= r;
    setColor(c);
    drawCircle(radius);
    fillCircle(radius);
  }
  /** Constructor: creates a new black Ball at center of window
   *  Horizontal speed: vx, Vertical speed: vy, Radius r */
  public Ball( int vx, int vy, int r){
    moveTo(width/2,height/2,0);
    this.x= width/2;
    this.y= height/2;
    this.vx= vx;
    this.vy= vy;
    radius= r;
    setColor(1);
    drawCircle(radius);
    fillCircle(radius);
  }
  /** Move the ball once according to its speed */
  public void moveBallOnce(){
    Color save= getColor();
    setColor(Color.white);
    fillCircle(radius);
    moveTo(x+vx, y+vy, 0);
    x= x+vx;
    y= y+ vy;
    setColor(save);
    fillCircle(radius);
    if (x>width || x<0) {
      vx=-vx;}
    if (y>height || y<0) {
      vy=-vy;}
  }
  /** Perpetually move the ball */
  public void inMotion(){
    for (int k= 0; k!=-1; k=k+1){
      moveBallOnce();
      pause(100);}
  }
  
  /** A static version of the pause method in Turtle for use in 
   *  the static method multimotion */
  private static void paus(int d) {
        try { Thread.currentThread().sleep(d); }
        catch (InterruptedException e) { }
    }
  
  /** A static method. Creates up to n<=4 balls (green, red, blue, magenta) with random start positions, speeds (up to 20), and radius (10 to 50)
   *  and sets them in perpetual motion. The balls will bounce off of each other if they meet (the speeds are exchanged).
   *  Precondition: n>=1. 
   *  If n>4, only 4 balls are drawn.*/
  public static void multimotion(int n){
    Ball a= null;
    Ball b= null;
    Ball c= null;
    Ball d= null;
    if (n>=1){
      a= new Ball((int)Math.round(Math.random()*500), 
                    (int)Math.round(Math.random()*500),
                   (int)Math.round(Math.random()*20),
                   (int)Math.round(Math.random()*20), 
                  (int)Math.round(Math.random()*40)+10, Color.green);
      if (n>=2){
        b= new Ball((int)Math.round(Math.random()*500), 
                     (int)Math.round(Math.random()*500),
                     (int)Math.round(Math.random()*20),
                   (int)Math.round(Math.random()*20),
                    (int)Math.round(Math.random()*40)+10, Color.red);
        if (n>=3){
          c= new Ball((int)Math.round(Math.random()*500), 
                     (int)Math.round(Math.random()*500),
                     (int)Math.round(Math.random()*20),
                   (int)Math.round(Math.random()*20),
                      (int)Math.round(Math.random()*40)+10, Color.blue);
          if (n>=4){
            d= new Ball((int)Math.round(Math.random()*500), 
                     (int)Math.round(Math.random()*500),
                     (int)Math.round(Math.random()*20),
                   (int)Math.round(Math.random()*20),
                        (int)Math.round(Math.random()*40)+10, Color.magenta);
          }
        }
      }
    }
    
    for (int k=0; k!=-1; k=k+1){ 
      a.moveBallOnce();
      if (b!=null){
        b.moveBallOnce();
        if (Math.abs(a.x-b.x)<=Math.max(a.radius,b.radius) && 
          Math.abs(a.y-b.y)<=Math.max(a.radius,b.radius)){
        int f= b.vx;
        int e= b.vy;
        b.vx=a.vx; b.vy=a.vy; a.vx=f; a.vy=e;}
      }
      if (c!=null){
        c.moveBallOnce();
        if (Math.abs(a.x-c.x)<=Math.max(a.radius,c.radius) && 
          Math.abs(a.y-c.y)<=Math.max(a.radius,c.radius)){
        int f= c.vx;
        int e= c.vy;
        c.vx=a.vx; c.vy=a.vy; a.vx=f; a.vy=e;}
        if (Math.abs(b.x-c.x)<=Math.max(b.radius,c.radius) && 
          Math.abs(b.y-c.y)<=Math.max(b.radius,c.radius)){
        int f= b.vx;
        int e= b.vy;}
      }
        if (d!=null){
          d.moveBallOnce();
          if (Math.abs(a.x-d.x)<=Math.max(a.radius,d.radius) && 
            Math.abs(a.y-d.y)<=Math.max(a.radius,d.radius)){
            int f= d.vx;
            int e= d.vy;
            d.vx=a.vx; d.vy=a.vy; a.vx=f; a.vy=e;}
          if (Math.abs(b.x-d.x)<=Math.max(b.radius,d.radius) && 
            Math.abs(b.y-d.y)<=Math.max(b.radius,d.radius)){
            int f= b.vx;
            int e= b.vy;
            b.vx=d.vx; b.vy=d.vy; d.vx=f; d.vy=e;}
           if (Math.abs(d.x-c.x)<=Math.max(d.radius,c.radius) && 
            Math.abs(d.y-c.y)<=Math.max(d.radius,c.radius)){
            int f= d.vx;
            int e= d.vy;
            d.vx=c.vx; d.vy=c.vy; c.vx=f; c.vy=e;}
        }
      paus(50);
    }
  }
}
 