import java.awt.*;
/** Assignment A4: using a Turtle
 * 
 * @author    Peter O'Brien
 * 
 * Execute this to start this game going:
 * 
 *     Ballpjo8.funBox(20,30,50);
 */
public class Ballpjo8 extends Turtle {
  private int radius; // The radius of the ball;
  private int vx, vy; // The horizontal and vertical acceleration of the ball;

  /** Constructor: a Ball starting at (x,y) with acceleartion (vx,vy), radius r
   *               and color c;
   * 
   * @param x the initial x coordinate of the ball
   * @param y the initial y coordinate of the ball
   * @param vx the acceleration of the ball in the x direction
   * @param vy the acceleration of the ball in the y direction
   * @param r the radius of the ball
   * @param c the color of the ball
   */
  public Ballpjo8(int x, int y, int vx, int vy, int r, Color c){
    super(x,y,0);

    radius= r;
    this.vx= vx;
    this.vy= vy;    
    setColor(c);
    fillCircle(2*radius);

  }

  /** Constructor: a black Ball starting at the middle of the panel with acceleration (vx,vy)
   *               and radius r;
   * @param vx the acceleration of the ball in the x direction
   * @param vy the acceleration of the ball in the y direction
   * @param r the radius of the ball    
   */
  public Ballpjo8(int vx,int vy,int r){
    this(width/2,height/2,vx,vy,r,Color.black);
  }


  /** Set the radius of the circle 
   */
  public void setRadius(int r){
    radius= r;
  }
  /** Set the horizontal acceleration to vx*/
  public void setVx(int vx){
    this.vx= vx; 
  }

  /** Set the vertical acceleartion to vy*/
  public void setVy(int vy){
    this.vy= vy; 
  }

  /** = the radius of the ball*/
  public int getRadius(){
    return radius; 
  }

  /** = the horizontal acceleration of the ball*/
  public int getVx(){
    return vx; 
  }

  /** = the vertical acceleration of the ball*/
  public int getVy(){
    return vy; 
  }

  /** Moves the ball vx pixels in the x direction and vy pixels in the y direction.
   * The ball 'bounces' when it 'hits' the edge of the window.
   */
  public void moveBallOnce(){
    int newx = getX() + getVx(); //The next x position of the ball
    int newy = getY() + getVy(); //The next y position of the ball
    if(newx + radius >= getWidth()){ 
      newx = getWidth()-radius;
      setVx(-getVx());
    }
    if(newx < radius){
      newx = radius;
      setVx(-getVx());
    }
    if(newy + radius >= getHeight()){
      newy = getHeight()-radius;
      setVy(-getVy());
    }
    if(newy < radius){
      newy = radius;
      setVy(-getVy());
    }
    Color save= getColor(); //stores the old color value
    setColor(Color.white);
    fillCircle(radius*2);
    moveTo(newx,newy,0);
    setColor(save);
    fillCircle(radius*2);
  }

  /** Sets ball perpetually in motion, moving vx pixels in the x direction and 
   * vy pixels inthe y direction 10 times per second. */
  public void inMotion(){
    for(int i = 1;i>0;i++){
      pause(100);
      moveBallOnce();
    }
  }

  /** Sets balls b1 and b2 perpetually in motion.
   * 
   * @param b1 The first ball to set in motion
   * @param b2 The second ball to set in motion
   */
  public static void inMotion(Ballpjo8 b1, Ballpjo8 b2){
    if(b1!=null && b2 !=null){
      for(int i = 1;i>0;i=1){
        b1.pause(100);
        b1.moveBallOnce();
        b2.moveBallOnce();
      }
    }
  }


