'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
/**
 * Helper functions for working with options and option lists.
 */

/**
 * Retrieve the option for a given value in an option list.
 * @param {Object[]} options - The options
 * @param {string} value - The value
 * @returns {Object} The option whose value exactly equals the given value. If more than one option
 * has the value, the first is returned. If no option has the value, null is returned.
 */
var getOptionForValue = exports.getOptionForValue = function getOptionForValue(options, value) {
  var option = null;

  // TODO: Use Array.find when it is supported in all browsers.

  if (options) {
    for (var i = 0; i < options.length; i += 1) {
      var candidateOption = options[i];

      if (candidateOption.value === value) {
        option = candidateOption;
        break;
      }
    }
  }

  return option;
};

/**
 * Retrieve the label for a given value in an option list.
 * @param {Object[]} options - The options
 * @param {string} value - The value
 * @returns {string} The label of the option whose value exactly equals the given value. If more
 * than one option has the value, the first is returned. If no option has the value, null is
 * returned.
 */
var getLabelForValue = exports.getLabelForValue = function getLabelForValue(options, value) {
  var option = getOptionForValue(options, value);

  return option ? option.label : null;
};

/**
 * Retrieve the option for a given label in an option list.
 * @param {Object[]} options - The options
 * @param {string} label - The label
 * @returns {Object} The option whose label exactly equals the given label. If more than one option
 * has the label, the first is returned. If no option has the label, null is returned.
 */
var getOptionForLabel = exports.getOptionForLabel = function getOptionForLabel(options, label) {
  var option = null;

  // TODO: Use Array.find when it is supported in all browsers.

  for (var i = 0; i < options.length; i += 1) {
    var candidateOption = options[i];

    if (candidateOption.label === label) {
      option = candidateOption;
      break;
    }
  }

  return option;
};

/**
 * Filter an option list by a given prefix. An option is retained by the filter if its label begins
 * with the prefix, case-insensitively.
 * @param {Object[]} options - The options to filter
 * @param {string} prefix - The prefix by which to filter
 * @returns {Object[]} An array of options whose labels begin with the prefix
 */
var filterOptionsByPrefix = exports.filterOptionsByPrefix = function filterOptionsByPrefix(options, prefix) {
  if (!prefix) {
    return options;
  }

  var normalizedPrefix = prefix.toLowerCase();

  // TODO: Use String.startsWith when it is supported in all browsers.

  return options.filter(function (option) {
    return option.label.toLowerCase().indexOf(normalizedPrefix, 0) === 0;
  });
};

/**
 * Normalize an option list. In options where the label is null or undefined, the label is set to
 * the option value. If the list is blankable, an option with empty value and label is added as the
 * first option. This function does not mutate the passed options.
 * @param {Object[]} options - The options to normalize
 * @param {boolean} blankable - If true, add a blank option to the beginning of the list
 * @returns {Object[]} A new array of normalized options
 */
var normalizeOptions = exports.normalizeOptions = function normalizeOptions(options, blankable) {
  var normalizedOptions = [];

  if (blankable) {
    normalizedOptions.push({
      value: '',
      label: ''
    });
  }

  if (options) {
    options.forEach(function (option) {
      var value = option.value;
      var label = option.label;

      if (label === null || typeof label === 'undefined') {
        label = value;
      }

      normalizedOptions.push({
        value: value,
        label: label
      });
    });
  }

  return normalizedOptions;
};