//////// Project 3



Ball w,b,r,o,g;
Button b1,b2,b3,b0;
Paragraph p1;

String title= " Projet 3";
String help= "'r' key to reset, 'q to quit. \n 'w' to remove wall. /n click any ball to reset it.";
String news= help;
String author= "Dymon Harris";

float up, right, down, left;
float center;
float mright, mleft;

boolean wall=true;

float horizon;

void setup() {
  size( 700, 500 );
  horizon=  height/4;
  right= width-94;
  left=  105;
  up=  120;
  down= height-80;
  center= left + (right-left) / 2;
  mleft= 370;
  mright= 340;
  
  w=  new Ball();
  w.r=255;
  w.b=255;
  w.g=255;
  w.name=  "w";
  //
  b=  new Ball();
  b.r=0;
  b.g=0;
  b.b=200;
  b.name=  "b";
  //
  r=  new Ball();
  r.r=150;
  r.g=0;
  r.b=0;
  r.name=  "r";
  //
  o=  new Ball();
  o.r=225;
  o.g=100;
  o.b=0;
  o.name=  "o";
  //
  g=  new Ball();
  g.r=0;
  g.g=150;
  g.b=0;
    g.name=  "g";
  //
  b1= new Button(); 
  b1.r=170;
  b1.g=200;
  b1.b=255;
  b1.name= "Reset";
  //
  /*b2= new Button();
  b2.r=170;
  b2.g=200;
  b2.b=255;
  b2.name= "Color"; */
  //
  b3= new Button(); 
  b3.r=170;
  b3.g=200;
  b3.b=255;
  b3.name="Wall";
  //
  b0= new Button(); 
  b0.r=170;
  b0.g=200;
  b0.b=255;
  b0.name="Quit";
  //
  p1= new Paragraph();
  p1.r=150;
  p1.g=200;
  p1.b=250;
  p1.name="Project 3 \n \n 'r' key to reset, 'q to quit. \n 'w' to remove wall.\n click any ball to reset it.";
  //
  reset();
}
void reset() {
  w.x= left + (right-left) / 4;
  w.y= up + (down-up) / 2;
  w.dx= w.dy=0;
  mleft= 370;
  mright= 340;
  wall = true;
  
  w.reset();
  b.reset();
  r.reset();
  o.reset();
  g.reset();
  
}

//// NEXT FRAME:  scene, birds, balls.
void draw() {
  background ( 150,200,250 );
  rectMode(CENTER);
  table ( left, up, right, down );
 /* scene();
*/  balls();
}

//// Scene: Draw the pool table with walls
void table( float left, float up, float right, float down ) {
  fill( 0,150,100 );
  strokeWeight(15);
  stroke( 200,200,200 );
  rect( 355,270,545,345 );
  stroke(0);
  strokeWeight(8);


    if (!wall) {
    float center= left + (right-left) / 2;    
    line( 0,0,0,0 );
  }
  
    if (wall) {
    float center= left + (right-left) / 2;    
     line( 355,415,355,125 );
  }
}

//// SCENE:  sky & grass.
/*void scene() {
  background(150,200,250);
  fill( 150,250,150 );
}
*/
//// Move & show each ball
void balls() {
  collision( w, b );
  collision( w, r );
  collision( w, o );
  collision( w, g );
  //
  collision( b, r );
  collision( b, o );
  collision( b, g );
  //
  collision( r, o );
  collision( r, g );
  //
  collision( o, g );
  //
  w.move();
  b.move();
  r.move();
  o.move();
  g.move();
  //
  w.show();
  b.show();
  r.show();
  o.show();
  g.show();
  //
  b1.show();
 /* b2.show(); */
  b3.show();
  b0.show();
  //
  p1.show();
}

//// Elastic collisions.
void collision( Ball p, Ball q ) {
  if ( p.hit( q.x,q.y ) ) {
    float tmp;
    tmp=p.dx;  p.dx=q.dx;  q.dx=tmp;      // Swap the velocities.
    tmp=p.dy;  p.dy=q.dy;  q.dy=tmp;
    p.move();  p.move();   p.move();
    q.move();  q.move();   q.move();
  }
}


