define(function(){

  var cb, loading;

  function LocalAudioVisualizer(domNode, loadNode, callback){
    this.domNode = domNode;
    cb = callback;
    loading = loadNode;

    dropAndLoad(domNode, init, "ArrayBuffer");
  }

  LocalAudioVisualizer.prototype.loadUrl = function(url){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';

    xhr.onload = function(e) {
      init(this.response);
    };

    xhr.send();
  };

// Reusable dropAndLoad function: it reads a local file dropped on a
// `dropElement` in the DOM in the specified `readFormat`
// (In this case, we want an arrayBuffer)
function dropAndLoad(dropElement, callback, readFormat) {
  var readFormat = readFormat || "DataUrl";

  dropElement.addEventListener('dragover', function(e) {
    e.stopPropagation();
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
  }, false);

  dropElement.addEventListener('drop', function(e) {
    e.stopPropagation();
    e.preventDefault();
    loadFile(e.dataTransfer.files[0]);
  }, false) ;

  function loadFile(files) {
    var file = files;
    var reader = new FileReader();
    reader.onload = function(e) {
      $('#filename').text(file.name).fadeIn('slow');
      callback(e.target.result);
    }
    reader['readAs'+readFormat](file);
  }
}

// Once the file is loaded, we start getting our hands dirty.
function init(arrayBuffer) {
  // document.getElementById('instructions').innerHTML = 'Loading ...'
  $(loading).text('Loading').css({display:'inline-block'}).fadeIn('slow');
  // Create a new `audioContext` and its `analyser`
  window.audioCtx = new webkitAudioContext();
  window.analyser = audioCtx.createAnalyser();
  // If a sound is still playing, stop it.
  if (window.source) source.noteOff(0);
  // Decode the data in our array into an audio buffer
  audioCtx.decodeAudioData(arrayBuffer, function(buffer) {
    window.source = audioCtx.createBufferSource();
    source.buffer = buffer;
    source.connect(analyser);
    analyser.connect(audioCtx.destination);
    source.noteOn(0);

    $(loading).fadeOut('slow');
    setTimeout(function(){
      $('#filename').fadeOut('slow');
    },8000);
    new visualizer(cb, analyser);
  })
}

// The visualizer object. 
// Calls the `visualization` function every time a new frame
// is available.
// Is passed an `analyser` (audioContext analyser).
function visualizer(visualization, analyser) {
  var self = this;
  this.visualization = visualization;
  var last = Date.now();
  var loop = function() {
    var dt = Date.now() - last;
    // we get the current byteFreq data from our analyser
    var byteFreq = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(byteFreq);
    last = Date.now();
    // We might want to use a delta time (`dt`) too for our visualization.
    self.visualization(byteFreq, dt);
    webkitRequestAnimationFrame(loop);
  }
  webkitRequestAnimationFrame(loop);
}

  return LocalAudioVisualizer;

});
