var Tone = require('tone');
var Soundfont = require('soundfont-player');

function AudioEngine (sounds) {

    // tone setup

    this.tone = new Tone();

	// effects setup

    this.delay = new Tone.FeedbackDelay(0.25, 0.5);
    this.panner = new Tone.Panner();
    this.reverb = new Tone.Freeverb();

    this.clearEffects();

    Tone.Master.chain(this.delay, this.panner, this.reverb);

    // drum sounds

    // var drumFileNames = ['high_conga', 'small_cowbell',
    // 'snare_drum', 'splash cymbal'];
    // this.drumSamplers = this._loadSoundFiles(drumFileNames);

    // sound urls - map each url to its tone.sampler
    this.soundSamplers = [];
    this.loadSounds(sounds);

   // soundfont setup

    // instrument names used by Musyng Kite soundfont, in order to
    // match scratch instruments
    this.instrumentNames = ['acoustic_grand_piano', 'electric_piano_1',
        'drawbar_organ', 'acoustic_guitar_nylon', 'electric_guitar_clean',
         'acoustic_bass', 'pizzicato_strings', 'cello', 'trombone', 'clarinet'];

    Soundfont.instrument(Tone.context, this.instrumentNames[0]).then(
        function (inst) {
            this.instrument = inst;
            this.instrument.connect(Tone.Master);
        }.bind(this)
    );
}

AudioEngine.prototype.loadSounds = function (sounds) {
    for (var i=0; i<sounds.length; i++) {
        var url = sounds[i].fileUrl;
        var sampler = new Tone.Sampler(url, function () {
            this.soundSamplers[url] = sampler;
        }.bind(this)).toMaster();
    }
};

AudioEngine.prototype.playSound = function (soundNum) {
    this.soundSamplers[soundNum].triggerAttack();
};

AudioEngine.prototype.playSoundFromUrl = function (url) {
    if (url) {
        // if we've loaded it already, play it
        if (this.soundSamplers[url]) {
            // this.soundSamplers[url].triggerAttack();
            this.soundSamplers[url].player.start();
        } else {
        // else load, play, and store it
        // this results in a delay the first time you play the sound
            var sampler = new Tone.Sampler(url, function () {
                sampler.triggerAttack();
                this.soundSamplers[url] = sampler;
            }.bind(this)).toMaster();
        }
    }
};

AudioEngine.prototype.getSoundDuration = function (url) {
    return this.soundSamplers[url].player.buffer.duration;
};

AudioEngine.prototype.playNoteForBeats = function (note, beats) {
    this.instrument.play(
        note, Tone.context.currentTime, {duration : Number(beats)}
    );
};

AudioEngine.prototype.playDrumForBeats = function (drumNum) {
    this.drumSamplers[drumNum].triggerAttack();
};

AudioEngine.prototype.stopAllSounds = function () {
    // stop drum notes
    // for (var i = 0; i<this.drumSamplers.length; i++) {
    //     this.drumSamplers[i].triggerRelease();
    // }
    // stop sounds triggered with playSound (indexed by their urls)
    for (var key in this.soundSamplers) {
        this.soundSamplers[key].triggerRelease();
    }
    // stop soundfont notes
    this.instrument.stop();
};

AudioEngine.prototype.setEffect = function (effect, value) {
    switch (effect) {
    case 'ECHO':
        this.delay.wet.value = (value / 100) / 2; // max 50% wet
        break;
    case 'PAN':
        this.panner.pan.value = value / 100;
        break;
    case 'REVERB':
        this.reverb.wet.value = value / 100;
        break;
    case 'PITCH':
        this._setPitchShift(value / 20);
        break;
    }
};

AudioEngine.prototype.changeEffect = function (effect, value) {
    switch (effect) {
    case 'ECHO':
        this.delay.wet.value += (value / 100) / 2; // max 50% wet
        this.delay.wet.value = this._clamp(this.delay.wet.value, 0, 0.5);
        break;
    case 'PAN':
        this.panner.pan.value += value / 100;
        this.panner.pan.value = this._clamp(this.panner.pan.value, -1, 1);
        break;
    case 'REVERB':
        this.reverb.wet.value += value / 100;
        this.reverb.wet.value = this._clamp(this.reverb.wet.value, 0, 1);
        break;
    case 'PITCH':
        // this.pitchShift.pitch += value / 20;
        break;
    }
};

AudioEngine.prototype._setPitchShift = function (value) {
    for (var i in this.soundSamplers) {
        this.soundSamplers[i].player.playbackRate = 1 + value;
    }
};

AudioEngine.prototype.clearEffects = function () {
    this.delay.wet.value = 0;
    this._setPitchShift(0);
    this.panner.pan.value = 0;
    this.reverb.wet.value = 0;
};

// AudioEngine.prototype.loadSoundFromUrl = function(url) {

// };

AudioEngine.prototype._clamp = function (input, min, max) {
    return Math.min(Math.max(input, min), max);
};

module.exports = AudioEngine;


@@ -1424,34 +1424,30 @@
 (url
-, function () %7B%0A  
+).toMaster();%0A
         
   th
@@ -1434,34 +1434,32 @@
 ster();%0A        
-  
 this.soundSample
@@ -1464,56 +1464,21 @@
 lers
-%5Burl%5D = sampler;%0A        %7D.bind(this)).toMaster(
+.push(sampler
 );%0A 
@@ -1534,675 +1534,63 @@
 on (
-soundNum) %7B%0A    this.soundSamplers%5BsoundNum%5D.triggerAttack();%0A%7D;%0A%0AAudioEngine.prototype.playSoundFromUrl = function (url) %7B%0A    if (url) %7B%0A        // if we've loaded it already, play it%0A        if (this.soundSamplers%5Burl%5D) %7B%0A            // this.soundSamplers%5Burl%5D.triggerAttack();%0A            this.soundSamplers%5Burl%5D.player.start();%0A        %7D else %7B%0A        // else load, play, and store it%0A        // this results in a delay the first time you play the sound%0A            var sampler = new Tone.Sampler(url, function () %7B%0A                sampler.triggerAttack();%0A                this.soundSamplers%5Burl%5D = sampler;%0A            %7D.bind(this)).toMaster();%0A        %7D%0A    %7D
+index) %7B%0A    this.soundSamplers%5Bindex%5D.triggerAttack();
 %0A%7D;%0A
@@ -1641,19 +1641,21 @@
 nction (
-url
+index
 ) %7B%0A    
@@ -1680,19 +1680,21 @@
 amplers%5B
-url
+index
 %5D.player
@@ -3422,56 +3422,8 @@
 H':%0A
-        // this.pitchShift.pitch += value / 20;%0A
     

fix sound loading