//// HANDLERS:  keys & clicks.
void keyPressed() {
  if (key == 'q') exit();
  if (key == 'r') {
        w.reset();
        b.reset();
        r.reset();
        o.reset();
        g.reset();
  }
  if (key == 'a') {
    w.dx *= 2;          // Make a ball go faster!
    w.dy *= 2;
  }
  if (key == 'w') { mleft = left; mright = right; wall = false; }
}
    
void mousePressed() {
  
   if ( hit( mouseX, mouseY, b1.x, b1.y, 80, 40 ) ) {
      reset();
   }
   /* if ( hit( mouseX, mouseY, b2.x, b2.y, 80, 40 ) ) {
       r= int( random(0,255) ); 
       g= int( random(0,200) ); 
       b= int( random(0,230) );
   } */
  
  if ( hit( mouseX, mouseY, b3.x, b3.y, 80, 40 ) ) {
  { mleft = left; mright = right; wall = false; }
  }
  
  if ( hit( mouseX, mouseY, b0.x, b0.y, 80, 40 ) ) {
      exit();
   }
   
   if ( hit( mouseX,mouseY, w.x,w.y, 30,30  ) ) {  w.reset(); }
   if ( hit( mouseX,mouseY, b.x,b.y, 30,30  ) ) {  b.reset(); }
   if ( hit( mouseX,mouseY, r.x,r.y, 30,30  ) ) {  r.reset(); }
   if ( hit( mouseX,mouseY, o.x,o.y, 30,30  ) ) { o.reset(); }
   if ( hit( mouseX,mouseY, g.x,g.y, 30,30  ) ) {  g.reset(); }
}


//// OBJECTS ////
class Ball {
  //// PROPERTIES:  position, speed, color, etc. ////   (What a Ball "has".)
  float x,y, dx,dy;
  int r,g,b;
  String name="";
  
  //// CONSTRUCTORS (if any). ////
  
  //// METHODS:  show, move, detect a "hit", etc. ////  (What a Ball "does".)
  void show() {
    fill(r,g,b);
    strokeWeight(1);
    ellipse( x,y, 30,30 );
    fill(0);
    text( name, x-5,y );
    
  }
  
void move() {
    if (x<mleft || x>right) {  dx *=  -1; }
    if (y<up || y>down) {  dy *=  -1; }
    x=  x+dx;
    y=  y+dy;
  }


  void reset() {
    x=  random( width/2, width-100 );
    y=  random( horizon+0, height-50 );
    dx=  random( 1,5 );
    dy=  random( 1,3 );
  }
  boolean hit( float x, float y ) {
    if (  dist( x,y, this.x,this.y ) < 30 ) return true;
    else return false;
  }
}

class Button {
  float x,y,w,h;
  int r,g,b;
  String name="s";
  String s ;
  
  void show() {
    fill(r,g,b);
    strokeWeight(1);
    rect( x,y, 80,40 );
    fill(0);
    text( name, x-5,y );
    
    b1.x=150; b1.y=40; b1.w=100; b1.h=100; 
    /* b2.x=600; b2.y=40;  b2.w=100; b2.h=100; */
    b3.x=450; b3.y=40; b3.w=100; b3.h=100;
    b0.x=28;  b0.y=100;  b0.w=100; b0.h=100;
  }
}

class Paragraph {
  float x,y,w,h;
  int r,g,b;
  String name="s";
  String s ;
  
  void show() {
    fill(r,g,b);
    strokeWeight(0);
    rect( x,y, 0,0 );
    fill(0);
    text( name, x-5,y );
    p1.x=230; p1.y=20; p1.w=0; p1.h=0;
  }
}
  
boolean hit( float x1, float y1, float x2, float y2, float w, float h ) {
  boolean result;

  // +++++ STUB ALWAYS RETURNS TRUE!
  if ( abs(x1-x2) < w && abs(y1-y2)<h ) {
    result=  true;
  } else {
    result=false;
  }
  return result;
}




