‘use strict’;

!function($) {

/**

* Interchange module.
* @module foundation.interchange
* @requires foundation.util.mediaQuery
* @requires foundation.util.timerAndImageLoader
*/

class Interchange {

/**
 * Creates a new instance of Interchange.
 * @class
 * @fires Interchange#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({}, Interchange.defaults, options);
  this.rules = [];
  this.currentPath = '';

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

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

/**
 * Initializes the Interchange plugin and calls functions to get interchange functioning on load.
 * @function
 * @private
 */
_init() {
  this._addBreakpoints();
  this._generateRules();
  this._reflow();
}

/**
 * Initializes events for Interchange.
 * @function
 * @private
 */
_events() {
  $(window).on('resize.zf.interchange', Foundation.util.throttle(() => {
    this._reflow();
  }, 50));
}

/**
 * Calls necessary functions to update Interchange upon DOM change
 * @function
 * @private
 */
_reflow() {
  var match;

  // Iterate through each rule, but only save the last match
  for (var i in this.rules) {
    if(this.rules.hasOwnProperty(i)) {
      var rule = this.rules[i];
      if (window.matchMedia(rule.query).matches) {
        match = rule;
      }
    }
  }

  if (match) {
    this.replace(match.path);
  }
}

/**
 * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object.
 * @function
 * @private
 */
_addBreakpoints() {
  for (var i in Foundation.MediaQuery.queries) {
    if (Foundation.MediaQuery.queries.hasOwnProperty(i)) {
      var query = Foundation.MediaQuery.queries[i];
      Interchange.SPECIAL_QUERIES[query.name] = query.value;
    }
  }
}

/**
 * Checks the Interchange element for the provided media query + content pairings
 * @function
 * @private
 * @param {Object} element - jQuery object that is an Interchange instance
 * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys
 */
_generateRules(element) {
  var rulesList = [];
  var rules;

  if (this.options.rules) {
    rules = this.options.rules;
  }
  else {
    rules = this.$element.data('interchange');
  }

  rules =  typeof rules === 'string' ? rules.match(/\[.*?\]/g) : rules;

  for (var i in rules) {
    if(rules.hasOwnProperty(i)) {
      var rule = rules[i].slice(1, -1).split(', ');
      var path = rule.slice(0, -1).join('');
      var query = rule[rule.length - 1];

      if (Interchange.SPECIAL_QUERIES[query]) {
        query = Interchange.SPECIAL_QUERIES[query];
      }

      rulesList.push({
        path: path,
        query: query
      });
    }
  }

  this.rules = rulesList;
}

/**
 * Update the `src` property of an image, or change the HTML of a container, to the specified path.
 * @function
 * @param {String} path - Path to the image or HTML partial.
 * @fires Interchange#replaced
 */
replace(path) {
  if (this.currentPath === path) return;

  var _this = this,
      trigger = 'replaced.zf.interchange';

  // Replacing images
  if (this.$element[0].nodeName === 'IMG') {
    this.$element.attr('src', path).on('load', function() {
      _this.currentPath = path;
    })
    .trigger(trigger);
  }
  // Replacing background images
  else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) {
    this.$element.css({ 'background-image': 'url('+path+')' })
        .trigger(trigger);
  }
  // Replacing HTML
  else {
    $.get(path, function(response) {
      _this.$element.html(response)
           .trigger(trigger);
      $(response).foundation();
      _this.currentPath = path;
    });
  }

  /**
   * Fires when content in an Interchange element is done being loaded.
   * @event Interchange#replaced
   */
  // this.$element.trigger('replaced.zf.interchange');
}

/**
 * Destroys an instance of interchange.
 * @function
 */
destroy() {
  //TODO this.
}

}

/**

* Default settings for plugin
*/

Interchange.defaults = {

/**
 * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation.
 * @option
 * @type {?array}
 * @default null
 */
rules: null

};

Interchange.SPECIAL_QUERIES = {

'landscape': 'screen and (orientation: landscape)',
'portrait': 'screen and (orientation: portrait)',
'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)'

};

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

}(jQuery);