int PREGAME = 0;
int GAME = 1;
int POSTGAME = 2;
int gamemode = PREGAME;

Rocket r;
HashSet spiders = new HashSet();
HashSet bullets = new HashSet();

int wave = 0;
int score = 0;

void setup(){
  r = new Rocket();
  //spiders.add(new Spider());
  size(500,500);
  //smooth();
  textFont(createFont("",24),24);

  gamemode = PREGAME;

}

float controlX = 250;
float controlY = 450;
float controlSize = 80;

void draw(){
  background(50,50,200);
  if(gamemode == PREGAME || gamemode == POSTGAME) {
    drawPregame();
  }
  rectMode(CORNER);
  fill(0,128,0);
  noStroke();
  rect(0,400,500,100);


  stroke(0,50);
  fill(200,50);
  strokeWeight(2);
  ellipse(controlX,controlY,controlSize,controlSize);
  fill(255,255,0,50);

  float dX = mouseX - r.x;
  float dY = mouseY - r.y;

  float angle = atan2(dY,dX);
  float power = dist(mouseX,mouseY,controlX,controlY);
  if(power >= 30) power = 30;

  pushMatrix();
  translate(controlX,controlY);
  ellipse(cos(angle)*power,sin(angle)*power,20,20);
  popMatrix();
  stroke(0); fill(0);

  r.setAnglePower(angle,power);

  r.move();
  r.draw();


  Iterator i = spiders.iterator();
  while(i.hasNext()){
     Spider s = (Spider)i.next();
     s.move();
    s.draw(); 
    
     Iterator i2 = bullets.iterator();
  while(i2.hasNext()){
     Bullet b = (Bullet)i2.next();
     if(b.hitSpider(s)) { b.dead = true; s.dead = true;}
    b.draw(); 
  }
    
    
  }
  
  
  
   i = bullets.iterator();
  while(i.hasNext()){
     Bullet b = (Bullet)i.next();
     if(b.move()) b.dead = true;;
     
  }
  
   i = bullets.iterator();
  while(i.hasNext()){
  Bullet b = (Bullet)i.next();
  if(b.dead) i.remove();
  }
  
    i = spiders.iterator();
  while(i.hasNext()){
     Spider s = (Spider)i.next();
     if(s.dead) {score++;i.remove();}  
     
     if(dist(r.x,r.y,s.x,s.y )< 20){
        r.dead = true; 
        gamemode = POSTGAME;
       // line(0,0,r.x,r.y);
     }
  }
  
  if(spiders.size() == 0 && gamemode == GAME){
   
    for(int j = 0; j < wave;j++){  
      spiders.add(new Spider()); 
    }
      wave++;
   
  }
  
  if(frameCount % 10 == 0 && ! r.dead && gamemode == GAME){
    bullets.add(new Bullet());
  }

if(gamemode == GAME){
  textAlign(LEFT);
  fill(255);
   text("wave:"+(wave-1),320,420); 
   //text("<-your control",300,450); 
   text("score:"+(score),320,480); 
}

  //print(power+" ");
}

class Bullet{
  boolean dead = false;
  float x,y,xs,ys; 
  Bullet(){
      x = r.x; y = r.y;
      xs = cos(r.a) * 5;
      ys = sin(r.a) * 5;
   } 
   boolean move(){
      x += xs;
     y += ys; 
     if(x < 0 || x > 500 || y < 0 || y > 400){
      return true; 
     }
     return false;
   }
   boolean hitSpider(Spider s){
      if(dist(x,y,s.x,s.y) <= 20) return true;
     return false; 
   }
   void draw(){
      fill(0); 
     stroke(0);
    strokeWeight(3);
   ellipse(x,y,2,2); 
   }
   
}

void mousePressed(){
if(gamemode != GAME){
   wave = 1;
   spiders = new HashSet();
  r = new Rocket(); 
  gamemode = GAME;
}
}

class Spider{
  boolean dead = false;
  float x=250,y=250;
  float xs,ys;
  float a;
  
  Spider(){
     y = random(400);
     x = 500;
     if(random(10) < 5){
        x = 0; 
     }
  }
  