  /**/////////////////Custom Function////////////////////////////////*/
  /** Run funBox with good demo settings: initial position (110,50) and 25us delay */
  public static void funBox(){
    funBox(110,50,25);
  }
  /** A bouncing ball that interacts with one sliding box and three stationary boxes. The ball bounces off any 
   * side of the sliding box and changes color when it does so. The ball becomes temporarily trapped when it 
   * hits the rightmost box, doubles in speed when it hits the center box and becomes one half larger when it 
   * hits the leftmost box. The ball begins at (xi,yi) and the speed of the system is given by the delay(in 
   * microseconds) spd.
   * @param xi initial x position of the ball
   * @param yi initial y position of the ball
   * @param spd initial speed (delay between renderings) of the system
   * */
  public static void funBox(int xi, int yi, int spd){
    Color g[]={new Color(205,38,38),new Color(16,78,139),new Color(102,205,0),Color.orange,Color.black,new Color(139,115,85)};//Array of color values for the ball
    int RYi = 350; //Initial slider y coord.
    int Rv = 5;  //Slider velocity
    int b2Rad = 15; //Ball's initial Radius
    int c3 = 0; //counter for rightmost funbox;
    boolean f1=true; //funbox 1 exists
    boolean f2=true; //funbox 2 exists
    boolean f3=true; //funbox 3 exists

    Ballpjo8 b1 = new Ballpjo8(0,0,0); //Instance of Ball that handles the funboxes and the slider
    Ballpjo8 b2 = new Ballpjo8(xi,yi,5,5,b2Rad,new Color(0,0,139)); //The ball.     

    b1.clear();

    //Initialize Funbox1 (leftmost)
    b1.setColor(new Color(102,205,0));
    b1.moveTo(30,470,0);      
    b1.fillRectangle(60,60);
    b1.setColor(Color.black);
    b1.drawRectangle(60,60);

    //Initialize Funbox2 (rightmost)
    b1.setColor(new Color(205,38,38));
    b1.moveTo(470,470,0);
    b1.fillRectangle(60,60);
    b1.setColor(Color.black);
    b1.drawRectangle(62,62);

    //Initialize Funbox3 (center)
    b1.setColor(new Color(39,64,139));
    b1.moveTo(250,480,0);
    b1.fillRectangle(100,40);
    b1.setColor(Color.black);
    b1.drawRectangle(100,40);

    //Initialize Slider
    b1.setColor(Color.black);
    b1.moveTo(30,RYi,0);
    b1.drawRectangle(50,20);

    for(int i=1;i>0;i++){      
      int newx = b1.getX()+Rv;   // next position of the slider        
      int t = (int)(Math.random() * 6);//Random color index
      int x = b2.getX();  //x position of b2
      int y = b2.getY(); //y position of b2
      int qX= 1; //x velocity modifier
      int qY= 1; //y velocity modifier
      boolean m = false; //the ball has hit the slider
      boolean z = false; //the ball has hit the center funbox
      b2Rad=b2.getRadius(); //radius of b2

      b1.pause(spd);      
      if(c3>0)c3--;

      //Handle Ball colliding with slider.  

      if(y<(RYi-10) && y>(RYi-10-b2Rad) && x>(newx-25-10) && x<(newx+25+10) && b2.getVy()>0){
        b2.setVy(-b2.getVy());
        m=true;
      }
      if(y>(RYi-10-10) && y<(RYi+10+10) && x<(newx-25) && x>(newx-25-b2Rad) && b2.getVx()>0){
        b2.setVx(-b2.getVx());
        m=true;
      }
      if(y>(RYi+10) && y<(RYi+10+b2Rad) && x<(newx+25+10) && x>(newx-25-10) && b2.getVy()<0){
        b2.setVy(-b2.getVy());
        m=true;
      }
      if(y>(RYi-10-10) && y<(RYi+10+10) && x>(newx+25) && x<(newx+25+b2Rad) && b2.getVx()<0){
        b2.setVx(-b2.getVx()); 
        m=true;
      }
      if(m)b2.setColor(g[t]);

      //Handle ball colliding with funbox1
      if(f1 && b2.getY()>(430-b2Rad) && b2.getX()<(70+b2Rad)){
        if(b2.getVx() < 0 && b2.getX() > 75) qX=-1;
        else qY=-1;
        b2.setVx(b2.getVx()*qX);
        b2.setVy(b2.getVy()*qY);
        b2.setRadius((int)(b2.getRadius()*1.5));
        f1=false;
        b1.setColor(Color.white);
        b1.drawRectangle(50,20);
        b1.moveTo(30,470,0);      
        b1.fillRectangle(62,62);
      }

      //Handle ball colliding with funbox2
      if(f2 && b2.getY()>(430-b2Rad) && b2.getX()>(430-b2Rad)){
        if(b2.getVx() > 0 && b2.getX() < 425) qX=-1;
        else qY=-1;
        b2.setVx(b2.getVx()*qX);
        b2.setVy(b2.getVy()*qY);
        c3=300;
        f2=false;
        b1.setColor(Color.white);
        b1.drawRectangle(50,20);
        b1.moveTo(470,470,0);      
        b1.fillRectangle(62,62);
        b1.moveTo(newx,RYi,0);

        b2.setColor(Color.white);
        b2.fillCircle(b2.getRadius()*2);
        b2.moveTo(470,470,0);
        b2.setColor(g[t]);
        b2.fillCircle(b2.getRadius()*2);
      }

      //Handle ball colliding with funbox3
      if(f3 && b2.getY()>(460-b2Rad) && b2.getX()<(300+b2Rad) && b2.getX()>(200-b2Rad)){
        if(b2.getX()<200 && b2.getVx()>0){ 
          b2.setVx(-b2.getVx());
          z=true;
        }
        if(b2.getX()>300 && b2.getVx()<0){
          b2.setVx(-b2.getVx());
          z=true;
        }
        if(b2.getY()>460&&b2.getVy()>0){
          b2.setVy(-b2.getVy());
          z=true;
        }
        if(z){
          b2.setVy(2*b2.getVy());
          b2.setVx(2*b2.getVx());
          b1.setColor(Color.white);
          b1.drawRectangle(50,20);
          b1.moveTo(250,480,0);
          b1.fillRectangle(102,42);
          b1.moveTo(newx,RYi,0);
          f3=false;         
        }
      }

      //Move the Rectangle      
      b1.setColor(Color.white);
      b1.drawRectangle(50,20);        
      if(newx>b1.getWidth()-25){
        newx=b1.getWidth()-25;
        Rv = -Rv;
      }
      if(newx<25){
        newx=25;
        Rv=-Rv;
      }
      b1.moveTo(newx,RYi,0);
      b1.setColor(Color.black);
      b1.drawRectangle(50,20);

      //Move the ball if it is not trapped.
      if(c3==0)b2.moveBallOnce();
    }
  }


}