(function (Module) {

var DRUM_TYPES = [
  '4OP-FM',
  'Bongos',
  'CR78',
  'KPR77',
  'Kit3',
  'Kit8',
  'LINN',
  'R8',
  'Stark',
  'Techno',
  'TheCheebacabra1',
  'TheCheebacabra2',
  'acoustic-kit',
  'breakbeat13',
  'breakbeat8',
  'breakbeat9'
];

var sounds = _.object(_.map(DRUM_TYPES, function(kit) {
  var ss =  _.map(['hihat.wav', 'kick.wav', 'snare.wav', 'tom1.wav', 'tom2.wav', 'tom3.wav'], function(s){
    return '/assets/sounds/drums/' + kit + '/' + s;
  });
  return [kit, ss];
}));

zound.modules.Drum = Module.extend({
  initialize: function () {
    Module.prototype.initialize.call(this);
    this.pVolume = new zound.models.ModulePropertyRange({ min: 0, max: 100, title: "Volume", value: 100 });
    this.pType = new zound.models.ModulePropertySelect({ values: DRUM_TYPES, title: "Kit" });
    this.properties.add([this.pVolume, this.pType]);
  },

  canHaveInputs: function () {
    return false;
  },

  canPlayNote: function () {
    return true;
  },

  init: function (ctx) {
    var me = this;
    var as = _.map(_.pairs(sounds), function(v){

      var kit = v[0],
          paths = v[1];

      var es =
        Q.all(_.map(paths, function(p){
          return me._loadSound(ctx, p);
        })).then(function(sounds){
          return [kit, sounds];
        });

      return es;
    });

    this.promiseOfSounds = Q.all(as).then(_.object);

    return this.promiseOfSounds.then(_.bind(function (sounds) {
      this.buffers = sounds;
    }, this));
  },

  noteOn: function (note, ctx, time) {

    if(this.promiseOfSounds.isPending())
      return;

    var sample = ctx.createBufferSource();
    var l = sounds[this.pType.getText()].length;

    sample.buffer = this.buffers[this.pType.getText()][note % l];
    sample.start(time);
    sample.stop(time + 0.3); // TODO: real sound duration

    var gain = ctx.createGain();
    gain.gain.value = this.pVolume.getPercent();

    sample.connect(gain);
    this.broadcastToOutputs(gain, ctx);
  },

  noteOff: function () {
    // needed?
  },

  _loadSound: function(ctx, url) {
    var d = Q.defer();
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';

    request.onload = function() {
      ctx.decodeAudioData(request.response, function(b) {
        d.resolve(b);
      }, function(e){
        d.reject(e);
      });
    };
    request.onerror = function(e) {
      d.reject(e);
    };
    request.send();
    return d.promise;
  }

});

}(zound.models.Module));

@@ -608,16 +608,44 @@
 (this);%0A
+    this.properties.add(%5B%0A  
     this
@@ -742,22 +742,24 @@
 : 100 %7D)
-;%0A
+,%0A 
     
+ 
 this.pTy
@@ -842,61 +842,871 @@
 %22 %7D)
-;
+,
 %0A    
+  
 this.p
-roperties.add(%5B
+HihatVolume = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22HiHat Volume%22, value: 100 %7D),%0A      this.pKickVolume = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22Kick Volume%22, value: 100 %7D),%0A      this.pSnareVolume = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22Snare Volume%22, value: 100 %7D),%0A      
 this.p
+Tom1
 Volume
-, this.pType%5D)
+ = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22Tom1 Volume%22, value: 100 %7D),%0A      this.pTom2Volume = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22Tom2 Volume%22, value: 100 %7D),%0A      this.pTom3Volume = new zound.models.ModulePropertyRange(%7B min: 0, max: 100, title: %22Tom3 Volume%22, value: 100 %7D)%0A    %5D);%0A    this.volumeControls = %5Bthis.pHihatVolume, this.pKickVolume, this.pSnareVolume, this.pTom1Volume, this.pTom2Volume, this.pTom3Volume%5D
 ;%0A  
@@ -2365,17 +2365,16 @@
 time) %7B%0A
-%0A
     if(t
@@ -2405,22 +2405,16 @@
 nding())
-%0A     
  return;
@@ -2414,17 +2414,16 @@
 return;%0A
-%0A
     var 
@@ -2505,16 +2505,38 @@
 .length;
+%0A    var i = note %25 l;
 %0A%0A    sa
@@ -2584,24 +2584,17 @@
 Text()%5D%5B
-note %25 l
+i
 %5D;%0A    s
@@ -2639,42 +2639,30 @@
 e + 
-0.3); // TODO: real sound 
+sample.buffer.
 duration
 %0A%0A  
@@ -2657,16 +2657,18 @@
 duration
+);
 %0A%0A    va
@@ -2741,16 +2741,52 @@
 ercent()
+*this.volumeControls%5Bi%5D.getPercent()
 ;%0A%0A    s

add individual volume control + use buffer.duration