import com.dhchoi.CountdownTimer;
import com.dhchoi.CountdownTimerService;
//
import ddf.minim.*;
import ddf.minim.ugens.*; 
import ddf.minim.analysis.*;

class PlayState extends State
{

  PranaCircle prana;
  PFont font;
  PFont fontInfo;
  PFont font200;
  ParticleSystem ps;

  CountdownTimer timer;
  String timerCallbackInfo = "";
  int  timeLeft = 2;
  String breathPhase;
  int phaseId = 0;
  String [] breathPhases = new String[]{"Inhalar", "Retener", "Exhalar", "Relajar" };
  int breathCycles = 10;
  int breathCyclesLeft = breathCycles;
  int [] breathPattern = {2, 1, 3, 2};
  //Minim minim;
  //AudioInput in;
  float inputLerp;
  AudioOutput out;
  Oscil wave;

  AudioSample breathIn;
  AudioSample breathOut;
  AudioSample bell;
  AudioSample bowl;

  boolean startGame = false;
  boolean gameOver = false;
  int startCountdown = 3; // coutdown in secs
  int countTime = 3;

  int totalPranaPoints = 0;
  PImage bgImg;

  void setup()
  {
    
  sprite = loadImage("sprite.png");
  ps = new ParticleSystem(1000);
  prana = new PranaCircle(width/2, height/2, 200);
  bgImg = loadImage("fondo.png");
  font = createFont("spacefri.ttf", 30);
  font200 = createFont("spacefri.ttf", 200);
  fontInfo = loadFont("Consolas-14.vlw");
  textFont(font);
  initAudio();
  initBreathPhase();
  }
  
void initAudio() {
  //minim = new Minim(app);
  //in = minim.getLineIn();
  bell = minim.loadSample("tibetan_bell.mp3", 512);
  bowl = minim.loadSample("bowl.mp3",512);
  out = minim.getLineOut();
  wave = new Oscil(440, 0.5f, Waves.SINE);
  wave.patch(out);
}

void initBreathPhase() {
  phaseId = 0;
  breathPhase = breathPhases[phaseId];
  int phaseDuration = breathPattern[phaseId];
  timeLeft = phaseDuration;
  int totalCicleDuration = 0;
  bell.trigger();
  for (int duration : breathPattern) {
    totalCicleDuration += duration;
  }

  long totalDuration = totalCicleDuration*breathCycles*1000+startCountdown*3000;
  //println(breathPhase+":"+timeLeft);
  timer = CountdownTimerService.getNewCountdownTimer(app).configure(1000, totalDuration).start();
}

 
void breathInfo() {
  //textFont(fontInfo,14);
  fill(255);
  textSize(30);
  text("Wave: "+breathCyclesLeft, width-180, 30);
  textAlign(CENTER);
  text(breathPhase, width/2, height/2+250);
  text(timeLeft, width/2, height/2+280);
  textAlign(LEFT);
}

void pranaLogic(){
  float inLvl = in.left.level()*50;
  float eMin = 0.5;
  float eMax = 20;
  float iMin = 0.2;
  float iMax = 12;
  println(in.left.level()*50);
  if(breathPhase == "Exhalar"){
    if(inLvl > eMin && inLvl < eMax){
      prana.contract();
    }
  }else if(breathPhase == "Inhalar"){
    if(inLvl > iMin && inLvl < iMax){
      prana.expand();
    }
  }
}


void draw() {
  background(170, 137, 228);
  image(bgImg,0,0);
  fill(255);
  textFont(font, 30);
  text("Pranawave", 30, 30);
 
  if(startGame){
     ps.update();
     ps.display();
     ps.setEmitter(width/2, height/2);
  }
 
  prana.draw();
  breathInfo();
  drawWaveForm();
  
  if(gameOver){
    textFont(font200,100);
    fill(255,200);
    textAlign(CENTER);
    text("GAME OVER", width/2, height/2);
    textAlign(CORNER);
    currentState = new MainMenuState();
    currentState.setup();
  }

  if (!startGame) {
    drawStartCountdown();
  } else {
    pranaLogic();
  }
}

void drawStartCountdown() {
  textAlign(CENTER, CENTER);
  textFont(font200, 200);
  fill(255);
  text(startCountdown, width/2, height/2-20);
  textAlign(CORNER);
  textFont(font, 30);
}

void drawWaveForm() {
  // draw the waveforms so we can see what we are monitoring
  stroke(255);
  for (int i = 0; i < in.bufferSize() - 1; i++)
  {
    line( i, (height/2) + in.left.get(i)*20, i+1, (height/2) + in.left.get(i+1)*20);
    //line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
  }
  
  stroke(170, 137, 228);
  strokeWeight(1);
  for (int i = 0; i < out.bufferSize()-1; i++) {
    line( i, (height/2)-50 -out.left.get(i)*100, i+1, (height/2)-50  - out.left.get(i+1)*100 );
    line( i, (height/2)+50 - out.right.get(i)*100, i+1, (height/2)+50 - out.right.get(i+1)*100 );
  }

  fill(255, 100);
  rectMode(CORNERS);
  float lerpIn = lerp(inputLerp, height-50-in.left.level()*400, 0.5);
  rect(width/2-20, lerpIn, width/2+20, height);

  inputLerp =  height-50-in.left.level()*400;
 

  float amp = in.left.level()*10;
  wave.setAmplitude(amp);

  if (breathPhase == "Inhalar") {
    wave.setFrequency(320);
  } else if ( breathPhase == "Exhalar") {
    wave.setFrequency(110);
  }
}

void onTickEvent(CountdownTimer t, long timeLeftUntilFinish) {
  //timerCallbackInfo = "[tick] - timeLeft: " + timeLeftUntilFinish + "ms";
  if (!startGame) {
    countTime--;
    if(countTime == 0){
      countTime = 3;
      startCountdown--;
      bell.trigger();
    }
    //startCountdown--;
    if (startCountdown == 0) {
      startGame = true;
      //breathIn.trigger();
    }
  } else {
    timeLeft--;
    if (timeLeft == 0) {
      if (phaseId < 3) {
        phaseId++;
        if (phaseId == 2) {
          //breathOut.trigger();
        }
      } else {
        phaseId = 0;
        //breathIn.trigger();
        breathCyclesLeft--;
      }

      int phaseDuration = breathPattern[phaseId];
      breathPhase = breathPhases[phaseId];
      timeLeft = phaseDuration;
    }
  }
}

void computePranaPoints(){
  
}

void onFinishEvent(CountdownTimer t) { 
  gameOver = true;
  bowl.trigger();
}

}