'use strict';

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

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

var _stringUtils = require('../utils/string-utils');

var _domUtils = require('../utils/dom-utils');

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

var JS_COLLAPSIBLE = 'mdlext-js-collapsible'; /**
                                               * @license
                                               * Copyright 2016-2017 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
                                               */

/**
 * A collapsible is a component to mark expandable and collapsible regions.
 * The component use the aria-expanded state to indicate whether regions of
 * the content are collapsible, and to expose whether a region is currently
 * expanded or collapsed.
 * @see https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions
 */

var COLLAPSIBLE_CONTROL_CLASS = 'mdlext-collapsible';
var COLLAPSIBLE_GROUP_CLASS = 'mdlext-collapsible-group';
var COLLAPSIBLE_REGION_CLASS = 'mdlext-collapsible-region';

/**
 * The collapsible component
 */

var Collapsible = function () {

  /**
   * @constructor
   * @param {HTMLElement} element The element that this component is connected to.
   */
  function Collapsible(element) {
    var _this = this;

    (0, _classCallCheck3.default)(this, Collapsible);
    this.element_ = null;
    this.controlElement_ = null;

    this.keyDownHandler = function (event) {
      if (event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE) {
        event.preventDefault();

        // Trigger click
        (event.target || _this.controlElement).dispatchEvent(new MouseEvent('click', {
          bubbles: true,
          cancelable: true,
          view: window
        }));
      }
    };

    this.clickHandler = function (event) {
      if (!_this.isDisabled) {
        if (event.target !== _this.controlElement) {
          // Do not toggle if a focusable element inside the control element triggered the event
          var p = (0, _domUtils.getParentElements)(event.target, _this.controlElement);
          p.push(event.target);
          if (p.find(function (el) {
            return (0, _domUtils.isFocusable)(el);
          })) {
            return;
          }
        }
        _this.toggle();
      }
    };

    this.element_ = element;
    this.init();
  }

  (0, _createClass3.default)(Collapsible, [{
    key: 'collapse',
    value: function collapse() {
      if (!this.isDisabled && this.isExpanded) {
        if (this.dispatchToggleEvent('collapse')) {
          this.controlElement.setAttribute('aria-expanded', 'false');
          var regions = this.regionElements.slice(0);
          for (var i = regions.length - 1; i >= 0; --i) {
            regions[i].setAttribute('hidden', '');
          }
        }
      }
    }
  }, {
    key: 'expand',
    value: function expand() {
      if (!this.isDisabled && !this.isExpanded) {
        if (this.dispatchToggleEvent('expand')) {
          this.controlElement.setAttribute('aria-expanded', 'true');
          this.regionElements.forEach(function (region) {
            return region.removeAttribute('hidden');
          });
        }
      }
    }
  }, {
    key: 'toggle',
    value: function toggle() {
      if (this.isExpanded) {
        this.collapse();
      } else {
        this.expand();
      }
    }
  }, {
    key: 'dispatchToggleEvent',
    value: function dispatchToggleEvent(action) {
      return this.element.dispatchEvent(new CustomEvent('toggle', {
        bubbles: true,
        cancelable: true,
        detail: {
          action: action
        }
      }));
    }
  }, {
    key: 'disableToggle',
    value: function disableToggle() {
      this.controlElement.setAttribute('aria-disabled', true);
    }
  }, {
    key: 'enableToggle',
    value: function enableToggle() {
      this.controlElement.removeAttribute('aria-disabled');
    }
  }, {
    key: 'addRegionId',
    value: function addRegionId(regionId) {
      var ids = this.regionIds;
      if (!ids.find(function (id) {
        return regionId === id;
      })) {
        ids.push(regionId);
        this.controlElement.setAttribute('aria-controls', ids.join(' '));
      }
    }
  }, {
    key: 'addRegionElement',
    value: function addRegionElement(region) {
      if (!(region.classList.contains(COLLAPSIBLE_GROUP_CLASS) || region.classList.contains(COLLAPSIBLE_REGION_CLASS))) {
        region.classList.add(COLLAPSIBLE_GROUP_CLASS);
      }

      if (!region.hasAttribute('role')) {
        var role = region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ? 'group' : 'region';
        region.setAttribute('role', role);
      }

      if (!region.hasAttribute('id')) {
        region.id = region.getAttribute('role') + '-' + (0, _stringUtils.randomString)();
      }

      if (this.isExpanded) {
        region.removeAttribute('hidden');
      } else {
        region.setAttribute('hidden', '');
      }
      this.addRegionId(region.id);
    }
  }, {
    key: 'removeRegionElement',
    value: function removeRegionElement(region) {
      if (region && region.id) {
        var ids = this.regionIds.filter(function (id) {
          return id === region.id;
        });
        this.controlElement.setAttribute('aria-controls', ids.join(' '));
      }
    }
  }, {
    key: 'removeListeners',
    value: function removeListeners() {
      this.controlElement.removeEventListener('keydown', this.keyDownHandler);
      this.controlElement.removeEventListener('click', this.clickHandler);
    }
  }, {
    key: 'init',
    value: function init() {
      var _this2 = this;

      var initControl = function initControl() {
        // Find the button element
        _this2.controlElement_ = _this2.element.querySelector('.' + COLLAPSIBLE_CONTROL_CLASS) || _this2.element;

        // Add "aria-expanded" attribute if not present
        if (!_this2.controlElement.hasAttribute('aria-expanded')) {
          _this2.controlElement.setAttribute('aria-expanded', 'false');
        }

        // Add role=button if control != <button>
        if (_this2.controlElement.nodeName.toLowerCase() !== 'button') {
          _this2.controlElement.setAttribute('role', 'button');
        }

        // Add tabindex
        if (!(0, _domUtils.isFocusable)(_this2.controlElement) && !_this2.controlElement.hasAttribute('tabindex')) {
          _this2.controlElement.setAttribute('tabindex', '0');
        }
      };

      var initRegions = function initRegions() {
        var regions = [];
        if (!_this2.controlElement.hasAttribute('aria-controls')) {
          // Add siblings as collapsible region(s)
          var r = _this2.element.nextElementSibling;
          while (r) {
            if (r.classList.contains(COLLAPSIBLE_GROUP_CLASS) || r.classList.contains(COLLAPSIBLE_REGION_CLASS)) {
              regions.push(r);
            } else if (r.classList.contains(JS_COLLAPSIBLE)) {
              // A new collapsible component
              break;
            }
            r = r.nextElementSibling;
          }
        } else {
          regions = _this2.regionElements;
        }
        regions.forEach(function (region) {
          return _this2.addRegionElement(region);
        });
      };

      var addListeners = function addListeners() {
        _this2.controlElement.addEventListener('keydown', _this2.keyDownHandler);
        _this2.controlElement.addEventListener('click', _this2.clickHandler);
      };

      initControl();
      initRegions();
      this.removeListeners();
      addListeners();
    }
  }, {
    key: 'downgrade',
    value: function downgrade() {
      this.removeListeners();
    }
  }, {
    key: 'element',
    get: function get() {
      return this.element_;
    }
  }, {
    key: 'controlElement',
    get: function get() {
      return this.controlElement_;
    }
  }, {
    key: 'isDisabled',
    get: function get() {
      return this.controlElement.hasAttribute('disabled') && this.controlElement.getAttribute('disabled').toLowerCase() !== 'false' || this.controlElement.hasAttribute('aria-disabled') && this.controlElement.getAttribute('aria-disabled').toLowerCase() !== 'false';
    }
  }, {
    key: 'isExpanded',
    get: function get() {
      return this.controlElement.hasAttribute('aria-expanded') && this.controlElement.getAttribute('aria-expanded').toLowerCase() === 'true';
    }
  }, {
    key: 'regionIds',
    get: function get() {
      return this.controlElement.hasAttribute('aria-controls') ? this.controlElement.getAttribute('aria-controls').split(' ') : [];
    }
  }, {
    key: 'regionElements',
    get: function get() {
      return this.regionIds.map(function (id) {
        return document.querySelector('#' + id);
      }).filter(function (el) {
        return el != null;
      });
    }
  }]);
  return Collapsible;
}();

