‘use strict’;

!function($) {

/**

* AccordionMenu module.
* @module foundation.accordionMenu
* @requires foundation.util.keyboard
* @requires foundation.util.motion
* @requires foundation.util.nest
*/

class AccordionMenu {

/**
 * Creates a new instance of an accordion menu.
 * @class
 * @fires AccordionMenu#init
 * @param {jQuery} element - jQuery object to make into an accordion menu.
 * @param {Object} options - Overrides to the default plugin settings.
 */
constructor(element, options) {
  this.$element = element;
  this.options = $.extend({}, AccordionMenu.defaults, this.$element.data(), options);

  Foundation.Nest.Feather(this.$element, 'accordion');

  this._init();

  Foundation.registerPlugin(this, 'AccordionMenu');
  Foundation.Keyboard.register('AccordionMenu', {
    'ENTER': 'toggle',
    'SPACE': 'toggle',
    'ARROW_RIGHT': 'open',
    'ARROW_UP': 'up',
    'ARROW_DOWN': 'down',
    'ARROW_LEFT': 'close',
    'ESCAPE': 'closeAll'
  });
}

/**
 * Initializes the accordion menu by hiding all nested menus.
 * @private
 */
_init() {
  this.$element.find('[data-submenu]').not('.is-active').slideUp(0);//.find('a').css('padding-left', '1rem');
  this.$element.attr({
    'role': 'menu',
    'aria-multiselectable': this.options.multiOpen
  });

  this.$menuLinks = this.$element.find('.is-accordion-submenu-parent');
  this.$menuLinks.each(function(){
    var linkId = this.id || Foundation.GetYoDigits(6, 'acc-menu-link'),
        $elem = $(this),
        $sub = $elem.children('[data-submenu]'),
        subId = $sub[0].id || Foundation.GetYoDigits(6, 'acc-menu'),
        isActive = $sub.hasClass('is-active');
    $elem.attr({
      'aria-controls': subId,
      'aria-expanded': isActive,
      'role': 'menuitem',
      'id': linkId
    });
    $sub.attr({
      'aria-labelledby': linkId,
      'aria-hidden': !isActive,
      'role': 'menu',
      'id': subId
    });
  });
  var initPanes = this.$element.find('.is-active');
  if(initPanes.length){
    var _this = this;
    initPanes.each(function(){
      _this.down($(this));
    });
  }
  this._events();
}

/**
 * Adds event handlers for items within the menu.
 * @private
 */
_events() {
  var _this = this;

  this.$element.find('li').each(function() {
    var $submenu = $(this).children('[data-submenu]');

    if ($submenu.length) {
      $(this).children('a').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function(e) {
        e.preventDefault();

        _this.toggle($submenu);
      });
    }
  }).on('keydown.zf.accordionmenu', function(e){
    var $element = $(this),
        $elements = $element.parent('ul').children('li'),
        $prevElement,
        $nextElement,
        $target = $element.children('[data-submenu]');

    $elements.each(function(i) {
      if ($(this).is($element)) {
        $prevElement = $elements.eq(Math.max(0, i-1)).find('a').first();
        $nextElement = $elements.eq(Math.min(i+1, $elements.length-1)).find('a').first();

        if ($(this).children('[data-submenu]:visible').length) { // has open sub menu
          $nextElement = $element.find('li:first-child').find('a').first();
        }
        if ($(this).is(':first-child')) { // is first element of sub menu
          $prevElement = $element.parents('li').first().find('a').first();
        } else if ($prevElement.parents('li').first().children('[data-submenu]:visible').length) { // if previous element has open sub menu
          $prevElement = $prevElement.parents('li').find('li:last-child').find('a').first();
        }
        if ($(this).is(':last-child')) { // is last element of sub menu
          $nextElement = $element.parents('li').first().next('li').find('a').first();
        }

        return;
      }
    });

    Foundation.Keyboard.handleKey(e, 'AccordionMenu', {
      open: function() {
        if ($target.is(':hidden')) {
          _this.down($target);
          $target.find('li').first().find('a').first().focus();
        }
      },
      close: function() {
        if ($target.length && !$target.is(':hidden')) { // close active sub of this item
          _this.up($target);
        } else if ($element.parent('[data-submenu]').length) { // close currently open sub
          _this.up($element.parent('[data-submenu]'));
          $element.parents('li').first().find('a').first().focus();
        }
      },
      up: function() {
        $prevElement.focus();
        return true;
      },
      down: function() {
        $nextElement.focus();
        return true;
      },
      toggle: function() {
        if ($element.children('[data-submenu]').length) {
          _this.toggle($element.children('[data-submenu]'));
        }
      },
      closeAll: function() {
        _this.hideAll();
      },
      handled: function(preventDefault) {
        if (preventDefault) {
          e.preventDefault();
        }
        e.stopImmediatePropagation();
      }
    });
  });//.attr('tabindex', 0);
}

/**
 * Closes all panes of the menu.
 * @function
 */
hideAll() {
  this.up(this.$element.find('[data-submenu]'));
}

/**
 * Opens all panes of the menu.
 * @function
 */
showAll() {
  this.down(this.$element.find('[data-submenu]'));
}

/**
 * Toggles the open/close state of a submenu.
 * @function
 * @param {jQuery} $target - the submenu to toggle
 */
toggle($target){
  if(!$target.is(':animated')) {
    if (!$target.is(':hidden')) {
      this.up($target);
    }
    else {
      this.down($target);
    }
  }
}

/**
 * Opens the sub-menu defined by `$target`.
 * @param {jQuery} $target - Sub-menu to open.
 * @fires AccordionMenu#down
 */
down($target) {
  var _this = this;

  if(!this.options.multiOpen) {
    this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target)));
  }

  $target.addClass('is-active').attr({'aria-hidden': false})
    .parent('.is-accordion-submenu-parent').attr({'aria-expanded': true});

    //Foundation.Move(this.options.slideSpeed, $target, function() {
      $target.slideDown(_this.options.slideSpeed, function () {
        /**
         * Fires when the menu is done opening.
         * @event AccordionMenu#down
         */
        _this.$element.trigger('down.zf.accordionMenu', [$target]);
      });
    //});
}

/**
 * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well.
 * @param {jQuery} $target - Sub-menu to close.
 * @fires AccordionMenu#up
 */
up($target) {
  var _this = this;
  //Foundation.Move(this.options.slideSpeed, $target, function(){
    $target.slideUp(_this.options.slideSpeed, function () {
      /**
       * Fires when the menu is done collapsing up.
       * @event AccordionMenu#up
       */
      _this.$element.trigger('up.zf.accordionMenu', [$target]);
    });
  //});

  var $menus = $target.find('[data-submenu]').slideUp(0).addBack().attr('aria-hidden', true);

  $menus.parent('.is-accordion-submenu-parent').attr('aria-expanded', false);
}

/**
 * Destroys an instance of accordion menu.
 * @fires AccordionMenu#destroyed
 */
destroy() {
  this.$element.find('[data-submenu]').slideDown(0).css('display', '');
  this.$element.find('a').off('click.zf.accordionMenu');

  Foundation.Nest.Burn(this.$element, 'accordion');
  Foundation.unregisterPlugin(this);
}

}

AccordionMenu.defaults = {

/**
 * Amount of time to animate the opening of a submenu in ms.
 * @option
 * @type {number}
 * @default 250
 */
slideSpeed: 250,
/**
 * Allow the menu to have multiple open panes.
 * @option
 * @type {boolean}
 * @default true
 */
multiOpen: true

};

// Window exports Foundation.plugin(AccordionMenu, ‘AccordionMenu’);

}(jQuery);