'use strict';

var _isInteger = require('babel-runtime/core-js/number/is-integer');

var _isInteger2 = _interopRequireDefault(_isInteger);

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

var _assign = require('babel-runtime/core-js/object/assign');

var _assign2 = _interopRequireDefault(_assign);

var _intervalFunction = require('../utils/interval-function');

var _intervalFunction2 = _interopRequireDefault(_intervalFunction);

var _easing = require('../utils/easing');

var _jsonUtils = require('../utils/json-utils');

var _constants = require('../utils/constants');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * @license
 * Copyright 2016 Leif Olsen. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This code is built with Google Material Design Lite,
 * which is Licensed under the Apache License, Version 2.0
 */

/**
 * Image carousel
 */

var MDL_RIPPLE_CONTAINER = 'mdlext-carousel__slide__ripple-container';

(function () {
  'use strict';

  //const CAROUSEL = 'mdlext-carousel';

  var SLIDE = 'mdlext-carousel__slide';
  var ROLE = 'list';
  var SLIDE_ROLE = 'listitem';

  /**
   * @constructor
   * @param {Element} element The element that will be upgraded.
   */
  var MaterialExtCarousel = function MaterialExtCarousel(element) {
    // Stores the element.
    this.element_ = element;

    // Default config
    this.config_ = {
      interactive: true,
      autostart: false,
      type: 'slide',
      interval: 1000,
      animationLoop: (0, _intervalFunction2.default)(1000)
    };

    this.scrollAnimation_ = (0, _intervalFunction2.default)(33);

    // Initialize instance.
    this.init();
  };

  window['MaterialExtCarousel'] = MaterialExtCarousel;

  /**
   * Start slideshow animation
   * @private
   */
  MaterialExtCarousel.prototype.startSlideShow_ = function () {
    var _this = this;

    var nextSlide = function nextSlide() {
      var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected]');
      if (slide) {
        slide.removeAttribute('aria-selected');
        slide = slide.nextElementSibling;
      }
      if (!slide) {
        slide = _this.element_.querySelector('.' + SLIDE + ':first-child');
        _this.animateScroll_(0);
      }
      if (slide) {
        _this.moveSlideIntoViewport_(slide);
        slide.setAttribute('aria-selected', '');
        _this.emitSelectEvent_('next', null, slide);
        return true;
      }
      return false;
    };

    var nextScroll = function nextScroll(direction) {
      var nextDirection = direction;

      if ('next' === direction && _this.element_.scrollLeft === _this.element_.scrollWidth - _this.element_.clientWidth) {
        nextDirection = 'prev';
      } else if (_this.element_.scrollLeft === 0) {
        nextDirection = 'next';
      }
      var x = 'next' === nextDirection ? Math.min(_this.element_.scrollLeft + _this.element_.clientWidth, _this.element_.scrollWidth - _this.element_.clientWidth) : Math.max(_this.element_.scrollLeft - _this.element_.clientWidth, 0);

      _this.animateScroll_(x, 1000);
      return nextDirection;
    };

    if (!this.config_.animationLoop.started) {
      (function () {
        _this.config_.animationLoop.interval = _this.config_.interval;
        var direction = 'next';

        if ('scroll' === _this.config_.type) {
          _this.config_.animationLoop.start(function () {
            direction = nextScroll(direction);
            return true; // It runs until cancelSlideShow_ is triggered
          });
        } else {
          nextSlide();
          _this.config_.animationLoop.start(function () {
            return nextSlide(); // It runs until cancelSlideShow_ is triggered
          });
        }
      })();
    }

    // TODO: Pause animation when carousel is not in browser viewport or user changes tab
  };

  /**
   * Cancel slideshow if running. Emmits a 'pause' event
   * @private
   */
  MaterialExtCarousel.prototype.cancelSlideShow_ = function () {
    if (this.config_.animationLoop.started) {
      this.config_.animationLoop.stop();
      this.emitSelectEvent_('pause', _constants.VK_ESC, this.element_.querySelector('.' + SLIDE + '[aria-selected]'));
    }
  };

  /**
   * Animate scroll
   * @param newPosition
   * @param newDuration
   * @param completedCallback
   * @private
   */
  MaterialExtCarousel.prototype.animateScroll_ = function (newPosition, newDuration, completedCallback) {
    var _this2 = this;

    var start = this.element_.scrollLeft;
    var distance = newPosition - start;

    if (distance !== 0) {
      (function () {
        var duration = Math.max(Math.min(Math.abs(distance), newDuration || 400), 100); // duration is between 100 and newDuration||400ms||distance
        var t = 0;
        _this2.scrollAnimation_.stop();
        _this2.scrollAnimation_.start(function (timeElapsed) {
          t += timeElapsed;
          if (t < duration) {
            _this2.element_.scrollLeft = (0, _easing.inOutQuintic)(t, start, distance, duration);
            return true;
          } else {
            _this2.element_.scrollLeft = newPosition;
            if (completedCallback) {
              completedCallback();
            }
            return false;
          }
        });
      })();
    } else {
      if (completedCallback) {
        completedCallback();
      }
    }
  };

  /**
   * Execute commend
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.command_ = function (event) {
    var _this3 = this;

    var x = 0;
    var slide = null;
    var a = event.detail.action.toLowerCase();

    // Cancel slideshow if running
    this.cancelSlideShow_();

    switch (a) {
      case 'first':
        slide = this.element_.querySelector('.' + SLIDE + ':first-child');
        break;

      case 'last':
        x = this.element_.scrollWidth - this.element_.clientWidth;
        slide = this.element_.querySelector('.' + SLIDE + ':last-child');
        break;

      case 'scroll-prev':
        x = Math.max(this.element_.scrollLeft - this.element_.clientWidth, 0);
        break;

      case 'scroll-next':
        x = Math.min(this.element_.scrollLeft + this.element_.clientWidth, this.element_.scrollWidth - this.element_.clientWidth);
        break;

      case 'next':
      case 'prev':
        slide = this.element_.querySelector('.' + SLIDE + '[aria-selected]');
        if (slide) {
          slide = a === 'next' ? slide.nextElementSibling : slide.previousElementSibling;
          this.setAriaSelected_(slide);
          this.emitSelectEvent_(a, null, slide);
        }
        return;

      case 'play':
        (0, _assign2.default)(this.config_, event.detail);
        this.startSlideShow_();
        return;

      case 'pause':
        return;

      default:
        return;
    }

    this.animateScroll_(x, undefined, function () {
      if ('scroll-next' === a || 'scroll-prev' === a) {
        var slides = _this3.getSlidesInViewport_();
        if (slides.length > 0) {
          slide = 'scroll-next' === a ? slides[0] : slides[slides.length - 1];
        }
      }
      _this3.setAriaSelected_(slide);
      _this3.emitSelectEvent_(a, null, slide);
    });
  };

  /**
   * Handles custom command event, 'scroll-prev', 'scroll-next', 'first', 'last', next, prev, play, pause
   * @param event. A custom event
   * @private
   */
  MaterialExtCarousel.prototype.commandHandler_ = function (event) {
    event.preventDefault();
    event.stopPropagation();
    if (event.detail && event.detail.action) {
      this.command_(event);
    }
  };

  /**
   * Handle keypress
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.keyDownHandler_ = function (event) {

    if (event && event.target && event.target !== this.element_) {

      var action = 'first';

      if (event.keyCode === _constants.VK_HOME || event.keyCode === _constants.VK_END || event.keyCode === _constants.VK_PAGE_UP || event.keyCode === _constants.VK_PAGE_DOWN) {

        event.preventDefault();
        if (event.keyCode === _constants.VK_END) {
          action = 'last';
        } else if (event.keyCode === _constants.VK_PAGE_UP) {
          action = 'scroll-prev';
        } else if (event.keyCode === _constants.VK_PAGE_DOWN) {
          action = 'scroll-next';
        }

        var cmd = new CustomEvent('select', {
          detail: {
            action: action
          }
        });
        this.command_(cmd);
      } else if (event.keyCode === _constants.VK_TAB || event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE || event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT || event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {

        var slide = getSlide_(event.target);

        if (!slide) {
          return;
        }

        // Cancel slideshow if running
        this.cancelSlideShow_();

        switch (event.keyCode) {
          case _constants.VK_ARROW_UP:
          case _constants.VK_ARROW_LEFT:
            action = 'prev';
            slide = slide.previousElementSibling;
            break;

          case _constants.VK_ARROW_DOWN:
          case _constants.VK_ARROW_RIGHT:
            action = 'next';
            slide = slide.nextElementSibling;
            break;

          case _constants.VK_TAB:
            if (event.shiftKey) {
              action = 'prev';
              slide = slide.previousElementSibling;
            } else {
              action = 'next';
              slide = slide.nextElementSibling;
            }
            break;

          case _constants.VK_SPACE:
          case _constants.VK_ENTER:
            action = 'select';
            break;
        }

        if (slide) {
          event.preventDefault();
          setFocus_(slide);
          this.emitSelectEvent_(action, event.keyCode, slide);
        }
      }
    }
  };

  /**
   * Handle dragging
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.dragHandler_ = function (event) {
    var _this4 = this;

    event.preventDefault();

    // Cancel slideshow if running
    this.cancelSlideShow_();

    var updating = false;
    var rAFDragId = 0;

    var startX = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
    var prevX = startX;
    var targetElement = event.target;

    var update = function update(e) {
      var currentX = e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0);
      var dx = prevX - currentX;

      if (dx < 0) {
        _this4.element_.scrollLeft = Math.max(_this4.element_.scrollLeft + dx, 0);
      } else if (dx > 0) {
        _this4.element_.scrollLeft = Math.min(_this4.element_.scrollLeft + dx, _this4.element_.scrollWidth - _this4.element_.clientWidth);
      }

      prevX = currentX;
      updating = false;
    };

    // drag handler
    var drag = function drag(e) {
      e.preventDefault();

      if (!updating) {
        rAFDragId = window.requestAnimationFrame(function () {
          return update(e);
        });
        updating = true;
      }
    };

    // end drag handler
    var endDrag = function endDrag(e) {
      e.preventDefault();

      _this4.element_.removeEventListener('mousemove', drag);
      _this4.element_.removeEventListener('touchmove', drag);
      window.removeEventListener('mouseup', endDrag);
      window.removeEventListener('touchend', endDrag);

      // cancel any existing drag rAF, see: http://www.html5rocks.com/en/tutorials/speed/animations/
      window.cancelAnimationFrame(rAFDragId);

      var slide = getSlide_(targetElement);
      setFocus_(slide);
      _this4.emitSelectEvent_('click', null, slide);
    };

    this.element_.addEventListener('mousemove', drag);
    this.element_.addEventListener('touchmove', drag);
    window.addEventListener('mouseup', endDrag);
    window.addEventListener('touchend', endDrag);
  };

  /**
   * Handle click
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.clickHandler_ = function (event) {
    // Click is handled by drag
    event.preventDefault();
  };

  /**
   * Handle focus
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.focusHandler_ = function (event) {
    var slide = getSlide_(event.target);
    if (slide) {
      // The last focused/selected slide has 'aria-selected', even if focus is lost
      this.setAriaSelected_(slide);
      slide.classList.add(_constants.IS_FOCUSED);
    }
  };

  /**
   * Handle blur
   * @param event
   * @private
   */
  MaterialExtCarousel.prototype.blurHandler_ = function (event) {
    var slide = getSlide_(event.target);
    if (slide) {
      slide.classList.remove(_constants.IS_FOCUSED);
    }
  };

  /**
   * Emits a custeom 'select' event
   * @param command
   * @param keyCode
   * @param slide
   * @private
   */
  MaterialExtCarousel.prototype.emitSelectEvent_ = function (command, keyCode, slide) {

    if (slide) {
      this.moveSlideIntoViewport_(slide);

      var evt = new CustomEvent('select', {
        bubbles: true,
        cancelable: true,
        detail: {
          command: command,
          keyCode: keyCode,
          source: slide
        }
      });
      this.element_.dispatchEvent(evt);
    }
  };

  /**
   * Get the first visible slide in component viewport
   * @private
   */
  MaterialExtCarousel.prototype.getSlidesInViewport_ = function () {
    var carouselRect = this.element_.getBoundingClientRect();

    var slidesInViewport = [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).filter(function (slide) {
      var slideRect = slide.getBoundingClientRect();
      return slideRect.left >= carouselRect.left && slideRect.right <= carouselRect.right;
    });
    return slidesInViewport;
  };

  /**
   * Move slide into component viewport - if needed
   * @param slide
   * @private
   */
  MaterialExtCarousel.prototype.moveSlideIntoViewport_ = function (slide) {
    var carouselRect = this.element_.getBoundingClientRect();
    var slideRect = slide.getBoundingClientRect();

    if (slideRect.left < carouselRect.left) {
      var x = this.element_.scrollLeft - (carouselRect.left - slideRect.left);
      this.animateScroll_(x);
    } else if (slideRect.right > carouselRect.right) {
      var _x = this.element_.scrollLeft - (carouselRect.right - slideRect.right);
      this.animateScroll_(_x);
    }
  };

  /**
   * Removes 'aria-selected' from all slides in carousel
   * @private
   */
  MaterialExtCarousel.prototype.setAriaSelected_ = function (slide) {
    if (slide) {
      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE + '[aria-selected]'))).forEach(function (slide) {
        return slide.removeAttribute('aria-selected');
      });
      slide.setAttribute('aria-selected', '');
    }
  };

  /**
   * Removes event listeners
   * @private
   */
  MaterialExtCarousel.prototype.removeListeners_ = function () {
    this.element_.removeEventListener('focus', this.focusHandler_);
    this.element_.removeEventListener('blur', this.blurHandler_);
    this.element_.removeEventListener('keydown', this.keyDownHandler_);
    this.element_.removeEventListener('mousedown', this.dragHandler_);
    this.element_.removeEventListener('touchstart', this.dragHandler_);
    this.element_.removeEventListener('click', this.clickHandler_, false);
    this.element_.removeEventListener('command', this.commandHandler_);
    this.element_.removeEventListener('mdl-componentdowngraded', this.mdlDowngrade_);
  };

  // Helpers
  var getSlide_ = function getSlide_(element) {
    return element.closest('.' + SLIDE);
  };

  var setFocus_ = function setFocus_(slide) {
    if (slide) {
      slide.focus();
    }
  };

  var addRipple_ = function addRipple_(slide) {
    if (!slide.querySelector('.' + MDL_RIPPLE_CONTAINER)) {
      var rippleContainer = document.createElement('span');
      rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
      rippleContainer.classList.add(_constants.MDL_RIPPLE_EFFECT);
      var ripple = document.createElement('span');
      ripple.classList.add(_constants.MDL_RIPPLE);
      rippleContainer.appendChild(ripple);

      var img = slide.querySelector('img');
      if (img) {
        // rippleContainer blocks image title
        rippleContainer.title = img.title;
      }
      slide.appendChild(rippleContainer);
      componentHandler.upgradeElement(rippleContainer, _constants.MDL_RIPPLE_COMPONENT);
    }
  };
  // End helpers


  // Public methods.

  /**
   * Cancel animation - if running.
   *
   * @public
   */
  MaterialExtCarousel.prototype.stopAnimation = function () {
    this.config_.animationLoop.stop();
  };
  MaterialExtCarousel.prototype['stopAnimation'] = MaterialExtCarousel.prototype.stopAnimation;

  /**
   * Upgrade slides
   * Use if more list elements are added later (dynamically)
   *
   * @public
   */
  MaterialExtCarousel.prototype.upgradeSlides = function () {
    var _this5 = this;

    var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);

    [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).forEach(function (slide) {

      slide.setAttribute('role', SLIDE_ROLE);

      if (_this5.config_.interactive) {
        if (!slide.getAttribute('tabindex')) {
          slide.setAttribute('tabindex', '0');
        }
        if (hasRippleEffect) {
          addRipple_(slide);
        }
      } else {
        slide.setAttribute('tabindex', '-1');
      }
    });
  };
  MaterialExtCarousel.prototype['upgradeSlides'] = MaterialExtCarousel.prototype.upgradeSlides;

  /**
   * Get config object
   *
   * @public
   */
  MaterialExtCarousel.prototype.getConfig = function () {
    return this.config_;
  };
  MaterialExtCarousel.prototype['getConfig'] = MaterialExtCarousel.prototype.getConfig;

  /**
   * Initialize component
   */
  MaterialExtCarousel.prototype.init = function () {

    if (this.element_) {
      // Config
      if (this.element_.hasAttribute('data-config')) {
        this.config_ = (0, _jsonUtils.jsonStringToObject)(this.element_.getAttribute('data-config'), this.config_);
      }

      // Wai-Aria
      this.element_.setAttribute('role', ROLE);

      // Prefer tabindex -1
      if (!(0, _isInteger2.default)(this.element_.getAttribute('tabindex'))) {
        this.element_.setAttribute('tabindex', -1);
      }

      // Remove listeners, just in case ...
      this.removeListeners_();

      if (this.config_.interactive) {

        // Ripple
        var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
        if (hasRippleEffect) {
          this.element_.classList.add(_constants.MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
        }

        // Listen to focus/blur events
        this.element_.addEventListener('focus', this.focusHandler_.bind(this), true);
        this.element_.addEventListener('blur', this.blurHandler_.bind(this), true);

        // Listen to keyboard events
        this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this), false);

        // Listen to drag events
        this.element_.addEventListener('mousedown', this.dragHandler_.bind(this), false);
        this.element_.addEventListener('touchstart', this.dragHandler_.bind(this), false);

        // Listen to click events
        this.element_.addEventListener('click', this.clickHandler_.bind(this), false);
      }

      // Listen to custom 'command' event
      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);

      // Listen to 'mdl-componentdowngraded' event
      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));

      // Slides collection
      this.upgradeSlides();

      // Set upgraded flag
      this.element_.classList.add(_constants.IS_UPGRADED);

      if (this.config_.autostart) {
        // Start slideshow
        this.startSlideShow_();
      }
    }
  };

  /*
   * Downgrade component
   * E.g remove listeners and clean up resources
   */
  MaterialExtCarousel.prototype.mdlDowngrade_ = function () {
    'use strict';
    //console.log('***** MaterialExtCarousel.mdlDowngrade_');

    // Stop animation - if any

    this.stopAnimation();

    // Remove listeners
    this.removeListeners_();
  };

  // The component registers itself. It can assume componentHandler is available
  // in the global scope.
  /* eslint no-undef: 0 */
  componentHandler.register({
    constructor: MaterialExtCarousel,
    classAsString: 'MaterialExtCarousel',
    cssClass: 'mdlext-js-carousel',
    widget: true
  });
})();