(function () {
  'use strict';

  /**
   * @constructor
   * @param {HTMLElement} element The element that will be upgraded.
   */

  var MaterialExtCollapsible = function MaterialExtCollapsible(element) {
    this.element_ = element;
    this.collapsible = null;

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

  /**
   * Initialize component
   */
  MaterialExtCollapsible.prototype.init = function () {
    if (this.element_) {
      this.collapsible = new Collapsible(this.element_);
      this.element_.classList.add(_constants.IS_UPGRADED);

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

  /*
   * Downgrade component
   * E.g remove listeners and clean up resources
   */
  MaterialExtCollapsible.prototype.mdlDowngrade_ = function () {
    this.collapsible.downgrade();
  };

  // Public methods.

  /**
   * Get control element.
   * @return {HTMLElement} element The element that controls the collapsible region.
   * @public
   */
  MaterialExtCollapsible.prototype.getControlElement = function () {
    return this.collapsible.controlElement;
  };
  MaterialExtCollapsible.prototype['getControlElement'] = MaterialExtCollapsible.prototype.getControlElement;

  /**
   * Get region elements controlled by this collapsible
   * @returns {Array<HTMLElement>} the collapsible region elements
   * @public
   */
  MaterialExtCollapsible.prototype.getRegionElements = function () {
    return this.collapsible.regionElements;
  };
  MaterialExtCollapsible.prototype['getRegionElements'] = MaterialExtCollapsible.prototype.getRegionElements;

  /**
   * Add region elements.
   * @param {Array<HTMLElement>} elements The element that will be upgraded.
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.addRegionElements = function () {
    var _this3 = this;

    for (var _len = arguments.length, elements = Array(_len), _key = 0; _key < _len; _key++) {
      elements[_key] = arguments[_key];
    }

    elements.forEach(function (element) {
      return _this3.collapsible.addRegionElement(element);
    });
  };
  MaterialExtCollapsible.prototype['addRegionElements'] = MaterialExtCollapsible.prototype.addRegionElements;

  /**
   * Remove collapsible region(s) from component.
   * Note: This operation does not delete the element from the DOM tree.
   * @param {Array<HTMLElement>} elements The element that will be upgraded.
   * @public
   */
  MaterialExtCollapsible.prototype.removeRegionElements = function () {
    var _this4 = this;

    for (var _len2 = arguments.length, elements = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      elements[_key2] = arguments[_key2];
    }

    elements.forEach(function (element) {
      return _this4.collapsible.removeRegionElement(element);
    });
  };
  MaterialExtCollapsible.prototype['removeRegionElements'] = MaterialExtCollapsible.prototype.removeRegionElements;

  /**
   * Expand collapsible region(s)
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.expand = function () {
    this.collapsible.expand();
  };
  MaterialExtCollapsible.prototype['expand'] = MaterialExtCollapsible.prototype.expand;

  /**
   * Collapse collapsible region(s)
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.collapse = function () {
    this.collapsible.collapse();
  };
  MaterialExtCollapsible.prototype['collapse'] = MaterialExtCollapsible.prototype.collapse;

  /**
   * Toggle collapsible region(s)
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.toggle = function () {
    this.collapsible.toggle();
  };
  MaterialExtCollapsible.prototype['toggle'] = MaterialExtCollapsible.prototype.toggle;

  /**
   * Check whether component has aria-expanded state true
   * @return {Boolean} true if aria-expanded="true", otherwise false
   */
  MaterialExtCollapsible.prototype.isExpanded = function () {
    return this.collapsible.isExpanded;
  };
  MaterialExtCollapsible.prototype['isExpanded'] = MaterialExtCollapsible.prototype.isExpanded;

  /**
   * Check whether component has aria-disabled state set to true
   * @return {Boolean} true if aria-disabled="true", otherwise false
   */
  MaterialExtCollapsible.prototype.isDisabled = function () {
    return this.collapsible.isDisabled;
  };
  MaterialExtCollapsible.prototype['isDisabled'] = MaterialExtCollapsible.prototype.isDisabled;

  /**
   * Disables toggling of collapsible region(s)
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.disableToggle = function () {
    this.collapsible.disableToggle();
  };
  MaterialExtCollapsible.prototype['disableToggle'] = MaterialExtCollapsible.prototype.disableToggle;

  /**
   * Enables toggling of collapsible region(s)
   * @return {void}
   * @public
   */
  MaterialExtCollapsible.prototype.enableToggle = function () {
    this.collapsible.enableToggle();
  };
  MaterialExtCollapsible.prototype['enableToggle'] = MaterialExtCollapsible.prototype.enableToggle;

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