import processing.core.*; 
import processing.xml.*; 

import ddf.minim.analysis.*; 
import ddf.minim.*; 
import processing.opengl.*; 

import java.applet.*; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.FocusEvent; 
import java.awt.Image; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class musiq extends PApplet {





float f = 0;
float s = 0;
float tim = 0;
float tim2 = 0;
float f1 = 0;
float starttime = 0;
int napu = 0;
float by = 0;
int start = 0;
Minim minim;
AudioPlayer jingle;
FFT fft;
BeatDetect beat;
int BALLCOUNT = 500;

Ball[] balls;
Ball2[] balls2;


public void setup() {
  size(1280,720,OPENGL);
  minim = new Minim(this);
  jingle = minim.loadFile("PaulWhitemanwithJohnnyHauser-GloomySunday.mp3", 1024);
  fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
  frameRate(60);

  balls = new Ball[BALLCOUNT];
  int j = 0;
  for (j=0;j<BALLCOUNT/2;j++) {
    balls[j] = new Ball(15);
  }
    for (j=BALLCOUNT/2;j<BALLCOUNT;j++) {
    balls[j] = new Ball(width-65);
  }
  
  balls2 = new Ball2[25];
  
  for (j=0;j<25;j++) {
    balls2[j] = new Ball2((int)random(15,height-15));
  }

  
  jingle.play();
  beat = new BeatDetect();
  starttime = millis();
  println("start:" + starttime);

  

}

public void draw() {
            tim2=millis()-starttime;
          tim = tim2/1000;


              background(42+cos(millis()*0.0001f+s*0.01f)*18);
        if (napu == 1) {
          napu = 0;
          println("----------------------------tim:" + tim);
        }

        if ((tim >= 0 && tim <  11.1f) || (tim >= 19.3f && tim <  38.5f)) { 

        stroke(192);
        strokeWeight(2);
        noFill();
      float f = 0;
      for(int i=0;i<256;i+=5) {
        f+= fft.getBand(i)*3;
}
        f = f / (256/5);
        float s2 = f*15;
        if (s2 <  s) {
          s-=0.5f;
        } else {
          s+=0.5f;
        }
        

        

        for (int j=0; j<s/2;j++) {
        stroke(64+j*3+cos(millis()*0.01f+j)*32,64+cos(millis()*0.0009f-j*0.1f)*128);
                float x = cos(s*0.01f+j*0.1f)*width/4;
        ellipse(width/2+x,height/2,s+j*j,s+j*j);
        }
        
        }
        
        if ((tim >= 12 && tim <  45.6f) | (tim >  190))  {
          
               float f = 0;
      for(int i=0;i<256;i+=5) {
        f+= fft.getBand(i)*3;
}
        f = f / (256/5);
        float s2 = f*15;
        if (s2 <  s) {
          s-=0.5f;
        } else {
          s+=0.5f;
        }
        
        if (tim <  16) {
          f1+=0.2f;
        }

        
        for (int q = 0; q <  25; q++) {
          for(int w = 0; w <  15; w++) {

            stroke(42+f1,64+cos((q*w)*0.01f+millis()*0.001f)*128);
            noFill();
            ellipse(35+q*65, 15+w*65, 50+s-w, 50+s-q);
          }
        }
          
        }
        
        if (tim >  50 && tim <  209) {
                             for (int ll=0;ll<25;ll++) {
            if (balls2[ll].dir == 0) {
            stroke(66,constrain(balls2[ll].ax,0,255));
            } else {
              stroke(66,255-constrain(balls2[ll].ax*0.15f,0,255));
            }
            
            if (tim >  200) {
              stroke(66,255-((tim-200)*28));
            }
            strokeWeight(3);
            ellipse(balls2[ll].ax,balls2[ll].ay,15+ll,15+ll);
            if (balls2[ll].dir == 0) balls2[ll].ax+=abs(cos(millis()*0.001f*cos(ll))*2);
            else balls2[ll].ax-=abs(cos(millis()*0.001f*cos(ll))*2);
            
            if (balls2[ll].ax >  width+15) {
              balls2[ll].ax = -15;
              balls2[ll].dir = 0;
            }

            if (balls2[ll].ax <  -30) {
              balls2[ll].ax = width+15;
              balls2[ll].dir = 1;
            }
            
            
          }

          int bb = 0;
          strokeWeight(2);

            float bbstart = (tim-50)*6;
            if (bbstart >  BALLCOUNT) bbstart = BALLCOUNT;
            
            if (tim >  180) bbstart = BALLCOUNT-(tim-180)*25;
            if (bbstart <  0) bbstart = 0;
            
          for (bb=0;bb<bbstart;bb++) {
            float bs = cos(millis()*0.001f+bb)*32;
            float xmod = 0;
            if (tim >  150) xmod = sin(millis()*0.001f+bb)*constrain((tim-150)*2, 0, 64);
            stroke(128,(128-bs*4));
            ellipse(balls[bb].ax+xmod, balls[bb].ay, bs, bs); 
            if (balls[bb].dir == 0) balls[bb].ay-=0.4f;
            else balls[bb].ay+=0.4f;
            if (balls[bb].ay <  -15) balls[bb].ay = height+15;
            if (balls[bb].ay >  height+15) balls[bb].ay = -15;
            
          }
        }

        
        if ((tim >  57.5f && tim <  67.7f) | (tim >  71.8f && tim <  81) | (tim >  85.8f && tim <  95.4f) | (tim >  98.9f && tim <  102.05f) | (tim >  104.7f && tim <  114.25f) | (tim >  118.35f && tim <  128.3f) | (tim >  132.7f && tim <  142.5f) | (tim >  145 && tim <  148.5f) ) {
                    float f = 0;
      for(int i=0;i<256;i+=5) {
        f+= fft.getBand(i)*3;
}
        f = f / (256/5);
        float s2 = f*15;
        if (s2 <  s) {
          s-=3;
        } else {
          s+=2;
        }
        
        for (int j=0; j<s/8;j++) {
          stroke(192,255-j*30);
          strokeWeight(1);
          ellipse(width/2,height/2,width/4,j*12);
        }
        
        } else {
          
          
          if (tim >  57.5f) {
   
          
        stroke(192);
        strokeWeight(2);
        noFill();
      float f = 0;
      for(int i=0;i<256;i+=5) {
        f+= fft.getBand(i)*3;
}
        f = f / (256/5);
        float s2 = f*15;
        if (s2 <  s) {
          s-=0.5f;
        } else {
          s+=0.5f;
        }
        

 
        for (int j=0; j<s/3;j++) {
        stroke(64+j*3+cos(millis()*0.01f+j)*32,64+cos(millis()*0.0009f-j*0.1f)*200);
                float x = cos(s*0.01f+j*0.1f)*width/4;
        ellipse(width/2+x,height/2,s+j*j,s+j*j);
        }
        
          }
        }
        
        
        if ((tim >  68.7f && tim <  73) | (tim >  82.7f && tim <  87) | (tim >  96.9f && tim <  101) | (tim >  115.5f && tim <  120) | (tim >  129.7f && tim <  134) | (tim >  143.5f && tim <  148) | (tim >  176.3f && tim <  181) | (tim >  189 && tim <  194)) {
 
 if (start == 0) by = -285/2;
 start = 1;
 stroke(75,constrain(55+by,0,255));
 by+=5;
 ellipse(width/2+cos(by*0.01f)*64,by,285,285);
 } else {
  start = 0;
}

        
               if (tim >  209.7f) exit();        

          fft.forward(jingle.mix);
/*
          float maxp = random(1000, 2000);

          for (int l = 0; l < maxp; l++) {
            float rx = random(1,width-1);
            float ry = random(1,height-1);
            color pc = color(random(32,64),random(32,60));
            set((int)rx,(int)ry,pc);
          }
*/

       //   println("tim:" + tim);

}

public void stop()
{
  jingle.close();
  minim.stop();  
  super.stop();
}

public void keyPressed() {
  napu = 1;
}

class Ball {
   float ax;
   float ay;
   int dir;
  
   Ball(int x) {
     ax = x+random(1,50);
     ay = random(1,height);
     dir = (int)random(0,2);
   }
   
}

class Ball2 {
   float ax;
   float ay;
   int dir;
  
   Ball2(int y) {
     ax = random(-25);
     ay = y+random(1,15);
     dir = (int)random(0,2);
   }
   
}


  static public void main(String args[]) {
    PApplet.main(new String[] { "--present", "--bgcolor=#666666", "--stop-color=#cccccc", "musiq" });
  }
}
