"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
/*!
 * jQuery Internationalization library
 *
 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
 *
 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
 * anything special to choose one license or the other and you don't have to
 * notify anyone which license you are using. You are free to use
 * UniversalLanguageSelector in commercial projects as long as the copyright
 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
 *
 * @licence GNU General Public Licence 2.0 or later
 * @licence MIT License
 */

(function ($) {
  'use strict';

  var MessageParserEmitter = function MessageParserEmitter() {
    this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
  };
  MessageParserEmitter.prototype = {
    constructor: MessageParserEmitter,
    /**
     * (We put this method definition here, and not in prototype, to make
     * sure it's not overwritten by any magic.) Walk entire node structure,
     * applying replacements and template functions when appropriate
     *
     * @param {Mixed} node abstract syntax tree (top node or subnode)
     * @param {Array} replacements for $1, $2, ... $n
     * @return {Mixed} single-string node or array of nodes suitable for
     *  jQuery appending.
     */
    emit: function emit(node, replacements) {
      var ret,
        subnodes,
        operation,
        messageParserEmitter = this;
      switch (_typeof(node)) {
        case 'string':
        case 'number':
          ret = node;
          break;
        case 'object':
          // node is an array of nodes
          subnodes = $.map(node.slice(1), function (n) {
            return messageParserEmitter.emit(n, replacements);
          });
          operation = node[0].toLowerCase();
          if (typeof messageParserEmitter[operation] === 'function') {
            ret = messageParserEmitter[operation](subnodes, replacements);
          } else {
            throw new Error('unknown operation "' + operation + '"');
          }
          break;
        case 'undefined':
          // Parsing the empty string (as an entire expression, or as a
          // paramExpression in a template) results in undefined
          // Perhaps a more clever parser can detect this, and return the
          // empty string? Or is that useful information?
          // The logical thing is probably to return the empty string here
          // when we encounter undefined.
          ret = '';
          break;
        default:
          throw new Error('unexpected type in AST: ' + _typeof(node));
      }
      return ret;
    },
    /**
     * Parsing has been applied depth-first we can assume that all nodes
     * here are single nodes Must return a single node to parents -- a
     * jQuery with synthetic span However, unwrap any other synthetic spans
     * in our children and pass them upwards
     *
     * @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
     * @return {string}
     */
    concat: function concat(nodes) {
      var result = '';
      $.each(nodes, function (i, node) {
        // strings, integers, anything else
        result += node;
      });
      return result;
    },
    /**
     * Return escaped replacement of correct index, or string if
     * unavailable. Note that we expect the parsed parameter to be
     * zero-based. i.e. $1 should have become [ 0 ]. if the specified
     * parameter is not found return the same string (e.g. "$99" ->
     * parameter 98 -> not found -> return "$99" ) TODO throw error if
     * nodes.length > 1 ?
     *
     * @param {Array} nodes One element, integer, n >= 0
     * @param {Array} replacements for $1, $2, ... $n
     * @return {string} replacement
     */
    replace: function replace(nodes, replacements) {
      var index = parseInt(nodes[0], 10);
      if (index < replacements.length) {
        // replacement is not a string, don't touch!
        return replacements[index];
      } else {
        // index not found, fallback to displaying variable
        return '$' + (index + 1);
      }
    },
    /**
     * Transform parsed structure into pluralization n.b. The first node may
     * be a non-integer (for instance, a string representing an Arabic
     * number). So convert it back with the current language's
     * convertNumber.
     *
     * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
     * @return {string} selected pluralized form according to current
     *  language.
     */
    plural: function plural(nodes) {
      var count = parseFloat(this.language.convertNumber(nodes[0], 10)),
        forms = nodes.slice(1);
      return forms.length ? this.language.convertPlural(count, forms) : '';
    },
    /**
     * Transform parsed structure into gender Usage
     * {{gender:gender|masculine|feminine|neutral}}.
     *
     * @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
     * @return {string} selected gender form according to current language
     */
    gender: function gender(nodes) {
      var gender = nodes[0],
        forms = nodes.slice(1);
      return this.language.gender(gender, forms);
    },
    /**
     * Transform parsed structure into grammar conversion. Invoked by
     * putting {{grammar:form|word}} in a message
     *
     * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}]
     * @return {string} selected grammatical form according to current
     *  language.
     */
    grammar: function grammar(nodes) {
      var form = nodes[0],
        word = nodes[1];
      return word && form && this.language.convertGrammar(word, form);
    }
  };
  $.extend($.i18n.parser.emitter, new MessageParserEmitter());
})(jQuery);