import ddf.minim.*;

Minim minim;

void stop(){
  // always close Minim audio classes when you are done with them :-)
  closeSounds();
  minim.stop();
  super.stop();
}
int SAMPLECOUNT = 4;

AudioPlayer music;
AudioSnippet robot_boom;
AudioSnippet player_boom;
AudioSnippet mine_drop;
AudioSnippet mine_ready;

AudioSnippet[] scratch = new AudioSnippet[SAMPLECOUNT];
void loadSounds(){
  minim = new Minim(this);
  music = minim.loadFile("Space Game.wav");
  
 robot_boom = minim.loadSnippet("explsn.wav");
 player_boom = minim.loadSnippet("Playerexplsn.wav");
 mine_drop = minim.loadSnippet("Mineplacement.wav");
 mine_ready  = minim.loadSnippet("Redmine.wav");

}
void startMusic(){
   music.loop(); 
}



void fx(AudioSnippet a){
   a.pause();a.rewind();a.play(); 
}
void fx_robot_boom() { fx(robot_boom); }
void fx_player_boom() { fx(player_boom); }
void fx_mine_drop() { fx(mine_drop); }
void fx_mine_ready() { fx(mine_ready); }


void closeSounds(){
  
  music.close();
  robot_boom.close();
  player_boom.close();
  mine_drop.close();
  mine_ready.close();
  
}













int CARD = 1;
int TITLE_BEFORE = 2;
int PLAY = 3;
int TITLE_AFTER;

int gameMode = CARD;
PImage cardImage;


int SQ = 10;
float SQSZ = 500 / SQ;
int killed;
Robot player = new Robot(true);

ArrayList<Mine> mines = new ArrayList<Mine>();
ArrayList<Explosion> explosions = new ArrayList<Explosion>();

void setup(){
   size(500,500); 
    loadSounds();
   cardImage = loadImage("smallbill.jpg");
   //gameStart();
   textAlign(CENTER,CENTER);
}

void draw(){
      background(50);

  if(gameMode == CARD){
      drawCard();
   }
  
  
   
   if(gameMode == TITLE_BEFORE || gameMode == TITLE_AFTER || gameMode == PLAY){

     play();      
   }    
   if(gameMode == TITLE_BEFORE || gameMode == TITLE_AFTER){

     drawTitle();
      
   } 
//   if(gameMode == PLAY){
     
  // }
   
}




void drawCard(){
  background(50);
    textAlign(CENTER);
    fill(255);
    image(cardImage,202,150);
   text("an alienbill.com /",250,145);
   text("kirkjerk joint\n\n\naudio by\nrenzo heredia\n\n\n\n(click)",250,310);
}

void drawTitle(){
   textSize(50);
   textAlign(CENTER,CENTER);
   
   fill(0,random(100,255),0);
   
   text("ROBOTISH",0,0,500,500);
   
   
   textSize(20);
   if(gameMode == TITLE_AFTER) text("FINAL ROUND: "+round+"\nROBOTS BLOWN UP:"+killed, 0,0,500,200);
   text("avoid blue head robots\n\nclick to drop delay-action mines",0,300,500,200);
   
}
ArrayList<Robot>robots = new ArrayList<Robot>();
void gameStart(){
  explosions = new ArrayList<Explosion>();
  mines = new ArrayList<Mine>();
 killed = 0; 
  gameMode = PLAY;  
   round = 0;
   roundStart();
   
   
}

int preludeTime = 0;
int round;
void roundStart(){
  round++;
    preludeTime = 200;

   robots = new ArrayList<Robot>();
   
   for(int c = 0; c < round; c++){
      robots.add(new Robot(false)); 
   }


}

void mousePressed(){
   if(gameMode == CARD){
      gameMode = TITLE_BEFORE;
       
 startMusic();
 
      return;
   } 
   if(gameMode == TITLE_BEFORE||gameMode==TITLE_AFTER){
      gameStart();
     return; 
   }
   if(gameMode == PLAY){
     mines.add(new Mine(player)); 
     fx_mine_drop();
   }
}


void play(){
  background(50);
  
//  text(round(frameRate),100,100);
  
  if(preludeTime > 0){
     preludeTime--;
    textSize(40);
    fill(0,random(100,255),0);
   text("ROUND "+round+" READY",0,0,500,500); 
  }

  strokeWeight(2);
  stroke(0,random(100,255),0);
  for(int c = 0; c < SQ; c++){
     line(0,c*(500/SQ),500,c*(500/SQ)); 
     line(c*(500/SQ),0,c*(500/SQ),500); 
  }
  
  for(Explosion e:explosions){
     e.draw(); 
  }
  
    for(Mine m : mines){
     m.move();
    m.draw(); 
  }
  for(Robot r: robots){
    if(preludeTime <= 0) r.move();
    r.draw();
  }
  if(gameMode == PLAY || gameMode == TITLE_BEFORE){
  player.move();
  player.draw();
  }
  ArrayList<Robot> robotsToKill = new ArrayList<Robot>();
  ArrayList<Mine> minesToKill  = new ArrayList<Mine>();
  for(Robot r : robots){
     for(Mine m : mines){
        if(m.hit(r)){
           robotsToKill.add(r); 
           minesToKill.add(m); 
        }
     } 
     if(gameMode == PLAY && player.hit(r)){
       fx_player_boom();
       explosions.add(new Explosion(r));
       gameMode = TITLE_AFTER;
     }
  }
  if(robotsToKill.size() > 0){
    fx_robot_boom();
  }
  for(Mine m : mines){
   if(gameMode == PLAY && m.hit(player)){
       explosions.add(new Explosion(player));
       gameMode = TITLE_AFTER;
       fx_player_boom();
     }
  }
  
  for(Robot r : robotsToKill){
     robots.remove(r);
     killed++;
     explosions.add(new Explosion(r));
  }
  for(Mine m : minesToKill){
     mines.remove(m);
     
  }
  if(robots.size() == 0 && gameMode == PLAY){
    roundStart();
  }

}

