"use strict";

var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };

var Scroller = (function () {
  //   set options(options) {
  //     let defaultOptions = {
  //     }
  //     this._options = Object.mixin(defaultOptions, options) // doesn't actually exist >:(
  //   }

  function Scroller(wrapper) {
    var _this = this;
    var scrollable = arguments[1] === undefined ? wrapper.querySelector("ul") : arguments[1];
    var prev = arguments[2] === undefined ? wrapper.querySelector(".prev") : arguments[2];
    var next = arguments[3] === undefined ? wrapper.querySelector(".next") : arguments[3];
    return (function () {
      //     this.options = {}

      _this.wrapper = wrapper;
      _this.ele = scrollable;
      _this.prevEle = prev;
      _this.nextEle = next;
      _this.isMoving = false;

      _this.nextEle.addEventListener("click", _this.next.bind(_this));
      _this.prevEle.addEventListener("click", _this.prev.bind(_this));

      _this.ele.addEventListener("scroll", _this._debounceUtil(_this._toggleControlVisibility.bind(_this)));

      window.addEventListener("resize", _this._toggleControlVisibility.bind(_this));

      _this._toggleControlVisibility();
    })();
  }

  _prototypeProperties(Scroller, null, {
    _debounceUtil: {
      value: function _debounceUtil(func) {
        var wait = arguments[1] === undefined ? 100 : arguments[1];
        // cribbed from http://davidwalsh.name/javascript-debounce-function
        var timeout = undefined;
        return function () {
          var context = this;
          var args = arguments;
          var later = function () {
            timeout = null;
            func.apply(context, args);
          };
          clearTimeout(timeout);
          timeout = setTimeout(later, wait);
        };
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    _toggleControlVisibility: {
      value: function _toggleControlVisibility() {
        if (this.isMoving) return; // wait a second, geez

        //     console.log({sl: this.ele.scrollLeft, cw: this.ele.clientWidth, summed: this.ele.scrollLeft+this.ele.clientWidth, sw: this.ele.scrollWidth});

        this.prevEle.classList[this.ele.scrollLeft <= 0 ? "add" : "remove"]("hidden");
        this.nextEle.classList[this.ele.scrollLeft + this.ele.clientWidth >= this.ele.scrollWidth ? "add" : "remove"]("hidden");
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    next: {
      value: function next() {
        this._move(1);
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    prev: {
      value: function prev() {
        this._move(-1);
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    _move: {
      value: function _move() {
        var vector = arguments[0] === undefined ? 1 : arguments[0];
        if (this.isMoving) return;

        var _ref = [this.ele.clientWidth, this.ele.scrollLeft, this.ele.scrollWidth];

        var width = _ref[0];
        var offset = _ref[1];
        var scrollWidth = _ref[2];
        vector = vector / Math.abs(vector);

        var newOffset = offset + vector * width;
        newOffset = Math.min(newOffset, scrollWidth - width);
        newOffset = Math.max(newOffset, 0);

        this._moveItMoveIt(offset, newOffset);
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    _moveItMoveIt: {
      value: function _moveItMoveIt(oldOffset, newOffset) {
        var _this = this;
        this.isMoving = true;

        var startTime = Date.now();
        var duration = 300;
        var currentOffset = oldOffset;
        var animStep = function () {
          var currentTime = Date.now();

          currentOffset = _this._easeInOutCirc(currentTime - startTime, oldOffset, newOffset - oldOffset, duration);
          _this.ele.scrollLeft = currentOffset;

          if (currentTime < startTime + duration) {
            requestAnimationFrame(animStep);
          } else {
            _this.isMoving = false;
            _this.ele.scrollLeft = newOffset;
            _this._toggleControlVisibility();
          }
        };

        requestAnimationFrame(animStep);
      },
      writable: true,
      enumerable: true,
      configurable: true
    },
    _easeInOutCirc: {
      value: function _easeInOutCirc(currentIteration, startValue, changeInValue, totalIterations) {
        // from http://kirupa.googlecode.com/svn/trunk/easing.js
        if ((currentIteration /= totalIterations / 2) < 1) {
          return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue;
        }
        return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue;
      },
      writable: true,
      enumerable: true,
      configurable: true
    }
  });

  return Scroller;
})();

var yep = new Scroller(document.querySelector(".scroller"));