Guy guy;
HashSet treasures = new HashSet();

void setup()  
{ 
  textFont(loadFont("BradleyHandITC-30.vlw"));
  size(200, 200);  // Size should be the first statement 
  noStroke();     // Set line drawing color to white 
  frameRate(30); 
  for (int i=0;i<NUMATTRACTORS;i++) { 
    points.add(new Attractor());     
  } 
  
  guy = new Guy(true);

} 

int TITLE = 1;
int PLAYING = 2;
int AFTER = 3;
int gamemode = TITLE;
float starting;

void mouseClicked(){
   if(gamemode == TITLE || gamemode == AFTER){
     gamemode = PLAYING;
treasures = new HashSet();
  for(int i = 0; i < 10; i++){
     treasures.add(new Guy(false));
  }
    starting = millis();
  
   } 
   
}

 float score;
// The statements in draw() are executed until the  
// program is stopped. Each statement is executed in  
// sequence and after the last line is read, the first  
// line is executed again. 
void draw()  
{  
  background(0);   // Set the background to black 
  fill(255); 

  
   moveAttractors();
   float speed = 0 ;
   for(int i = 0 ; i < NUMATTRACTORS; i++){
     Attractor cA = (Attractor) points.get(i);  
     speed += abs(cA.dx) + abs(cA.dy);  
   }
    doBackground();  

fill(0);
if(gamemode == TITLE || gamemode == AFTER){
  text("Blurble",20,75);
  if(gamemode == AFTER) {
//    text("time:"+score,20,100);

  } 
  
  text("in bubble land",10,120);
  text("catch the food",10,150);
  text("click to play",10,175);
}
if(gamemode == PLAYING){
   score = (millis() - starting)/100;
   
   score = int(score);
   score /= 10;
 //score *= 10; 
}
if(gamemode == PLAYING || gamemode == AFTER)
{
  text("time:"+score,10,25);
  
}
if(gamemode == PLAYING) {
   if(treasures.size() == 0){
      gamemode = AFTER;
   }   
}

  guy.move();
  guy.draw();
  
  Iterator i = treasures.iterator();
  while(i.hasNext()){
     Guy t = (Guy)i.next();
    t.move();
   t.draw(); 
    float dist = mag(t.x-guy.x,t.y-guy.y);
    if(dist < 20){
       i.remove();
    }

  }
  
}  




class Guy{
    float x = 100; 
    float y = 100;
    float xspeed = .1,yspeed = .1;
    boolean player;
 
 float gx, gy;
    Guy(boolean main){
        if(!main){
          x = random(200);
          y = random(200);
        }  
        player = main;
 
 gx = random(200);
 gy = random(200);
 
    }
    
    
    void draw(){
      float bright = closest * 3;
      if(player){
       fill(bright,0,0,40);
       float r = bright / 10;
//    ellipse(x,y,r,r);  
    } else {
       fill(0,bright,0,200);
  //        ellipse(x,y,10,10);
      }
      
  }
  float closest;
  
   void move(){
      closest = 400;
     int nearest=-1;
         for (int p=0;p<NUMATTRACTORS;p++) { 
        Attractor a=(Attractor)points.get(p); 
        float dist=a.distanceTo(x,y); 
        if (dist<closest) { 
          nearest=p; 
          closest=dist; 
        } 
      } 
          
     Attractor cA = (Attractor)points.get(nearest);
     
     xspeed += (x - cA.x)/200;
     yspeed += (y - cA.y)/200;
     
float wantangle ;
if(player){
  wantangle= atan2(mouseY-y, mouseX-x);
} else {
  wantangle= atan2(gy-y, gx-x);
  
}
float mod = .2;
float dx = mod*cos(wantangle);
float dy = mod*sin(wantangle);

xspeed += dx;//(mouseX - x)/400;
yspeed += dy; //(mouseY - y)/400;
      float bright = closest * 3;
      float w;
     
      w = (300-(bright))/20;
    if(!player) w /= 2; 
  
  if(w < 1) w = 1;
      strokeWeight(w);
 
if(player){
  stroke(bright,0,0,40);
} else {
  stroke(0,bright,0,40);
  
}
line(x,y,x+(dx*50),y+(dy*50));     
noStroke();          
     x += xspeed;
     y += yspeed;
     
   /*  if(player){
        x = mouseX;
        y = mouseY;
     }*/
     
     if(x<0) {x = 0; xspeed *= .5;}
     if(y<0) {y = 0; yspeed *= .5;}
     if(x>200) {x = 200; xspeed *= .5;}
     if(y>200) {y = 200; yspeed *= .5;}
     float MAX = 3;
     if(sqrt(pow(xspeed,2)+pow(yspeed,2)) > MAX){
        float wa = atan2(yspeed,xspeed);
         xspeed = MAX * cos(wa);
         yspeed =MAX * sin(wa);
     }
     
   }
}











 
Random die=new Random(); 
ArrayList points=new ArrayList(); 
 
class Attractor { 
   
  public float x; 
  public float y; 
  public float  dx; 
  public float dy; 
  public Attractor() { 
    this.x=random(200); 
    this.y=random(200); 
    this.dx=-random(-1,1); 
    this.dy=-random(-1,1); 
  } 
   
public void move() {
if(mousePressed){
  /*
   if( x < mouseX){
     dx += .15;
   } 
   if( x > mouseX){
     dx -= .15;
   } 
   if( y < mouseY){
     dy += .15;
   } 
   if( y > mouseY){
     dy -= .15;
   }
  */ 
}
  
  
  
  // move with wall bounce
this.x+=this.dx;
if (this.x<0) { x = 0; dx = abs(dx);} 
if (this.x>200) { x = 200; dx = -abs(dx);} 
this.y+=this.dy;
if (this.y<0)  { y = 0; dy = abs(dy);} 
if (this.y>200)  { y = 200; dy = -abs(dx);} 




}


  public float distanceTo(float  xx,float yy) { 
    return dist(xx,yy,this.x,this.y);
  } 
} 
 
 
float y = 100; 
 
 
int NUMATTRACTORS = 15;
 
void doBackground(){
   
  for (int x=0;x<200;x+=2) { 
    for (int y=0;y<200;y+=2) { 
      int nearest=0; 
      float closest=1000.0; 
      for (int p=0;p<NUMATTRACTORS;p++) { 
        Attractor a=(Attractor)points.get(p); 
        float dist=a.distanceTo(x,y); 
        if (dist<closest) { 
          nearest=p; 
          closest=dist; 
        } 
      } 
      Attractor a=(Attractor)points.get(nearest); 
      //fill(a.r,a.g,a.b); // fill by color
     float lightval =250-2.5*closest ; 
    // print(lightval+" ");
      fill(lightval,lightval,255); 
      rect(x,y,2,2); 
    } 
  } 
 
} 
 
void moveAttractors() {
  for (int i=0;i<NUMATTRACTORS;i++) { 
    Attractor a=(Attractor)points.get(i); 
    a.move(); 
  }
  
}