‘use strict’;

!function($) {

/**

* ResponsiveAccordionTabs module.
* @module foundation.responsiveAccordionTabs
* @requires foundation.util.keyboard
* @requires foundation.util.timerAndImageLoader
* @requires foundation.util.motion
* @requires foundation.accordion
* @requires foundation.tabs
*/

class ResponsiveAccordionTabs {

/**
 * Creates a new instance of a responsive accordion tabs.
 * @class
 * @fires ResponsiveAccordionTabs#init
 * @param {jQuery} element - jQuery object to make into a dropdown menu.
 * @param {Object} options - Overrides to the default plugin settings.
 */
constructor(element, options) {
  this.$element = $(element);
  this.options  = $.extend({}, this.$element.data(), options);
  this.rules = this.$element.data('responsive-accordion-tabs');
  this.currentMq = null;
  this.currentPlugin = null;
  if (!this.$element.attr('id')) {
    this.$element.attr('id',Foundation.GetYoDigits(6, 'responsiveaccordiontabs'));
  };

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

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

/**
 * Initializes the Menu by parsing the classes from the 'data-responsive-accordion-tabs' attribute on the element.
 * @function
 * @private
 */
_init() {
  // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules
  if (typeof this.rules === 'string') {
    let rulesTree = {};

    // Parse rules from "classes" pulled from data attribute
    let rules = this.rules.split(' ');

    // Iterate through every rule found
    for (let i = 0; i < rules.length; i++) {
      let rule = rules[i].split('-');
      let ruleSize = rule.length > 1 ? rule[0] : 'small';
      let rulePlugin = rule.length > 1 ? rule[1] : rule[0];

      if (MenuPlugins[rulePlugin] !== null) {
        rulesTree[ruleSize] = MenuPlugins[rulePlugin];
      }
    }

    this.rules = rulesTree;
  }

  this._getAllOptions();

  if (!$.isEmptyObject(this.rules)) {
    this._checkMediaQueries();
  }
}

_getAllOptions() {
  //get all defaults and options
  var _this = this;
  _this.allOptions = {};
  for (var key in MenuPlugins) {
    if (MenuPlugins.hasOwnProperty(key)) {
      var obj = MenuPlugins[key];
      try {
        var dummyPlugin = $('<ul></ul>');
        var tmpPlugin = new obj.plugin(dummyPlugin,_this.options);
        for (var keyKey in tmpPlugin.options) {
          if (tmpPlugin.options.hasOwnProperty(keyKey) && keyKey !== 'zfPlugin') {
            var objObj = tmpPlugin.options[keyKey];
            _this.allOptions[keyKey] = objObj;
          }
        }
        tmpPlugin.destroy();
      }
      catch(e) {
      }
    }
  }
}

/**
 * Initializes events for the Menu.
 * @function
 * @private
 */
_events() {
  var _this = this;

  $(window).on('changed.zf.mediaquery', function() {
    _this._checkMediaQueries();
  });
}

/**
 * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out.
 * @function
 * @private
 */
_checkMediaQueries() {
  var matchedMq, _this = this;
  // Iterate through each rule and find the last matching rule
  $.each(this.rules, function(key) {
    if (Foundation.MediaQuery.atLeast(key)) {
      matchedMq = key;
    }
  });

  // No match? No dice
  if (!matchedMq) return;

  // Plugin already initialized? We good
  if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return;

  // Remove existing plugin-specific CSS classes
  $.each(MenuPlugins, function(key, value) {
    _this.$element.removeClass(value.cssClass);
  });

  // Add the CSS class for the new plugin
  this.$element.addClass(this.rules[matchedMq].cssClass);

  // Create an instance of the new plugin
  if (this.currentPlugin) {
    //don't know why but on nested elements data zfPlugin get's lost
    if (!this.currentPlugin.$element.data('zfPlugin') && this.storezfData) this.currentPlugin.$element.data('zfPlugin',this.storezfData);
    this.currentPlugin.destroy();
  }
  this._handleMarkup(this.rules[matchedMq].cssClass);
  this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {});
  this.storezfData = this.currentPlugin.$element.data('zfPlugin');

}

_handleMarkup(toSet){
  var _this = this, fromString = 'accordion';
  var $panels = $('[data-tabs-content='+this.$element.attr('id')+']');
  if ($panels.length) fromString = 'tabs';
  if (fromString === toSet) {
    return;
  };

  var tabsTitle = _this.allOptions.linkClass?_this.allOptions.linkClass:'tabs-title';
  var tabsPanel = _this.allOptions.panelClass?_this.allOptions.panelClass:'tabs-panel';

  this.$element.removeAttr('role');
  var $liHeads = this.$element.children('.'+tabsTitle+',[data-accordion-item]').removeClass(tabsTitle).removeClass('accordion-item').removeAttr('data-accordion-item');
  var $liHeadsA = $liHeads.children('a').removeClass('accordion-title');

  if (fromString === 'tabs') {
    $panels = $panels.children('.'+tabsPanel).removeClass(tabsPanel).removeAttr('role').removeAttr('aria-hidden').removeAttr('aria-labelledby');
    $panels.children('a').removeAttr('role').removeAttr('aria-controls').removeAttr('aria-selected');
  }else{
    $panels = $liHeads.children('[data-tab-content]').removeClass('accordion-content');
  };

  $panels.css({display:'',visibility:''});
  $liHeads.css({display:'',visibility:''});
  if (toSet === 'accordion') {
    $panels.each(function(key,value){
      $(value).appendTo($liHeads.get(key)).addClass('accordion-content').attr('data-tab-content','').removeClass('is-active').css({height:''});
      $('[data-tabs-content='+_this.$element.attr('id')+']').after('<div id="tabs-placeholder-'+_this.$element.attr('id')+'"></div>').remove();
      $liHeads.addClass('accordion-item').attr('data-accordion-item','');
      $liHeadsA.addClass('accordion-title');
    });
  }else if (toSet === 'tabs'){
    var $tabsContent = $('[data-tabs-content='+_this.$element.attr('id')+']');
    var $placeholder = $('#tabs-placeholder-'+_this.$element.attr('id'));
    if ($placeholder.length) {
      $tabsContent = $('<div class="tabs-content"></div>').insertAfter($placeholder).attr('data-tabs-content',_this.$element.attr('id'));
      $placeholder.remove();
    }else{
      $tabsContent = $('<div class="tabs-content"></div>').insertAfter(_this.$element).attr('data-tabs-content',_this.$element.attr('id'));
    };
    $panels.each(function(key,value){
      var tempValue = $(value).appendTo($tabsContent).addClass(tabsPanel);
      var hash = $liHeadsA.get(key).hash.slice(1);
      var id = $(value).attr('id') || Foundation.GetYoDigits(6, 'accordion');
      if (hash !== id) {
        if (hash !== '') {
          $(value).attr('id',hash);
        }else{
          hash = id;
          $(value).attr('id',hash);
          $($liHeadsA.get(key)).attr('href',$($liHeadsA.get(key)).attr('href').replace('#','')+'#'+hash);
        };
      };
      var isActive = $($liHeads.get(key)).hasClass('is-active');
      if (isActive) {
        tempValue.addClass('is-active');
      };
    });
    $liHeads.addClass(tabsTitle);
  };
}

/**
 * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out.
 * @function
 */
destroy() {
  if (this.currentPlugin) this.currentPlugin.destroy();
  $(window).off('.zf.ResponsiveAccordionTabs');
  Foundation.unregisterPlugin(this);
}

}

ResponsiveAccordionTabs.defaults = {};

// The plugin matches the plugin classes with these plugin instances. var MenuPlugins = {

tabs: {
  cssClass: 'tabs',
  plugin: Foundation._plugins.tabs || null
},
accordion: {
  cssClass: 'accordion',
  plugin: Foundation._plugins.accordion || null
}

};

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

}(jQuery);