int SCREENSIZE = 300;
int CRITTERCOUNT = 50;
int CRITTERWIDTH=8;
int CRITTERHEIGHT=10;
critter c[]; 
int count; 

int BEFOREGAME = 0;
int DURINGGAME = 1;
int AFTERGAME = 2;

int gamestage = BEFOREGAME;

int timer;

int numcaught;
float ballX = 150,ballY = 150,ballXSpeed, ballYSpeed;

void keyPressed(){
  
  
  
 
  if(keyCode == 32){

    if(gamestage == AFTERGAME){
      for(int i = 0; i < CRITTERCOUNT * 7; i++){
        c[i].x = random(SCREENSIZE);
        c[i].y = random(SCREENSIZE) ;
      }
    }
     if(gamestage == BEFOREGAME || gamestage == AFTERGAME){
      gamestage = DURINGGAME;
      timer = 0;

    }
  }

if(keyCode == 37){
   ballXSpeed = -3;
}
if(keyCode == 39){
   ballXSpeed = 3;
}
if(keyCode == 38){
   ballYSpeed = -3;
}
if(keyCode == 40){
   ballYSpeed = 3; 
}

}

void setup(){
  size(300,300);
  c = new critter[CRITTERCOUNT*10];
  framerate(30);

  ellipseMode(CENTER_RADIUS);

  for(int h = 1; h <= 7; h++){     
    PImage leftdown = loadImage(h+"-down-l.gif");    
    PImage rightdown = loadImage(h+"-down-r.gif");    
    PImage leftup = loadImage(h+"-up-l.gif");    
    PImage rightup = loadImage(h+"-up-r.gif");  



    for(int i = 0; i < CRITTERCOUNT; i++){
      c[count++] = new critter(random(SCREENSIZE),random(SCREENSIZE),leftdown,rightdown,leftup,rightup);
    }
  }
  textFont(loadFont("Arial-Black-14.vlw"),14);
  textAlign(CENTER);
}

void draw(){
  background(4,66,90);

  ballX += ballXSpeed;
  ballY += ballYSpeed;

  noStroke();
  fill(247,198,99);

  ellipse(ballX,ballY,3,3);


numcaught = 0;
  for(int i = 0; i < count; i++){

    if(c[i].isCaught){
      numcaught++;
    }
  }

  if(numcaught == (CRITTERCOUNT*7)){
    gamestage = AFTERGAME;
  }


  if(gamestage == DURINGGAME){
    timer++;
    stroke(255);
    fill(255);
    text("critters: "+((CRITTERCOUNT*7)-numcaught)+" time:"+timer,150,20);
  }  
  float sqrtnumcaught = 3+sqrt(numcaught);




if(ballX < sqrtnumcaught){
   ballX = sqrtnumcaught;
  ballXSpeed = 1; 
}
if(ballY < sqrtnumcaught){
   ballY = sqrtnumcaught;
  ballYSpeed = 1; 
}
if(ballX > SCREENSIZE-sqrtnumcaught){
   ballX = SCREENSIZE-sqrtnumcaught;
  ballXSpeed = -1; 
}
if(ballY > SCREENSIZE-sqrtnumcaught){
   ballY = SCREENSIZE-sqrtnumcaught;
  ballYSpeed = -1; 
}
ballXSpeed *= .99;
ballYSpeed *= .99;












  for(int i = 0; i < count; i++){
    c[i].move(sqrtnumcaught);
    c[i].show();
  }

    stroke(255);
    fill(255);

  if(gamestage == BEFOREGAME){


      text("THE COSMIC ARK REPOPULATION",150,50);
      text("PROGRAM HAS SUCCEEDED",150,75);
      text("BEYOND OUR WILDEST DREASMS",150,100);

      text("NOW YOU PRINCE OF ALL COSMOS",150,150);
      text("MUST COLLECT THE CRITTERS",150,175);
      text("WITH YOUR KATAMARI",150,200);
      text("AS FAST AS YOU CAN",150,225);

      text("space button to start",150,275);
    } 
  if(gamestage == AFTERGAME){
      text("CONGRATULATIONS",150,50); 
      text("YOU DID IT IN "+timer+" COSMISECONDS",150,100); 
      text("space button to try again",150,275);       
    }





}



