import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import processing.sound.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class fasti extends PApplet {



// Declare the processing sound variables 
SoundFile sample;
Amplitude rms;

// Declare a scaling factor
float scale = 5.0f;

// Declare a smooth factor
float smoothFactor = 0.25f;

// Used for smoothing
float sum;

PGraphics g;
PGraphics g2;
PGraphics g3;
PFont font;
int lippu[];

public void setup() {
  //size(1920, 1080, P3D);
  
  noCursor();
  font = loadFont("BIZ-UDMincho-Medium-22.vlw");
  textFont(font);
  g = createGraphics(640,360);
  g2 = createGraphics(640,360);
  g3 = createGraphics(640,360);


  g3.beginDraw();
  g3.background(0,0);
  g3.endDraw();

  //Load and play a soundfile and loop it
  sample = new SoundFile(this, "music.wav");

  // Create and patch the rms tracker
  rms = new Amplitude(this);
  rms.input(sample);

  lippu = new int[16];

  frameRate(60);

}      

boolean musicinit = false;

int lh = 21;

int wx = 2;
int wy = lh;

String testi = "Let me tell you about chaos. Here's my theory: chaos is the noise of the universe on the carrier wave of creation - a blindingly buzzing generator of a range of absolutes, the edges blending on edges like a rusty razor blade of the cosmos - the bleeding edge of a whole that is ever expanding, bursting forth from a zero position of unknowably complex initial seeding parameters - one could argue that the universe is a chaotic result of the computational return value of a previous universe, all calculating in the depths of a universe simulating computer of truly cosmic scales. Chaos and order, the traditionally binary human mind sees these concepts as somehow separate entities, whereas I see them as the range limits of plus and minus on a scale of multi dimensionally complex vectors rotating in infinite spins of fate, affecting and effecting, reacting and not reacting. We reach the absolute minima and round back to the friendly embrace of the maxima, the largest but somehow so breath takingly close to flipping back like a truncated sailor on a sliding scale of stars. stars. stars. stars. stars. stars... <<<<<<< code by visy - music by junior85 'Left For Deadish' . . . all rights reserved but none taken for granted. AS.        ";

String[] texti = splitTokens(testi);
int wi = 0;
int sp = 0;
int ch = 0;

public boolean drawWord() {
    boolean lb = false;
    
    String tx = texti[wi] + " ";

        if (wi < texti.length-1) wi++;
        else {
          exit(); 
        }

    for(int i = 0; i < tx.length(); i++) {
      ch++;
      if((tx.charAt(i) == ' ' && ch > 57) || ch > 68) lb = true;
    }
    
    ch++;

    if (wi % 4 == 0)
      tx = tx.toUpperCase();
    
    g3.stroke(0);
    g3.fill(0);
    g3.text(tx,wx-1,wy+1-2);

    g3.stroke(255);
    g3.fill(255);
    
    g3.textFont(font);
    g3.text(tx,wx,wy-2);

    wx+=g3.textWidth(tx);
    return lb;
}

int frame2 = 0;

public void draw2() {  // this is run repeatedly. 
  g3.beginDraw();
  g3.textFont(font);

  frame2++;

  if (frame2 % 12 != 0) return; 
  
  if (drawWord()) {
      wx = 2;
      wy+=lh;
      if (wy > g3.height) { wy = lh; g3.background(0,0); }
      ch = 0;
  }
  if (frame2 % 16 == 0) g3.filter(INVERT);
  g3.endDraw();
}

int frame = 0;

public void draw() {
  float t = millis();
  
  sum += (rms.analyze() - sum) * smoothFactor;  
  float rmsScaled = sum * (g.height/2) * scale;

  g.beginDraw();
  g.background(0, 0, 255);
  
  
  float vaihtu = sum * 16 > 1 ? sum*16 : sum*4; 
  
  if (cos(t*0.001f) > 0.5f) {
  
    frame++;
    if (frame % 8 == 0) {
      for (int i = 0; i < 16; i++) {
        lippu[i] = color( random(192), random(128), random(195));
      }
    }
  }
  
  float divv = 16 + vaihtu;
  
  float bh = g.height/17;
  int yy = 0;
  for (int y = 0; y < g.height; y+=bh) {
    g.noStroke();
    g.fill(lippu[yy % 16]);
    g.rect(0,y,g.width,y+bh);
    yy++;
  }
  g.noFill();
  g.stroke(255, 255, 255);

  float rs = 92+cos(t*0.001f)*32;
  
  for (int x = -g.width*2; x < g.width*2; x+=rs) {
    g.strokeWeight(abs(divv*vaihtu*cos(x*0.1f)));
    g.pushMatrix();
    g.translate(-g.width*3+t*0.1f-x+g.width/2-rs/2,64+g.height/2-rs/2);
   // g.rotate(t*0.001);
    g.rect(0, 0, rs, rs);
    g.translate(-g.width/2-rs/2,-g.height/2-rs/2);
    g.popMatrix();
  
  }
 
  g.endDraw();
 
  g2.beginDraw();
  g2.tint(255,128+cos(t*0.05f)*0.5f);
  g2.image(g,0,0,g2.width,g2.height);
  if (frame2 % 2 == 0) g2.filter(GRAY);

  g2.endDraw();
  draw2();
 
 tint(255,255);
  image(g2,0,0,width,height);
  tint(255,192+cos(t*0.003f+sum*10)*32);
  image(g3,0,0,width,height);
 
  if (!musicinit) sample.play();
  musicinit = true;
}
  public void settings() {  fullScreen(P3D); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "--present", "--window-color=#000000", "--hide-stop", "fasti" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
