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

import ddf.minim.*; 
import javax.swing.*; 
import java.awt.event.*; 
import java.io.File; 

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






Minim minim;
AudioInput in;
AudioRecorder recorder;
AudioPlayer recording;
String words[];
int wordIndex;
String currentWord;
String newWord;
PImage shelby;
boolean space;
boolean isRecording;

public void setup() {
  size(512, 200, P2D);
  textMode(SCREEN);
  textFont(createFont("Serif", 24));
  textAlign(CENTER, CENTER);
  fill(0);
  stroke(0, 0, 255);
  shelby = loadImage("data/shelby.png");
  
  prepareExitHandler();

  minim = new Minim(this);
  in = minim.getLineIn(Minim.STEREO, 2048);

  words = loadStrings("words.txt");
  wordIndex = PApplet.parseInt(loadStrings("data/word.txt")[0]);
  getWord();
}

public void getWord() {

  boolean extra;

  if (newWord != null) extra = true;
  else extra = false;

  if (extra) currentWord = newWord;
  else currentWord = split(words[wordIndex], ' ')[0];

  File f = new File(sketchPath("recordings/"+currentWord+".wav"));
  if (f.exists()) f.delete();

  recorder = minim.createRecorder(in, "recordings/"+ f.getName(), false);

  if (!extra) {
    String[] indexToSave = {
      str(wordIndex)
      };
      saveStrings("data/word.txt", indexToSave);
  }
}

// Display

public void draw() {

  if (space) background(0, 255, 0); 
  else if (isRecording) background(255, 0, 0);
  else background(255);

  image(shelby, 0, 0);

  for (int i = 0; i < in.bufferSize() - 1; i++) {
    line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
    line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
  }

  text(currentWord, width/2, height/2);

  if (newWord != null) {
    text("\u221e", width/2, height - 25);
  }

  else text(nfc(words.length - wordIndex), width/2, height - 25);

  if (recorder.isRecording()) {
    fill(255, 0, 0);
    text("R", 15, 18);
    fill(0);
  }
}

// Controls

public void keyPressed() {
  if (key == ' ' && space == false) {
    space = true;
    wordIndex++;
    newWord = null;
    if (wordIndex == words.length) {
      return;
    }
    getWord();
  }

  if (key == 'n') {
    SwingUtilities.invokeLater(new Runnable() {  
      public void run() 
      {  
        String preset = "";
        newWord = javax.swing.JOptionPane.showInputDialog(frame, "Which word would you like to record?", preset);

        if (newWord != null) {
          getWord();
        }
      }
    }
    );
  }
}

public void keyReleased() {
  if (key == ' ') {
    space = false;
  }
}

public void mousePressed() {
  getWord();
  if (recording != null && recording.isPlaying()) recording.pause();
  recorder.beginRecord();
  isRecording = true;
}

public void mouseReleased() {
  if (recorder.isRecording()) { 
    recorder.endRecord();
    isRecording = false;
    recording = recorder.save();
    if (recording.length() > 100) {
      recording.loop();
    } 
    else {
      File f = new File(sketchPath("recordings/"+currentWord+".wav"));
      if (f.exists()) f.delete();
    }
  }
}

// Quit


private void prepareExitHandler() {
  Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    public void run () {
      File f = new File(sketchPath("recordings/"+currentWord+".wav"));
      if (f.exists()) f.delete();
    }
  }
  ));
}

  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#FFFFFF", "VoiceRecorder" });
  }
}
