‘use strict’;

!function($) {

/**

* Toggler module.
* @module foundation.toggler
* @requires foundation.util.motion
* @requires foundation.util.triggers
*/

class Toggler {

/**
 * Creates a new instance of Toggler.
 * @class
 * @fires Toggler#init
 * @param {Object} element - jQuery object to add the trigger to.
 * @param {Object} options - Overrides to the default plugin settings.
 */
constructor(element, options) {
  this.$element = element;
  this.options = $.extend({}, Toggler.defaults, element.data(), options);
  this.className = '';

  this._init();
  this._events();

  Foundation.registerPlugin(this, 'Toggler');
}

/**
 * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate.
 * @function
 * @private
 */
_init() {
  var input;
  // Parse animation classes if they were set
  if (this.options.animate) {
    input = this.options.animate.split(' ');

    this.animationIn = input[0];
    this.animationOut = input[1] || null;
  }
  // Otherwise, parse toggle class
  else {
    input = this.$element.data('toggler');
    // Allow for a . at the beginning of the string
    this.className = input[0] === '.' ? input.slice(1) : input;
  }

  // Add ARIA attributes to triggers
  var id = this.$element[0].id;
  $(`[data-open="${id}"], [data-close="${id}"], [data-toggle="${id}"]`)
    .attr('aria-controls', id);
  // If the target is hidden, add aria-hidden
  this.$element.attr('aria-expanded', this.$element.is(':hidden') ? false : true);
}

/**
 * Initializes events for the toggle trigger.
 * @function
 * @private
 */
_events() {
  this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this));
}

/**
 * Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off".
 * @function
 * @fires Toggler#on
 * @fires Toggler#off
 */
toggle() {
  this[ this.options.animate ? '_toggleAnimate' : '_toggleClass']();
}

_toggleClass() {
  this.$element.toggleClass(this.className);

  var isOn = this.$element.hasClass(this.className);
  if (isOn) {
    /**
     * Fires if the target element has the class after a toggle.
     * @event Toggler#on
     */
    this.$element.trigger('on.zf.toggler');
  }
  else {
    /**
     * Fires if the target element does not have the class after a toggle.
     * @event Toggler#off
     */
    this.$element.trigger('off.zf.toggler');
  }

  this._updateARIA(isOn);
  this.$element.find('[data-mutate]').trigger('mutateme.zf.trigger');
}

_toggleAnimate() {
  var _this = this;

  if (this.$element.is(':hidden')) {
    Foundation.Motion.animateIn(this.$element, this.animationIn, function() {
      _this._updateARIA(true);
      this.trigger('on.zf.toggler');
      this.find('[data-mutate]').trigger('mutateme.zf.trigger');
    });
  }
  else {
    Foundation.Motion.animateOut(this.$element, this.animationOut, function() {
      _this._updateARIA(false);
      this.trigger('off.zf.toggler');
      this.find('[data-mutate]').trigger('mutateme.zf.trigger');
    });
  }
}

_updateARIA(isOn) {
  this.$element.attr('aria-expanded', isOn ? true : false);
}

/**
 * Destroys the instance of Toggler on the element.
 * @function
 */
destroy() {
  this.$element.off('.zf.toggler');
  Foundation.unregisterPlugin(this);
}

}

Toggler.defaults = {

/**
 * Tells the plugin if the element should animated when toggled.
 * @option
 * @type {boolean}
 * @default false
 */
animate: false

};

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

}(jQuery);