  int MOVEWAIT = Math.round( random(40,80));
  int counter = MOVEWAIT;
  void move(){
      a = atan2(r.y-y,r.x-x);
    counter--;
    if(counter <= 0){
      counter = MOVEWAIT;
      xs = cos(a) * 10;
      ys = sin(a) * 10;
    }    
    x += xs;
    y += ys;
    
    xs *= .9;ys *= .9;
    
    
    if(x < 0) { x = abs(xs); xs *= -.7; }
    if(y < 0) { y = abs(ys); ys *= -.7; }
    if(x > 500) { x = 500-abs(xs); xs *= -7; }
    if(y > 400) { y = 400-abs(ys); ys *= -.7; }
    
  }
  void draw(){
     fill(128);
     pushMatrix();
     translate(x,y);
     rotate(a-PI/2);
float LEGSIZE = 15;
      line(-LEGSIZE,-LEGSIZE/2,LEGSIZE,LEGSIZE/2);
      line(LEGSIZE,-LEGSIZE/2,-LEGSIZE,LEGSIZE/2);
      line(LEGSIZE,0,-LEGSIZE,0);

    ellipse(0,0,20,20); 
    popMatrix();
  }
  
  
}


class Rocket {
  float x = 250; 
  float y = 250;
  float xs,ys;
  float a;
  float p;
  boolean dead = false;
  Rocket(){

  }

  void move(){
    
    
    if(dead) {
       ys += .1;
       x+=xs;
       y+=ys;
      return; 
    }
    xs += cos(a) * p/400;
    ys += sin(a) * p/400;
    x += xs;
    y += ys;
    
    float ma = atan2(ys,xs);
    float mg = dist(0,0,xs,ys);
    float MAXSPEED = 8;
    if(mg > MAXSPEED){
      xs = MAXSPEED * cos(ma);
      ys = MAXSPEED * sin(ys);
    }
    
    
   // iterator 
    
    if(x < 0) { x = abs(xs); xs *= -.7; }
    if(y < 0) { y = abs(ys); ys *= -.7; }
    if(x > 500) { x = 500-abs(xs); xs *= -.7; }
    if(y > 400) { y = 400-abs(ys); ys *= -.7; }
    
   
    
  }
  float BEESIZE = 20;
  float counter;
  void setAnglePower(float a,float p){
   this.a = a;
  this.p = p; 
  }
  void draw(){
    float  wingoff = sin(counter+=.3)*5;  
    pushMatrix();
    translate(x,y);
    rotate(a+PI/2);
    
      noFill();
    ellipse(-3,-3+wingoff,15,15);
    ellipse(3,-3+wingoff,15,15);

    if(dead) {fill(128); }
    else {
      fill(255,255,0);
      wingoff = sin(counter+=p/40)*5;  
  }
  strokeWeight(3);
    line(0,0,-BEESIZE/2,-BEESIZE/2);
    line(0,0,BEESIZE/2,-BEESIZE/2);
    
    ellipse(0,0,BEESIZE,BEESIZE);
    line(-BEESIZE/2,0,BEESIZE/2,0);
    line(-BEESIZE/2,BEESIZE/4,BEESIZE/2,BEESIZE/4);
    
    fill(0);stroke(0);
    ellipse(-4,-5,1,1);
    ellipse(4,-5,1,1);
    
    popMatrix(); 
  }
}


void resetGame(){

}

void drawPregame(){
  fill(255);
  textAlign(CENTER);
 String sum = "";
  if(gamemode == POSTGAME){
      sum = "last score:"+score+" wave:"+(wave-1);
  }
  text("SPIDERCON\n\nspiders are invading!\n"+sum+"\nguide your beefighter with the mouse and defend your sky\nCLICK TO PLAY",50,100,400,350);
}
void drawPostgame(){

}

HashSet keysDown = new HashSet();
void keyPressed(){
  this.keysDown.add(this.keyEvent.getKeyCode());
}
void keyReleased(){
  this.keysDown.remove(this.keyEvent.getKeyCode());  
}
boolean isKeyDown(int keyCode){
  if(keysDown.contains(keyCode)) return true;
  return false; 
}