'use strict';

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

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

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

var _isInteger2 = _interopRequireDefault(_isInteger);

var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');

var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);

var _entries = require('babel-runtime/core-js/object/entries');

var _entries2 = _interopRequireDefault(_entries);

var _getIterator2 = require('babel-runtime/core-js/get-iterator');

var _getIterator3 = _interopRequireDefault(_getIterator2);

var _fullThrottle = require('../utils/full-throttle');

var _fullThrottle2 = _interopRequireDefault(_fullThrottle);

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
 */

/**
 * Responsive Lightbox
 */

(function () {
  'use strict';

  var LIGHTBOX = 'mdlext-lightbox';
  var LIGHTBOX_SLIDER = 'mdlext-lightbox__slider';
  var LIGHTBOX_SLIDER_SLIDE = 'mdlext-lightbox__slider__slide';
  var STICKY_FOOTER = 'mdlext-lightbox--sticky-footer';
  var BUTTON = 'mdl-button';

  /**
   * https://github.com/google/material-design-lite/issues/4205
   * @constructor
   * @param {Element} element The element that will be upgraded.
   */
  var MaterialExtLightbox = function MaterialExtLightbox(element) {
    // Stores the element.
    this.element_ = element;

    // Initialize instance.
    this.init();
  };
  window['MaterialExtLightbox'] = MaterialExtLightbox;

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

    if (event) {
      if (event.keyCode === _constants.VK_ESC || event.keyCode === _constants.VK_SPACE || event.keyCode === _constants.VK_END || event.keyCode === _constants.VK_HOME || event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT || event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {

        if (event.keyCode !== _constants.VK_ESC) {
          event.preventDefault();
          event.stopPropagation();
        }

        var action = 'first';
        if (event.keyCode === _constants.VK_END) {
          action = 'last';
        } else if (event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT) {
          action = 'prev';
        } else if (event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {
          action = 'next';
        } else if (event.keyCode === _constants.VK_SPACE) {
          action = 'select';
        } else if (event.keyCode === _constants.VK_ESC) {
          action = 'cancel';
        }

        dispatchAction_(action, this);
      }
    }
  };

  /**
   * Handle button clicks
   * @param event
   * @private
   */
  MaterialExtLightbox.prototype.buttonClickHandler_ = function (event) {

    if (event) {
      event.preventDefault();
      event.stopPropagation();

      dispatchAction_(this.getAttribute('data-action') || '', this);

      var n = this.closest('.' + LIGHTBOX);
      if (n) {
        n.focus();
      }
    }
  };

  /**
   * Dispatches an action custom event
   * @param action
   * @param source
   * @param target
   * @private
   */
  var dispatchAction_ = function dispatchAction_(action, source) {
    var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source;


    target.dispatchEvent(new CustomEvent('action', {
      bubbles: true,
      cancelable: true,
      detail: {
        action: action || '',
        source: source
      }
    }));
  };

  /**
   * Reposition dialog if component parent element is "DIALOG"
   * @param lightboxElement
   * @private
   */
  var repositionDialog_ = function repositionDialog_(lightboxElement) {
    var footerHeight = function footerHeight(footer, isSticky) {
      return isSticky && footer ? footer.offsetHeight : 0;
    };

    var reposition = function reposition(dialog, fh) {
      if (window.getComputedStyle(dialog).position === 'absolute') {
        var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        var topValue = scrollTop + (window.innerHeight - dialog.offsetHeight - fh) / 2;
        dialog.style.top = Math.max(scrollTop, topValue) + 'px';
      }
    };

    var p = lightboxElement.parentNode;
    var dialog = p && p.nodeName === 'DIALOG' ? p : null;

    if (dialog && dialog.hasAttribute('open')) {
      lightboxElement.style.width = 'auto';
      lightboxElement.style.maxWidth = '100%';
      var img = lightboxElement.querySelector('img');
      if (img) {
        lightboxElement.style.maxWidth = img.naturalWidth !== undefined ? img.naturalWidth + 'px' : img.width + 'px' || '100%';
      }

      var fh = footerHeight(lightboxElement.querySelector('footer'), lightboxElement.classList.contains(STICKY_FOOTER));
      var vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - fh;
      if (dialog.offsetHeight > vh) {
        var n = 0;
        while (dialog.offsetHeight > vh && ++n < 4) {
          lightboxElement.style.width = lightboxElement.offsetWidth * vh / lightboxElement.offsetHeight + 'px';
        }
      }
      reposition(dialog, fh);
    }
  };

  /**
   * Handle image load
   * @param event
   * @private
   */

  MaterialExtLightbox.prototype.imgLoadHandler_ = function () /*event*/{
    repositionDialog_(this);
  };

  /**
   * Handle image drag
   * @param event
   * @private
     */
  MaterialExtLightbox.prototype.imgDragHandler_ = function (event) {

    var setStyles = function setStyles(element, properties) {
      //noinspection JSAnnotator
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;

      try {
        for (var _iterator = (0, _getIterator3.default)((0, _entries2.default)(properties)), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var _step$value = (0, _slicedToArray3.default)(_step.value, 2),
              key = _step$value[0],
              value = _step$value[1];

          element.style[key] = value;
        }
        // ... or:
        //for (const key in properties) {
        //  element.style[key] = properties[key];
        //}
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator.return) {
            _iterator.return();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }
    };

    event.preventDefault();
    //event.stopPropagation();

    var x = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);

    var img = this;
    img.style.opacity = '0.2';

    var slider = document.createElement('div');
    slider.classList.add(LIGHTBOX_SLIDER);
    setStyles(slider, { 'width': img.offsetWidth + 'px', 'height': img.offsetHeight + 'px' });

    var slide = document.createElement('div');
    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
    slide.textContent = '>';
    setStyles(slide, {
      'width': img.offsetWidth + 'px',
      'height': img.offsetHeight + 'px',
      'line-height': img.offsetHeight + 'px',
      'font-size': img.offsetHeight / 4 + 'px',
      'text-align': 'right',
      'background-image': 'url("' + (img.getAttribute('data-img-url-prev') || '') + '")'
    });
    slider.appendChild(slide);

    slide = document.createElement('div');
    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
    setStyles(slide, {
      'width': img.offsetWidth + 'px',
      'height': img.offsetHeight + 'px',
      'background-image': 'url("' + img.src + '")'
    });
    slider.appendChild(slide);

    slide = document.createElement('div');
    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
    slide.textContent = '<';
    setStyles(slide, {
      'width': img.offsetWidth + 'px',
      'height': img.offsetHeight + 'px',
      'line-height': img.offsetHeight + 'px',
      'font-size': img.offsetHeight / 4 + 'px',
      'text-align': 'left',
      'background-image': 'url("' + (img.getAttribute('data-img-url-next') || '') + '")'
    });
    slider.appendChild(slide);

    img.parentNode.appendChild(slider);

    // drag handler
    var drag = function drag(e) {
      e.preventDefault();
      var dx = (e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0)) - x; // TODO: maybe rewrite to improve performance

      if (slider.offsetWidth - Math.abs(dx) > 19) {
        slider.style.left = dx + 'px';
      }
    };

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

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

      var dx = slider.offsetLeft;
      img.parentNode.removeChild(slider);
      img.style.opacity = '1.0';

      if (Math.abs(dx) > 19) {
        dispatchAction_(dx > 0 ? 'prev' : 'next', img);
      }
    };

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

  /**
   * Initialize component
   */
  MaterialExtLightbox.prototype.init = function () {
    var _this = this;

    if (this.element_) {
      // Do the init required for this component to work
      this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this.element_), true);

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

      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + BUTTON))).forEach(function (button) {
        return button.addEventListener('click', _this.buttonClickHandler_.bind(button), false);
      });

      var figcaption = this.element_.querySelector('figcaption');
      if (figcaption) {
        figcaption.addEventListener('click', this.buttonClickHandler_.bind(figcaption), false);
      }

      var footer = this.element_.querySelector('footer');
      if (footer) {
        footer.addEventListener('click', this.buttonClickHandler_.bind(footer), false);
      }

      var img = this.element_.querySelector('img');
      if (img) {
        img.addEventListener('load', this.imgLoadHandler_.bind(this.element_), false);
        img.addEventListener('click', function (e) {
          return e.preventDefault();
        }, true);
        img.addEventListener('mousedown', this.imgDragHandler_.bind(img), true);
        img.addEventListener('touchstart', this.imgDragHandler_.bind(img), true);
      }
      window.addEventListener('resize', (0, _fullThrottle2.default)(function () {
        return repositionDialog_(_this.element_);
      }));
      window.addEventListener('orientationchange', function () {
        return repositionDialog_(_this.element_);
      });

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

  /*
   * Downgrade component
   * E.g remove listeners and clean up resources
   *
   * Nothing to downgrade
   *
  MaterialExtLightbox.prototype.mdlDowngrade_ = function() {
  };
  */

  /**
   * The component registers itself. It can assume componentHandler is available in the global scope.
   */
  /* jshint undef:false */
  componentHandler.register({
    constructor: MaterialExtLightbox,
    classAsString: 'MaterialExtLightbox',
    cssClass: 'mdlext-js-lightbox'
  });
})();