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 chaserboom;
AudioSnippet playerboom;
AudioSnippet tankboom;

void loadSounds(){
  minim = new Minim(this);
  music = minim.loadFile("lowkeyJP.mp3");
  
 chaserboom = minim.loadSnippet("chaserboom.wav");
playerboom = minim.loadSnippet("playerboom.wav");
 tankboom = minim.loadSnippet("tankboom.wav");

}
void startMusic(){
music.pause();
  music.rewind();
  music.play(); 
}



void fx(AudioSnippet a){
   a.pause();a.rewind();a.play(); 
}
void fx_chaserboom() { fx(chaserboom); }
void fx_playerboom() { fx(playerboom); }
void fx_tankboom() { fx(tankboom); }


void closeSounds(){
  chaserboom.close();
  playerboom.close();
  tankboom.close();
  music.close();

  
}









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

int gameMode = CARD;
PImage cardImage;

int tanksKilled;
int          chasersKilled;
int round;

ArrayList<Chaser> chasers= new ArrayList<Chaser>();
ArrayList<Tank> tanks = new ArrayList<Tank>();
ArrayList<Smoke> smokes = new ArrayList<Smoke>();


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

void draw(){
   if(gameMode == CARD){
      drawCard();
   } 
   if(gameMode == TITLE_BEFORE || gameMode == TITLE_AFTER){
      drawTitle();
   } 
   if(gameMode == PLAY){
      play(); 
   }
   if(gameMode == PLAY || gameMode == TITLE_AFTER) showScore();
}


void mousePressed(){
   if(gameMode == CARD){
     startMusic();
      gameMode = TITLE_BEFORE;
      return;
   } 
    if(gameMode == TITLE_BEFORE || gameMode == TITLE_AFTER){
      startGame();
      return;
    }
}

void drawCard(){
  background(200);
    textAlign(CENTER);
    fill(0);
    image(cardImage,202,150);
   text("an alienbill.com /",250,145);
   text("kirkjerk joint\n\n\n(click)",250,310);
}

void drawTitle(){
   background(150,75,40);
fill(255);
   textSize(50);
   textAlign(CENTER,CENTER);
   text("HIT OR MISSILE",0,0,500,500);
   textSize(20);
   text("steer with the mouse - button moves\ndodge missiles and destroy the launchers\n\nclick to play",0,300,500,200);
}

void startGame(){
round = 1;

 tanksKilled = 0;
          chasersKilled = 0;
  gameMode = PLAY; 
  p = new Player();
 p.x = 250;
p.y = 250; 
 smokes = new ArrayList<Smoke>();
 chasers= new ArrayList<Chaser>();
tanks = new ArrayList<Tank>();
reseedTanks();


  
}
void reseedTanks(){
 for(int i = 0; i < round; i++){ 
  tanks.add(new Tank()); 
 }
}

void showScore(){
  fill(255);
  textSize(10);
  text("LEVEL:"+round+" LAUNCHERS DESTROYED:"+tanksKilled+" MISSILES DESTROYED:"+chasersKilled,0,0,500,50);
}

void play(){
   background(150,75,40);
   
  showScore();
   
  for(Tank t : tanks){
    t.move();
    t.draw();
  }
  
  
  ArrayList<Tank>tanksTK = new ArrayList<Tank>();
  ArrayList<Chaser>chasersTK = new ArrayList<Chaser>();

    boolean chaserHit = false;
    boolean tankHit = false;
  for(Chaser c:chasers){
    c.move();
    c.draw();
    for(Tank t : tanks){
      if(c.hit(t)){
         tanksTK.add(t);
         tankHit = true;
         tanksKilled++;
         chasersKilled++;
         chasersTK.add(c);
         smokes.add(new FireSmoke(t));
      }
    }
    for(Chaser c2:chasers){
      if(c.hit(c2)){
        chaserHit = true;
         chasersTK.add(c);
         chasersKilled++;
         smokes.add(new SmallFireSmoke(c));

      }
    }
  }
//  if(chaserHit ) fx_chaserboom();
  if(tankHit || chaserHit) fx_tankboom();
  tanks.removeAll(tanksTK);
  chasers.removeAll(chasersTK);
  
  
  
  if(tanks.size() == 0){
     round++;
    reseedTanks(); 
  }
  
  
  p.move();
  p.draw();

 for(Chaser c:chasers){
    if(c.hit(p)){
      fx_playerboom();
      startMusic();
       gameMode = TITLE_AFTER;
    } 
 }


  ArrayList<Smoke> smokesTK = new ArrayList<Smoke>();
  for(Smoke s : smokes){
     s.draw();
    if(s.aged()){
       smokesTK.add(s);
    } 
  }
  smokes.removeAll(smokesTK);
}


