import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;

AudioSnippet scream[] = new AudioSnippet[10];
AudioSnippet bam;

HashSet pixies = new HashSet();
HashSet fallingpixies = new HashSet();
HashSet deadpixies = new HashSet();
int fps = 30;
rock r = new rock();
void setup(){
  size(400,400,P3D);
  rectMode(CENTER);
  frameRate(fps);
Minim.start(this);
 for(int i = 0; i < 10; i++){
     scream[i] =  Minim.loadSnippet(i+".mp3");
  }
bam =   Minim.loadSnippet("bam.mp3");
    textFont(loadFont("Arial-Black-14.vlw"),14);

}

void resetgame(){
    timer = 0 ;
  for(int i = 0; i < 10; i++){
    pixies.add(new pixie(scream[i]));
  }
}

void stop()
{

    for(int i = 0; i < 10; i++){
scream[i].close();

  }
  super.stop();
}

void mousePressed(){
  if(gameon){
  r.isFalling = true; 
  r.playedSound = false;
  } else {
     gameon = true; 
     resetgame();
  }
}

boolean gameon = false;



float smalltimer;
int timer = -1;

void draw(){
  smalltimer++;
if(smalltimer >= fps && gameon ){
   smalltimer = 0;
   timer++;
} 

if(pixies.size() == 0){
  gameon = false;
  
  
}


    Iterator i;
  background(100,100,200);
if(gameon){

    text("Timer:"+timer+"  pixies left:"+pixies.size(),50,50);
} else {
  if(timer >= 0){
     text("pixiesmash! click to play - last score "+timer,50,50);
  } else {
      text("click to play pixiesmash! ",50,50);
  }
}
  translate(200,200,0);

  float yrot = (mouseX+200.0)/300.0;

  // rotateY(1+yrot);
  rotateX(-.25);
 
  stroke(255,100+(20.0*sin(smalltimer)));
  strokeWeight(2);
  fill(0,0);
  box(200,200,200);

  
   i = fallingpixies.iterator();
  while(i.hasNext()){
    fallingpixie f = (fallingpixie) i.next(); 
    if(f.move(r)){
      deadpixies.add(new deadpixie(f));
      i.remove();
    }
    f.draw();
  }
 i = deadpixies.iterator();
  while(i.hasNext()){
    deadpixie f = (deadpixie) i.next(); 
    f.draw();
  }

  
  if(r.move()){
    r = new rock(); 
  };
  r.draw();

 i = pixies.iterator();
  while(i.hasNext()){
    pixie f = (pixie) i.next(); 
    if(f.move(r)){
      fallingpixies.add(new fallingpixie(f));
      i.remove();
    }
    f.draw();
  }


}

class deadpixie{
   float  x,y,z;  
  float r,g,b;
  deadpixie(fallingpixie f) {
    x = f.x;
    y = f.y;
    z = f.z;
    r = f.r;
    g = f.g;
    b = f.b;
  }
  
  float ra = random(20);
float s = 2;
  void draw(){
    stroke(r,g,b,100+(ra*sin(smalltimer)));
    line(x-s,y,z-s,x+s,y,z+s);
    line(x+s,y,z-s,x-s,y,z+s);
  }

}

class fallingpixie{
  float  x,y,z;  
  float r,g,b;
  fallingpixie(pixie f) {
    x = f.x[0];
    y = f.y[0];
    z = f.z[0];
    r = f.r;
    g = f.g;
    b = f.b;
  }

  boolean move(rock r){
    
    y = r.y + (r.size/2); 
    if(y >= 100){
     return true; 
    } else {
       return false; 
    }
  }
  float s=2;
  void draw(){
    stroke(r,g,b,120);
    line(x-s,y,z-s,x+s,y,z+s);
    line(x+s,y,z-s,x-s,y,z+s);
  }

}

class pixie{
  float maxspeed = 10;
  float speed = 1;
  int pieces = 3;
  float maxplace = 100;
  float x[] = new float[pieces]; 
  float y[] = new float[pieces]; 
  float z[] = new float[pieces]; 
  float xs,ys,zs;
  float r,g,b;
  AudioSnippet snip;
  pixie(AudioSnippet ps){
    snip = ps;
    r = g = b = 255;
    if(int(random(2)) == 1){
      r = 200;
    } 
    if(int(random(2)) == 1){
      g = 200;
    } 
    if(int(random(2)) == 1){
      b = 200;
    } 
  }

