require('es6-object-assign').polyfill();

var Model = require('./Model');
var numberInRangeType = require('./types/numberInRange');

module.exports = Model.extend({

  type: 'effect',

  props: {
    bypass: ['boolean', true, false],
    nodes: ['object', true, function () { return {}; }],
    revision: ['number', true, 1]
  },

  dataTypes: {
    volumeRange: numberInRangeType('volumeRange', 0, 999),
    inclusivePositiveNumber: numberInRangeType('inclusivePositiveNumber', 0, Infinity),
    frequencyRange: numberInRangeType('frequencyRange', 20, 22050)
  },

  initialize: function () {
    Model.prototype.initialize.apply(this, arguments);
    this.on('change', this._bumpRevision);
  },

  _bumpRevision: function () {
    this.set({ revision: this.revision + 1 }, { silent: true });
  },

  createNode: function () {
    throw new Error('Required method "createNode" is not implemented for ' + this.cid);
  },

  configureNode: function (node) {
    throw new Error('Required method "configureNode" is not implemented for ' + this.cid);
  },

  combineNodes: function (input, output) {

    input.connect = function (destination) {
      output.connect(destination);
    };

    input.disconnect = function () {
      output.disconnect();
    };

    return input;
  },

  getNode: function (destinationId) {

    var nodes = this.nodes;
    var node = nodes[destinationId] = nodes[destinationId] || this.createNode();

    if (node._lastConfiguredRevision !== this.revision) {
      this.configureNode(node);
      node._lastConfiguredRevision = this.revision;
    }

    return node;
  }
});

@@ -286,43 +286,8 @@
 ; %7D%5D
-,%0A    revision: %5B'number', true, 1%5D
 %0A  %7D
@@ -528,242 +528,8 @@
 %7D,%0A%0A
-  initialize: function () %7B%0A    Model.prototype.initialize.apply(this, arguments);%0A    this.on('change', this._bumpRevision);%0A  %7D,%0A%0A  _bumpRevision: function () %7B%0A    this.set(%7B revision: this.revision + 1 %7D, %7B silent: true %7D);%0A  %7D,%0A%0A
   cr
@@ -1040,16 +1040,22 @@
 nationId
+, time
 ) %7B%0A%0A   
@@ -1079,24 +1079,25 @@
 .nodes;%0A
+%0A
     var 
 node = n
@@ -1092,79 +1092,211 @@
 var 
-node = nodes%5BdestinationId%5D = nodes%5BdestinationId%5D %7C%7C this.createNode()
+json = this.toJSON();%0A    delete json.nodes;%0A    delete json.revision;%0A    delete json.bypass;%0A    var params = JSON.stringify(json);%0A%0A    var id = destinationId + '//' + params;%0A    var node = nodes%5Bid%5D
 ;%0A%0A 
@@ -1306,57 +1306,60 @@
 if (
+!
 node
-._lastConfiguredRevision !=
+) %7B%0A      node = nodes%5Bid%5D 
 = this.
+c
 re
-vision) %7B
+ateNode();
 %0A   
@@ -1391,60 +1391,8 @@
 e);%0A
-      node._lastConfiguredRevision = this.revision;%0A
     

allow effects to change values over time, without affecting already processing signal