import ddf.minim.*;
import ddf.minim.signals.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
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;
AudioPlayer fanfare;

AudioSnippet[] scratch = new AudioSnippet[SAMPLECOUNT];
void loadSounds(){
   for(int i = 0; i < SAMPLECOUNT; i++){
    scratch[i] = minim.loadSnippet("Shave_var"+((i%4)+1)+".wav");  
  }
  music = minim.loadFile("bgmusic.wav");
  fanfare = minim.loadFile("victorysound.wav");
}

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

void winMusic(){
  fanfare.rewind();
   fanfare.play(); 
}

void scratch(){
  int i = int(random(SAMPLECOUNT));
  AudioSnippet s = scratch[i];
  s.pause();
  s.rewind();
  s.play();
}
void closeSounds(){
  
   for(int i = 0; i < SAMPLECOUNT; i++){
    scratch[i].close();
  }
  
  music.close();
  fanfare.close();
  
}



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

int gameMode = CARD;
PImage cardImage;

float starting;

Eye lefteye,righteye;
Razor razor ;
void setup(){
   size(500,500); 
   cardImage = loadImage("smallbill.jpg");
      smooth();
   lefteye = new Eye(150,200);
   righteye = new Eye(350,200);
   razor = new Razor();
   noCursor();
 doBristles();
 minim = new Minim(this);

 loadSounds();
}

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


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

ArrayList<Bristle> bristles = new ArrayList<Bristle>();

void startGame(){
   gameMode = PLAY; 
   if(bristles.size() == 0) doBristles();
  starting = millis();
}

void doBristles(){
bristles = new ArrayList<Bristle>();

   for(int i = 0; i < 500; i++){
       bristles.add(new Bristle());
   }  
}

void drawCard(){
  background(200);
    textAlign(CENTER);
    fill(0);
    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(){
//  background(200);
   textSize(80);
   fill(200,0,200);
   textAlign(CENTER,CENTER);
   text("SHAVE\nFACE\nRACE",0,0,500,500);
  textSize(20);
  text("click to play",0,0,500,60);

//   if(gameMode == TITLE_BEFORE) || gameMode == TITLE_AFTER){


}

float score = 0;
float bestScore = 99999999;
float smile = 1;

void play(){
   background(200);

  fill(255,200,200);
  stroke(0);
  strokeWeight(3);
 ellipse(250,250,400,400); 
 
  
lefteye.draw();
righteye.draw();
noFill();
arc(250,250,70,70,0,PI);


for(Bristle b : bristles){
   b.draw(); 
}

  stroke(0);
 smile = map(bristles.size(),0,500,1,-1);

 noFill();
 bezier(150,350,
 150,350+(smile * 80),
 350,350+(smile * 80), 
 350,350);
 //line(150,350,350,350);

if(gameMode == PLAY){
razor.draw(); 
 razor.cut();
if(bristles.size() == 0){
   endGame(); 
}
}




if(gameMode == PLAY || gameMode == TITLE_AFTER){
 textSize(20);
 if(gameMode == PLAY){
   score = (millis() - starting)/100;
   score = int(score);
   score /= 10;
 }
 String s =  "your time "+score;
if(gameMode == TITLE_AFTER){
   s +=  "  best time "+bestScore;
}

  text(s,0,440,500,60);
}
}


void endGame(){
   gameMode = TITLE_AFTER;
    score = (millis() - starting)/100;
   score = int(score);
   score /= 10;
   if(bestScore > score){
      bestScore = score; 
   }
   winMusic();
}

class Eye{
   float x, y;
  Eye(float px, float py){
     x = px; 
     y = py;
  } 
  void draw(){
    fill(255); stroke(0);
    ellipse(x,y,80,80);
    fill(0);
   float a = atan2( mouseY - y,  mouseX-x);
   float nx = cos(a) * 30;
   float ny = sin(a) * 30;
   ellipse(x + nx, y +ny,20,20);
   
  }
}




class Razor{
  float x,y;
   void draw(){
     fill(100);
         x = mouseX;
         y = mouseY;
         pushMatrix();
         translate(x,y);
         float a = atan2(250-y,250-x);
         rotate(a+PI/2);
         rect(-30,-20,60,20);
         rect(-10,0,20,100);
         popMatrix();
   }
  void cut(){
    ArrayList<Bristle> bristlesToKill = new ArrayList<Bristle>();
    boolean doScratch = false;
     for(Bristle b : bristles){
        if(dist(x,y,b.x,b.y) < 20){
          doScratch = true;
          bristlesToKill.add(b); 
         }
     }
     bristles.removeAll(bristlesToKill);
     if(doScratch) scratch();
     
     
  } 
}


class Bristle{
  float x,y,a;  
  Bristle(){
    a = random(0,PI);
    float out = random(40,200);
    x = 250+cos(a) * out;
    y = 250+sin(a) * out;
  }
  void draw(){
    stroke(200,100,0);
    line(x,y,x+cos(a)*4,y+sin(a)*4);
  }    
  
}