class Player extends rotater{
  void move(){
    if(mousePressed) speed = 5; else speed = 0;
     angle = atan2(mouseY - y, mouseX - x); 
      calcangles();
    super.move();
    
    if(random(100) < 40){
       smokes.add(new Smoke(this)); 
    }
    
  }
 void draw(){
   fill(255);
    stroke(0);
    // noFill();
    // ellipse(x,y,20,20);
    pushMatrix();
    translate(x,y);
    rotate(angle);

    triangle(10,0,-8,-8,-8,8);
    
    triangle(10,0,-8,-2,-8,2);

    popMatrix();
  }
}

class rotater {
    void draw(){
    stroke(0);
    // noFill();
    // ellipse(x,y,20,20);
    pushMatrix();
    translate(x,y);
    rotate(angle);
    
    triangle(10,0,-8,-2,-8,2);

    popMatrix();
//line(250,250,x,y);
  }
  String ima;
  
  void turn(float dir){

    angle += (.15 * dir);
    calcangles();

  }
  void calcangles(){
    angcos= cos(angle);
    angsin = sin(angle);
  }
  float x,y,angle,angcos,angsin, speed;


boolean hit(rotater r){
  if(this == r) return false;
  float dist = sqrt(pow(x-r.x,2) +  pow(y-r.y,2));
   if(dist < 20){
      return true;
   }
  return false;
}




  void move(){
    x +=  angcos* speed; 
    y += angsin * speed; 

  }
}


class Tank extends rotater{
  int time;
  Tank(){
    
     time = round(random(50,150));
    
     float a = random(2*PI);
    x =  250+cos(a)*200;
    y =  250+sin(a)*200;
  }
   void draw(){
     fill(255);
      ellipse(x,y,30,30);
      
      fill(128);
      if(time < 50) fill(128,0,0);
      noStroke();
      angle = atan2(p.y-y,p.x-x);
      ellipse(x+cos(angle)*5,y+sin(angle)*5,15,15);      
   } 
   void move(){
     time--;
     if(time <= 0){
        time = round(random(200,450));
         fx_chaserboom();
       chasers.add(new Chaser(this)); 
     }
     
   }
  
}

rotater p;

class Chaser extends rotater{

float mysize=20;
  float turnspeed;

  Chaser(){
    speed = 3;
    turnspeed = .03;
    angle = -PI/2;
active = true;
    calcangles();
    ima="chaser";
  }

  Chaser(Tank t){
    speed = 3;
    turnspeed = .03;
    angle = t.angle;
active = true;
    calcangles();
    ima="chaser";
    x = t.x+25*cos(angle);
    y = t.y+25*sin(angle);
  }

void draw(){
   fill(200,50,50);
  super.draw(); 
}
boolean killed = false;
boolean active = false;

  void move(){
    if(active && (!killed)){

   float  mentalchaserx = x;
float     mentalplanex = p.x;
    float dx = (mentalplanex -mentalchaserx);
    
    
    float dy = ( p.y - y);
    float wantangle = atan2(dy, dx);
    float anglediff = (angle - wantangle);  

    anglediff /= PI;
//this next bit catches the "runaround"
    if(anglediff > 1){
        anglediff -= 2;
    }
    if(anglediff < -1){
        anglediff += 2;
    }

//print("wantangle:"+(wantangle/PI)+"    angle  "+(angle/PI)+" diff: "+ (anglediff)+"  ");
    if(anglediff > 0){
    //  println(" <-\\");
    angle -= turnspeed; 
    } 
    else {
    //  println(" /->");

      angle += turnspeed; 
    }

    //stroke(255,0,0);
    //line(250,250,250+(cos(wantangle) * 30), 250+(sin(wantangle)*30));

//    line(250,250,245,245);
  //  line(250,250,255,255);

    //angle +=  turnspeed;
    calcangles();
    super.move();
    }
  }

}


class Smoke{
  float x,y,s;
  Smoke(rotater m){
     x = m.x;
    y = m.y;
    s = 1;
  }
  void draw(){
    noStroke();
     if(s > 0.2){
        float sz = 2 + 1/s;
        fill(255,255*s);
        ellipse(x,y,sz,sz);
     } 
  }
  boolean aged(){
     s -= .01;
    if(s < 0) return true;
   return false; 
  }
}


class FireSmoke extends Smoke{
  FireSmoke(rotater m){
     super(m); 
  }
  void draw(){
    noStroke();
     if(s > 0.2){
        float sz = 20 + (10*1/s);
        fill(255,0,0,255*s);
        ellipse(x,y,sz,sz);
     } 
  }
  boolean aged(){
     s -= .005;
    if(s < 0) return true;
   return false; 
  }
}

class SmallFireSmoke extends Smoke{
  SmallFireSmoke(rotater m){
     super(m); 
  }
  void draw(){
    noStroke();
     if(s > 0.2){
        float sz = 10 + (5*1/s);
        fill(255,0,0,255*s);
        ellipse(x,y,sz,sz);
     } 
  }
  boolean aged(){
     s -= .005;
    if(s < 0) return true;
   return false; 
  }
}