class critter {
  float x, y;
  PImage imgLeftDown, imgLeftUp, imgRightDown, imgRightUp;
  boolean isCaught = false;
  boolean isScared = false;
  boolean nowUp = true;

  PImage img;

  float xspeed = 0;
  float yspeed = 0;

  float frozX, frozY;

  critter(float inX, float inY, PImage inLeftDown,PImage inRightDown, PImage inLeftUp, PImage inRightUp){
    x = inX;
    y = inY;
    imgLeftDown = inLeftDown;
    imgRightDown = inRightDown;
    imgLeftUp = inLeftUp;
    imgRightUp = inRightUp;
    img = inRightUp;
  }

  void show(){
    // if(! isCaught)
    nowUp = ! nowUp;

    if(xspeed <= 0) {
      if(nowUp)
        img = imgLeftUp;
      else
        img = imgLeftDown;
    }
    if(xspeed > 0){
      if(nowUp)
        img = imgRightUp;
      else
        img = imgRightDown;
    }

    image(img,x,y);
  }

  boolean between(float val, float lower, float higher){
    if(val >= lower && val <= higher){
      return true;
    }
    return false;
  }

  void move(float sqrtnumcaught){

    int critterCenterX = (int)x+(CRITTERWIDTH/2);
    int critterCenterY =(int) y+(CRITTERHEIGHT/2);
    int cRight = (int)x+CRITTERWIDTH;
    int cBottom = (int)y+CRITTERHEIGHT;

    float mx = ballX;
    float my = ballY;

    if(gamestage == DURINGGAME){
      if(! isCaught){
        //        if(overlap() && overlap())
        if( sqrt(pow((critterCenterX - mx),2) + pow((critterCenterY - my),2))<sqrtnumcaught  ){
          isCaught = true;
          isScared = true;
          frozX = mx; 
          frozY = my;
        } //end else (not frozen now) 
      } // end not previously stopped 
      else { //previously stopped
        x = x + (mx-frozX);
        y = y + (my-frozY);
        frozX = mx;
        frozY = my;

      }
    } // end if mouse pressed
    else {
      isCaught = false;
    }

    if(! isCaught){
      float d = sqrt(  pow((mx - critterCenterX),2) + pow((my-critterCenterY),2 ));
      //println(d);
      if(d < 60 && random(100) < (60-d) ){      
        //line(mx,my,critterCenterX,critterCenterY);  
        isScared = true;


        if(mx < critterCenterX){
          xspeed = 1;
        } 
        else {
          xspeed = -1;
        }
        if(my < critterCenterY){
          yspeed = 1;
        } 
        else {
          yspeed = -1;
        }
      }//end if random
      else {
        isScared = false;
      }



    } 




    if(! isCaught && ! isScared){

      if(int(random(3)) == 0){
        xspeed = int(random(0,1)*3)-1;

      }
      if(int(random(3)) == 0){
        yspeed = int(random(0,1)*3)-1;
      }
    }
    if(! isCaught){ 

      x += xspeed; //random(-1,1);
      y += yspeed; 
      random(-1,1);

      x = constrain(x, 0, SCREENSIZE-CRITTERWIDTH);
      y = constrain(y, 0, SCREENSIZE-CRITTERHEIGHT);


    }
  }

}






boolean overlap(float line1val1,float line1val2,float line2val1,float line2val2){
  float line1min = (line1val1 < line1val2)?line1val1:line1val2;
  float line1max = (line1val1 > line1val2)?line1val1:line1val2;
  float line2min = (line1val1 < line2val2)?line2val1:line2val2;
  float line2max = (line1val1 > line2val2)?line2val1:line2val2;

  if(line1min < line2min && line1max < line2min){
    return false; 
  }
  if(line1min > line2max && line1max > line2max){
    return false; 
  }  


  return true;
}