int VERT = 1;
int HORIZ = 2;
class Robot{
   float x=250, y=250,tx,ty;
   float xs,ys;
  
  int travel;
  
  boolean isPlayer;
  float S = random(.03,.1);
  Robot(boolean pIsPlayer){
    if(isPlayer) S = .25;
    
    isPlayer = pIsPlayer;
    if(! isPlayer){
       int r = floor(random(4));
       if(r == 0){
         travel = VERT;
          y = (SQSZ/2);
          x = (floor(random(SQ)) * SQSZ )+ (SQSZ/2);
          tx = x;
          ty = 250;
       }
       if(r == 1){
         travel = VERT;
          y = 500- (SQSZ/2);
          x = (floor(random(SQ)) * SQSZ )+ (SQSZ/2);
          tx = x;
          ty = 250;
     }
       if(r == 2){
         travel = HORIZ;
          x = (SQSZ/2);
          y = (floor(random(SQ)) * SQSZ )+ (SQSZ/2);
          tx = 250;
          ty = y;
       }
       if(r == 3){
         travel = HORIZ;
          x = 500- (SQSZ/2);
          y = (floor(random(SQ)) * SQSZ )+ (SQSZ/2);
          tx = 250;
          ty = y;
     }
       
       
    }
  }
  
 void move(){
    if(isPlayer){
       tx = mouseX;
       ty = mouseY;
      xs *= .99;
    
      ys *= .99;
      
      if(x < 0) xs = abs(xs)*.5;
      if(x > 500) xs = -abs(xs)*.5;
      if(y < 0) ys = abs(ys)*.5;
      if(y > 500) ys = -abs(ys)*.5;
      float MAX = 4;
      if(abs(xs) > MAX) xs = MAX * (xs / abs(xs));
      if(abs(ys) > MAX)ys = MAX * (ys / abs(ys));
      
    }

    if(x < tx) xs += S; 
    if(x > tx) xs -= S; 
    if(y < ty) ys += S; 
    if(y > ty) ys -= S; 
    x += xs;
    y += ys;
 }
 
 
   boolean hit(Robot r){
    if(dist(r.x,r.y+15,x,y+15) < 20){
       return true; 
    }
    return false;
  
  
   }   
 
 void draw(){
   stroke(0);
   pushMatrix();
   translate(x,y);
   float a = map(xs,10,-10,-PI/3,PI/3);
   rotate(a);
   if(isPlayer){
     boolean hit = false;
     for(Mine m : mines){
        if(m.hit(this)){
           hit = true;
        } 
     }
     if(hit)fill(250,100,100);
     else fill(250,250,250);
   
   }
   else fill(100,100,250);
   ellipse(0,0-5,20,20);
   fill(50);
   ellipse(0,15,20,20);
   fill(100);
    rect(-10,-5,20,20);
   stroke(255,0,0);
  popMatrix();
 }
 
  
}


class Mine{
   int timeTilReady = 50;
   float x,y;
   Mine(Robot r){
       x = r.x;
       y = r.y+15;
   }
   void move(){
     if(timeTilReady > 0 ){
       timeTilReady--; 
      if(timeTilReady == 0){
       fx_mine_ready();
      }
     }
   }
   void draw(){
     stroke(0);
      if(timeTilReady >0) fill(150);
      else fill(random(120,240),0,0);
      ellipse(x,y,20,20);
   }
   
   boolean hit(Robot r){
    if(dist(r.x,r.y+15,x,y) < 20 && timeTilReady <= 0){
       return true; 
    }
    return false;
  
  
   }   
   
}

class vec2{
   float x,y ;
   vec2(float px, float py){
      x = px; y = py; 
   }
}

class Explosion{
  float x,y;
 ArrayList<vec2> pts = new ArrayList<vec2>(); 
   Explosion(Robot r){
    x = r.x + 5;
    y = r.y + 15;
    for(int i = 0; i < 10; i++){
     pts.add(new vec2(random(-20,20),random(-20,20)));
    }   
   } 
   void draw(){
     pushMatrix();
     translate(x,y);
      fill(100);
      stroke(0);
      beginShape();
      for(vec2 v : pts){
         vertex(v.x,v.y); 
      }
      endShape(CLOSE);
      popMatrix();
   }
   
   
   
}