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 PerlinTerrain extends PApplet {


SoundFile music;
Amplitude amp;
AudioIn in;

int cols, rows;
int scl = 20;
int w = 1500;
int h = 1200;
int sensitivity = 1000;
float flying;
float ballDistance = 150f;
float col = 0;
float textPos = 0;

float[][] terrain;

public void setup () {
  music = new SoundFile(this, "music.mp3");
  music.loop();
  amp = new Amplitude(this);
  in = new AudioIn(this, 0);
  in.start();
  amp.input(in);
  textSize(16);
  
  

  noCursor();
  
  cols = w/scl;
  rows = h/scl;
  
  terrain = new float[cols][rows];
  colorMode(HSB, 100);
  noiseDetail(3);
  noiseSeed(1);
}

public void draw() {
  
  //Generating and mooving noise
  flying -= .025f;
  
  float yoff = flying;
  for (int y = 20; y < rows; y++) {
    float xoff = 0;
    for (int x = 0; x < cols; x++) {
      terrain[x][y] = map(noise(xoff,yoff), 0, 1, -100, 100);
      xoff += .07f;
    }
    yoff += .07f;
  }
  
  background (0);

  noFill();
     
  Greetings();
    
  //Centering stuff
  translate(width/2, h/2);
  
  rotateX(PI/3);
  
  //Bigger ball
  translate(0,0,300);
  translate(sin(yoff) * ballDistance,cos(yoff) * ballDistance,50);
  rotateZ(radians(sin(-flying)*150));
  rotateX(radians(sin(-flying)*150));
  beginShape(TRIANGLE_STRIP);
  sphere(100+amp.analyze()*sensitivity);
  endShape();
  rotateX(-radians(sin(-flying)*150));
  rotateZ(-radians(sin(-flying)*150));
  translate(-sin(yoff) * ballDistance,-cos(yoff) * ballDistance,-50);
  translate(0,0,-300);

  
  //Smaller ball
  translate(0,0,300);
  translate(-sin(yoff) * ballDistance,-cos(yoff) * ballDistance,50);
  rotateZ(radians(sin(-flying)*150));
  rotateX(radians(-sin(-flying)*150));
  beginShape(TRIANGLE_STRIP);
  sphere(100+amp.analyze()*sensitivity);
  endShape();
  rotateX(radians(sin(-flying)*150));
  rotateZ(radians(-sin(-flying)*150));
  translate(sin(yoff) * ballDistance,cos(yoff) * ballDistance,-50);
  translate(0,0,-300);
  
  //Camera position on terrain
  //rotateX(PI/3);
  rotateZ(radians(sin(-flying)*5));
  rotateY(radians(sin(-flying)*5));
  translate(-w/2, -h/2);

  //Drawing vertecies
   for (int y = 20; y < rows; y++) {
     beginShape(TRIANGLE_STRIP);
    for (int x = 0; x < cols; x++) {
      try {
        stroke(map(terrain[x][y]-amp.analyze()*sensitivity,-100,100,0,120), 100, 100);
        vertex(x*scl, y*scl, terrain[x][y]-amp.analyze()*sensitivity);
        vertex(x*scl, (y+1)*scl, terrain[x][y+1]-amp.analyze()*sensitivity);
      } catch (ArrayIndexOutOfBoundsException e) {
        break; 
      }
   }
   endShape();
  }  
}

public void Greetings()
{
  textPos++;
  text("Hello Everyone!", textPos, (sin(flying)*80)+h/3, 501); 
  text("My name is Gramms.", textPos-300, (sin(flying-1)*80)+h/3, 501);
  text("I visited a demoparty for the first time in 2016", textPos-900, (sin(flying-2)*80)+h/3, 501);
  text("I thought it was a simple game development competition.", textPos-1500, (sin(flying-3)*80)+h/3, 501); 
  text("But it turned out to be something much better.", textPos-2100, (sin(flying-4)*80)+h/3, 501);
  text("Since that I'm amazed by demos", textPos-2700, (sin(flying-5)*80)+h/3, 501);
  text("and I was dreaming about that one day...", textPos-3300, (sin(flying-6)*80)+h/3, 501); 
  text("I'll be able to make one. Now here I am with my first demo-like thingy :)", textPos-3900, (sin(flying-7)*80)+h/3, 501);
  text("Greetings to: ", textPos-4200, (sin(flying-8)*80)+h/3, 501);
  text("Lunaticats", textPos-4400, (sin(flying-8)*80)+h/3, 501);
  text("Conspiracy", textPos-4600, (sin(flying-8)*80)+h/3, 501);
  text("Maugli", textPos-4800, (sin(flying-8)*80)+h/3, 501);
  text("Citrus", textPos-5000, (sin(flying-8)*80)+h/3, 501);
  text("Musk", textPos-5200, (sin(flying-8)*80)+h/3, 501);
  text("W0lf", textPos-5400, (sin(flying-8)*80)+h/3, 501);
  text("Blue", textPos-5600, (sin(flying-8)*80)+h/3, 501);
  text("Brian", textPos-5800, (sin(flying-8)*80)+h/3, 501);
  text("Severin", textPos-6000, (sin(flying-8)*80)+h/3, 501);
}
  public void settings() {  fullScreen(P3D); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "--present", "--window-color=#666666", "--hide-stop", "PerlinTerrain" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
