var Model = require('./Model');
var triggerParams = require('./mixins/triggerParams');
var volumeParams = require('./mixins/volumeParams');
var oscillatorParams = require('./mixins/oscillatorParams');
var sampleParams = require('./mixins/sampleParams');
var numberInRangeType = require('./types/numberInRange');

var Params = Model.extend(triggerParams, volumeParams, oscillatorParams, sampleParams, {
  type: 'params',

  props: {
    tempo: ['positiveNumber', true, 120]
  },

  dataTypes: {
    positiveNumber: numberInRangeType('positiveNumber', 1, Infinity)
  },

  initialize: function () {
    Model.prototype.initialize.apply(this, arguments);
    this.vent.trigger('clock:tempo', this);
    this.length  = this.calculateLength();
  },

  calculateLength: function () {
    var existingLength = this.length || 0;
    var lengthFromDuration = this.duration && this.lengthFromDuration(this.duration) || 0;
    return lengthFromDuration && lengthFromDuration < existingLength ? lengthFromDuration : existingLength;
  },

  lengthFromDuration: function (duration) {
    var secondsPerBeat = 60 / this.tempo;
    var secondsPerTick = secondsPerBeat / 96;
    return duration * secondsPerTick;
  }
});

Params.fromSources = function () {
  var sources = [].slice.call(arguments).reverse();
  var params = {};

  var multipliers = ['volume'];
  var adders = ['pitch', 'pan'];
  var keys = Object.keys(Params.prototype._definition);

  keys.forEach(function (key) {
    if (key === 'id') { return; }
    sources.forEach(function (source) {
      if (!source) { return; }
      var value = source[key];
      if (~multipliers.indexOf(key)) {
        if (!value || value < 0) { return; }
        var multiplier = value / 100;
        params[key] = params[key] ? params[key] * multiplier : value;
      }
      else if (~adders.indexOf(key)) {
        value = value || 0;
        params[key] = (params[key] || 0) + value;
      }
      else {
        params[key] = value || params[key];
      }
    });

    if (key === 'pan' && params[key] < -100) {
      params[key] = -100;
    }
    else if (key === 'pan' && params[key] > 100) {
      params[key] = 100;
    }
    else if (typeof params[key] === 'undefined') {
      delete params[key];
    }
  });

  return new Params(params);
};

module.exports = Params;

@@ -909,23 +909,20 @@
  0;%0A    
-return 
+if (
 lengthFr
@@ -975,30 +975,92 @@
 gth 
-? lengthFromDuration :
+%7C%7C !existingLength) %7B%0A      return lengthFromDuration;%0A    %7D%0A    else %7B%0A      return
  exi
@@ -1072,16 +1072,22 @@
 Length;%0A
+    %7D%0A
   %7D,%0A%0A  

fix params not using length from duration if no existing length