/**
 * Created by .
 * User: georgebrower
 * Date: 4/20/11
 * Time: 9:37 PM
 * To change this template use File | Settings | File Templates.
 */
var dat = dat || {};
dat.butter = dat.butter || {};
dat.butter.Elastic = function(value, easing, tolerance) {

  var _this = this;
  var _velocity = 0;
  var _hasArrived = false;

  this.value = value || 0;
  this.dest = value || 0;
  this.tolerance = tolerance || 0.001;
  this.strength = 1.8;
  this.mass = 1;
  this.damping = 0.4;

  this.__defineGetter__('velocity', function() {
    return _velocity;
  });

  this.hasArrived = function() {
    return _hasArrived;
  };

  this.update = function() {
    // if (_hasArrived) {
    //       return false;
    //     } else {
    //       if(_this.value != _this.dest || _velocity != 0) {
    //         _hasArrived = false;
    //       }
    //     }
    
    var force = -_this.strength*(_this.value-_this.dest);
    var acc = force/_this.mass;
    _velocity += acc;
    _velocity *= _this.damping;
    _this.value += _velocity;
    _this.updateSlave();
    // TODO;
    if (Math.abs(_this.value - _this.dest) < _this.tolerance && Math.abs
        (_velocity) < _this.tolerance) {
      _this.arrive();
    }
    return true;
  };

  // this.hasArrived = function() {
  //   return _this.value == _this.dest && _velocity == 0;
  // }

  this.arrive = function() {
    _arrivalCallback.call(_this);
    _this.value = _this.dest;
    _velocity = 0;
    _hasArrived = true;
  }

  this.grab = function() {

  }

  this.release = function() {
    
  }


  // "Inherited"

  var _slaveObject;
  var _slaveProperty;
  var _arrivalCallback = function() {
  };

  this.slave = function(object, property) {
    _slaveObject = object;
    _slaveProperty = property;
  }

  this.unslave = function() {
    _slaveObject = undefined;
    _slaveProperty = undefined;
  };

  this.updateSlave = function() {
    if (_slaveObject == undefined || _slaveProperty == undefined) return;
    _slaveObject[_slaveProperty] = _this.value;
  };

  this.onArrival = function(arrivalCallback) {
    _arrivalCallback = arrivalCallback;
  };

  this.valueOf = function() {
    return _this.value;
  }

}

