/* AUDIO CAPTURE FUNCTIONS */
var jsnode;
var mStreamNode;
var glob_stream = null;
var con = null;
var source;
var sampleRate = 22050;
var recording = false;
var speech_audio;

function createContext() {
    var context;
    try {
	context = new webkitAudioContext();
	return context;
    } catch(err) {
	alert("WebkitAudioContext failed. " + err);
    }
}

function startRecording() {
    clear();
    if(glob_stream == null) {
	console.log("GLOB_NULL ");
	navigator.webkitGetUserMedia({audio:true}, gotStream, function(e) {
	console.log("ERROR: webkit error  - ", e);
	    });
    } else {
	gotStream(glob_stream);
    }
}

function gotStream(stream) {
    /* Setup the variables */
    console.log("INFO: recording...");
    recording = true;
    if(con == null) con = createContext();
    glob_stream = stream;
    mStreamSource = con.createMediaStreamSource(stream);
    jsnode = con.createJavaScriptNode(256,1,1); // We could change this to stereo
    source = new Float32Array();
    console.log("INFO: ", source.length);
	
    var i = 0;
    jsnode.onaudioprocess = function(e) {
	if(!recording) return;
	
	/* get the input and assign it to source */
	var input = e.inputBuffer.getChannelData(0);
	source = Float32Concat(source, input);

	/* Now update the waveform */
	i++;
	updateWaveform(i, input);
    }
    mStreamSource.connect(jsnode);
    jsnode.connect(con.destination);
}

function playSpeech() {
    var buffer  = source;
    var dataview = encodeWAV(buffer);
    var audioBlob = new Blob([dataview], {type:'audio/wav'});
    var bloburl = webkitURL.createObjectURL(audioBlob);
    speech_audio = document.querySelector("audio");
    speech_audio.addEventListener("ended", playonended,false);
    speech_audio.src = bloburl;
    speech_audio.play();
}

function pausePlayback() {
    // speech_audio = document.querySelector("audio");
    speech_audio.pause();
}

function stopRecording() {
    console.log("INFO: stopRecording");
    recording = false;
    glob_stream.stop();
    jsnode.disconnect(con.destination);
}

function clear() {
    speech.src = null;
    source = null;
}

function writeString(view, offset, string){
  for (var i = 0; i < string.length; i++){
    view.setUint8(offset + i, string.charCodeAt(i));
  }
}

function encodeWAV(samples) {
    var buffer = new ArrayBuffer(48 + samples.length * 2);
    var view = new DataView(buffer);
    
    /* RIFF identifier */
    writeString(view, 0, 'RIFF');

    /* file length */
    view.setUint32(4, 32 + samples.length * 2, true);

    /* RIFF type */
    writeString(view, 8, 'WAVE');

    /* format chunk identifier */
    writeString(view, 12, 'fmt ');

    /* format chunk length */
    view.setUint32(16, 16, true);

    /* sample format (raw) */
    view.setUint16(20, 1, true);

    /* channel count */
    view.setUint16(22, 2, true);

    /* sample rate */
    view.setUint32(24, sampleRate, true);

    /* byte rate (sample rate * block align) */
    view.setUint32(28, sampleRate * 4, true);

    /* block align (channel count * bytes per sample) */
    view.setUint16(32, 4, true);

    /* bits per sample */
    view.setUint16(34, 16, true);

    /* data chunk identifier */
    writeString(view, 36, 'data');

    /* data chunk length */
    view.setUint32(40, samples.length * 2, true);
    

    /* TODO: this WILL need altered. */
    floatTo16BitPCM(view, 44, samples);
    
    return view;
}

function Float32Concat(first, second) {
    
    var firstLength = first.length;
    var result = new Float32Array(firstLength + second.length);
    
    result.set(first);
    result.set(second, firstLength);
    return result;
}

function floatTo16BitPCM(output, offset, input){
  for (var i = 0; i < input.length; i++, offset+=2){
    var s = Math.max(-1, Math.min(1, input[i]));
    output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
  }
}

function processAudio() {
    console.log("processing the audio...");
    f32 = source;
    
    result = "";
    var hex_array = new Array();
    for(i = 0; i < f32.length; i++) {
	hex = floatToIntBits(f32[i]).toString(16);
	hex_array.push(hex);
	if(hex != "") result = result + (hex + ":");
    }
    
    /* Now hand the hex string to Flash */
    var ogg_lib = swfobject.getObjectById("ogg_lib");
    
    if(ogg_lib == null) {
	// TODO: maybe some sort of error handling. i.e an alert maybe?
	console.log("ERROR-JS: getOggLib is null!!");
    }
    ogg_lib.passHex(result);
    clear();
}

function updateWaveform(index, inBuf) {
    if((index % 20) == 0){
	j = 0;
	for(x in inBuf) {
	    if((j % 6) == 0){
		n = parseFloat(inBuf[x]);
		if(n == 256 || n == 1024 || n == 4) // These keep popping out somehow??
		    n = 0;
		if((n < 1) || (n > -1)) {
		    if(typeof n === 'number' && !isNaN(n)) 
			usr_audio_data.push(n*4);
		}
	    }
	    j++;
	}
	usr_waveform.update({data:usr_audio_data});
    }
}