  void draw(){

    for(int i = 1; i < pieces; i++){
      stroke(r,g,b,120+(120 / i));
      line(x[i-1],y[i-1],z[i-1], x[i],y[i],z[i]);
      line(x[i-1],y[i-1]+1,z[i-1], x[i],y[i]+1,z[i]);
    }
    for(int i = 1; i < pieces; i++){
      stroke(0,0,0,20);
      line(x[i-1],100,z[i-1], x[i],100,z[i]);
      line(x[i-1],100,z[i-1], x[i],100,z[i]);
    }

  }
  boolean move(rock r){
    for(int i = pieces - 1; i > 0; i--){
      x[i] = x[i-1];
      y[i] = y[i-1];
      z[i] = z[i-1];
    } 
    if(int(random(2))==1){
      xs += speed; 
    } 
    else {
      xs -= speed; 
    }
    if(int(random(2))==1){
      ys += speed/10; 
    } 
    else {
      ys -= speed/10; 
    }
    if(int(random(2))==1){
      zs += speed; 
    } 
    else {
      zs -= speed; 
    }
    x[0] += xs;
    y[0] += ys;
    z[0] += zs;

    xs = constrain(xs, -maxspeed,maxspeed);
    ys = constrain(ys, -maxspeed,maxspeed);
    zs = constrain(zs, -maxspeed,maxspeed);

    if(abs(x[0]) > maxplace){
      xs =  -1; 
      x[0] = maxplace * (x[0] / abs(x[0]));
    }
    if(abs(y[0]) > maxplace){
      ys *= -1; 
      y[0] = maxplace * (y[0] / abs(y[0]));
    }
    if(abs(z[0]) > maxplace){
      zs *= -1; 
      z[0] = maxplace * (z[0] / abs(z[0]));
    }


    if(  

    between(x[0],r.x-(r.size/2),r.x+(r.size/2)) 
      &&   
      between(z[0],r.z-(r.size/2),r.z+(r.size/2)) 

    ){

      if(     r.isFalling && between(y[0], r.y+(r.size/2), r.y+ (r.size/2) + r.yspeed)){ //is in path!
        stroke(255);
         snip.rewind();      snip.play();
        return true;
      } 
      else {
        if(isNear(x[0], r.x-(r.size/2))){
          x[0] = r.x-(r.size/2);
          xs = 0; 
        }
        if(isNear(x[0], r.x+(r.size/2))){
          x[0] = r.x+(r.size/2);
          xs = 0; 
        }
        if(isNear(x[0], r.z-(r.size/2))){
          x[0] = r.z-(r.size/2);
          zs = 0; 
        }
        if(isNear(x[0], r.z+(r.size/2))){
          x[0] = r.z+(r.size/2);
          zs = 0; 
        }

      }
    }
    return false;
  }


}

boolean isNear(float a, float b){
  if(abs(a-b) < 10){
    return true; 
  }
  return false;
}

boolean between(float a, float b, float c){
  return( a >= b && a <= c);
}
boolean go(float a ){
  return true; 
}

class rock{
  float size = 50;
  float x,y,z;

  boolean isFalling = false;
  boolean isRising;

  float yspeed;
  rock(){
    y = -100 - (size/2) ; 

  }
boolean playedSound;
  boolean move(){
    // x = mouseX;
    if(! isFalling && !isRising){
      z = mouseY - 200; 
      z = constrain(z,-(75),75);
      x = mouseX - 200; 
      x = constrain(x,-(75),75);
      return false;
    } 
    else {
      if(isFalling){
      y += yspeed;

      yspeed += .2;
      if(! playedSound && y > 80 - (size/2)){
        bam.rewind();      bam.play();
        playedSound = true;
      }
      if(y > 100 - (size/2)){

        isFalling = false;
        isRising = true;
        return false; 
      }
      return false;
    }
    }
    if(isRising){
      yspeed = -4;
      y += yspeed;
      if(y <= -100 - (size/2)){
         y =  -100 - (size/2);
         isRising = false;
         yspeed=0;
      }
    }
    return false;
  }

  void draw(){
    pushMatrix();
    stroke(0,0);
    fill(0,40);
    translate(x,100,z);
    box(size,1,size);
    popMatrix(); 


    pushMatrix();
    stroke(128);
    fill(200,255);
    translate(x,y,z);
    box(size,size,size);
    popMatrix(); 



  }
}