(function () {
  var _ = this._ || require('underscore');
  var TWEEN = this.TWEEN || require('tween');
  var async = this.async || require('async');

  // see: http://jakearchibald.com/2013/animated-line-drawing-svg/
  function Path(el, options) {
    options || (options = {});
    _.defaults(options, {
      duration: 1000
    });
    this.options = options;
    
    this.el = el;
    
    var length = el.getTotalLength();
    this.length = length;

    // Set up the starting positions
    el.style.strokeDasharray = length + ' ' + length;
    el.style.strokeDashoffset = length;

    this.update(1);
  }
  Path.prototype.update = function (val) {
    this.val = val;
  };
  Path.prototype.paint = function () {
      this.el.style.strokeDashoffset = this.length * (1 - this.val);
  };
  Path.prototype.start = function (cb) {
    this.tween && this.tween.stop();
    
    var o = {t: 0};
    this.tween = new TWEEN.Tween(o).to({t: 1}, this.options.duration)
      .onUpdate(function () {
        this.update(o.t);
        this.paint();
      }.bind(this))
      .onComplete(function () {
        //console.log('complete');
        cb(null);
      })
      .start()
    ;
  };
  Path.prototype.stop = function () {
    this.tween && this.tween.stop();
  };
  Path.prototype.erase = function () {
    this.stop();
    this.tween = undefined;
    this.update(0);
    this.paint();
  };

  function Scribble(pathsEls, options) {
    options || (options = {});
    _.defaults(options, {
      duration: 2000,
      durationPerPath: false
    });
    this.options = options;

    var paths = []; this.paths = paths;
    var arr = []; this.arr = arr;

    var i = pathsEls.length;
    var totalLength = 0;
    while(i--) {
      var path = new Path(pathsEls[i], {duration: this.options.duration});
      paths.push(path);
      arr.push(path.start.bind(path));

      totalLength += path.length;
    }

    // normalize duration
    if (this.options.durationPerPath !== true) {
      var totalDuration = this.options.duration;
      var i = pathsEls.length;
      while (i--) {
        var path = paths[i];
        var percent = paths[i].length / totalLength;
        //if (percent > 2*1/pathsEls.length) continue;
        paths[i].options.duration = percent * totalDuration;
      }
    }

    var drawing = false;
  }
  Scribble.prototype.draw = function (cb) {
    if (this.drawing) return;

    this.drawing = true;
    async.series(this.arr, cb); // https://github.com/caolan/async#seriestasks-callback
  };
  Scribble.prototype.erase = function () {
    this.paths.forEach(function (path) {
      path.erase();
    });

    this.drawing = false;
  };

  // Exports
  this.Scribble = Scribble;
  if (typeof module !== "undefined" && module !== null) {
    module.exports = this.Scribble;
  }
}).call(this);