'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.replaceStr = undefined;

var _utils = require('./utils');

var codemap = [];
codemap[parseInt('0', 16)] =    require('./x0.json');
codemap[parseInt('1', 16)] =    require('./x1.json');
codemap[parseInt('1e', 16)] =   require('./x1e.json');
codemap[parseInt('1f', 16)] =   require('./x1f.json');
codemap[parseInt('2', 16)] =    require('./x2.json');
codemap[parseInt('2e', 16)] =   require('./x2e.json');
codemap[parseInt('2f', 16)] =   require('./x2f.json');
codemap[parseInt('3', 16)] =    require('./x3.json');
codemap[parseInt('4', 16)] =    require('./x4.json');
codemap[parseInt('4d', 16)] =   require('./x4d.json');
codemap[parseInt('4e', 16)] =   require('./x4e.json');
codemap[parseInt('4f', 16)] =   require('./x4f.json');
codemap[parseInt('5', 16)] =    require('./x5.json');
codemap[parseInt('5a', 16)] =   require('./x5a.json');
codemap[parseInt('5b', 16)] =   require('./x5b.json');
codemap[parseInt('5c', 16)] =   require('./x5c.json');
codemap[parseInt('5d', 16)] =   require('./x5d.json');
codemap[parseInt('5e', 16)] =   require('./x5e.json');
codemap[parseInt('5f', 16)] =   require('./x5f.json');
codemap[parseInt('6', 16)] =    require('./x6.json');
codemap[parseInt('6a', 16)] =   require('./x6a.json');
codemap[parseInt('6b', 16)] =   require('./x6b.json');
codemap[parseInt('6c', 16)] =   require('./x6c.json');
codemap[parseInt('6d', 16)] =   require('./x6d.json');
codemap[parseInt('6e', 16)] =   require('./x6e.json');
codemap[parseInt('6f', 16)] =   require('./x6f.json');
codemap[parseInt('7', 16)] =    require('./x7.json');
codemap[parseInt('7a', 16)] =   require('./x7a.json');
codemap[parseInt('7b', 16)] =   require('./x7b.json');
codemap[parseInt('7c', 16)] =   require('./x7c.json');
codemap[parseInt('7d', 16)] =   require('./x7d.json');
codemap[parseInt('7e', 16)] =   require('./x7e.json');
codemap[parseInt('7f', 16)] =   require('./x7f.json');
codemap[parseInt('8a', 16)] =   require('./x8a.json');
codemap[parseInt('8b', 16)] =   require('./x8b.json');
codemap[parseInt('8c', 16)] =   require('./x8c.json');
codemap[parseInt('8d', 16)] =   require('./x8d.json');
codemap[parseInt('8e', 16)] =   require('./x8e.json');
codemap[parseInt('8f', 16)] =   require('./x8f.json');
codemap[parseInt('9', 16)] =    require('./x9.json');
codemap[parseInt('9a', 16)] =   require('./x9a.json');
codemap[parseInt('9b', 16)] =   require('./x9b.json');
codemap[parseInt('9c', 16)] =   require('./x9c.json');
codemap[parseInt('9d', 16)] =   require('./x9d.json');
codemap[parseInt('9e', 16)] =   require('./x9e.json');
codemap[parseInt('9f', 16)] =   require('./x9f.json');
codemap[parseInt('10', 16)] =   require('./x10.json');
codemap[parseInt('11', 16)] =   require('./x11.json');
codemap[parseInt('12', 16)] =   require('./x12.json');
codemap[parseInt('13', 16)] =   require('./x13.json');
codemap[parseInt('14', 16)] =   require('./x14.json');
codemap[parseInt('15', 16)] =   require('./x15.json');
codemap[parseInt('16', 16)] =   require('./x16.json');
codemap[parseInt('17', 16)] =   require('./x17.json');
codemap[parseInt('18', 16)] =   require('./x18.json');
codemap[parseInt('20', 16)] =   require('./x20.json');
codemap[parseInt('21', 16)] =   require('./x21.json');
codemap[parseInt('22', 16)] =   require('./x22.json');
codemap[parseInt('23', 16)] =   require('./x23.json');
codemap[parseInt('24', 16)] =   require('./x24.json');
codemap[parseInt('25', 16)] =   require('./x25.json');
codemap[parseInt('26', 16)] =   require('./x26.json');
codemap[parseInt('27', 16)] =   require('./x27.json');
codemap[parseInt('28', 16)] =   require('./x28.json');
codemap[parseInt('30', 16)] =   require('./x30.json');
codemap[parseInt('31', 16)] =   require('./x31.json');
codemap[parseInt('32', 16)] =   require('./x32.json');
codemap[parseInt('33', 16)] =   require('./x33.json');
codemap[parseInt('50', 16)] =   require('./x50.json');
codemap[parseInt('51', 16)] =   require('./x51.json');
codemap[parseInt('52', 16)] =   require('./x52.json');
codemap[parseInt('53', 16)] =   require('./x53.json');
codemap[parseInt('54', 16)] =   require('./x54.json');
codemap[parseInt('55', 16)] =   require('./x55.json');
codemap[parseInt('56', 16)] =   require('./x56.json');
codemap[parseInt('57', 16)] =   require('./x57.json');
codemap[parseInt('58', 16)] =   require('./x58.json');
codemap[parseInt('59', 16)] =   require('./x59.json');
codemap[parseInt('60', 16)] =   require('./x60.json');
codemap[parseInt('61', 16)] =   require('./x61.json');
codemap[parseInt('62', 16)] =   require('./x62.json');
codemap[parseInt('63', 16)] =   require('./x63.json');
codemap[parseInt('64', 16)] =   require('./x64.json');
codemap[parseInt('65', 16)] =   require('./x65.json');
codemap[parseInt('66', 16)] =   require('./x66.json');
codemap[parseInt('67', 16)] =   require('./x67.json');
codemap[parseInt('68', 16)] =   require('./x68.json');
codemap[parseInt('69', 16)] =   require('./x69.json');
codemap[parseInt('70', 16)] =   require('./x70.json');
codemap[parseInt('71', 16)] =   require('./x71.json');
codemap[parseInt('72', 16)] =   require('./x72.json');
codemap[parseInt('73', 16)] =   require('./x73.json');
codemap[parseInt('74', 16)] =   require('./x74.json');
codemap[parseInt('75', 16)] =   require('./x75.json');
codemap[parseInt('76', 16)] =   require('./x76.json');
codemap[parseInt('77', 16)] =   require('./x77.json');
codemap[parseInt('78', 16)] =   require('./x78.json');
codemap[parseInt('79', 16)] =   require('./x79.json');
codemap[parseInt('80', 16)] =   require('./x80.json');
codemap[parseInt('81', 16)] =   require('./x81.json');
codemap[parseInt('82', 16)] =   require('./x82.json');
codemap[parseInt('83', 16)] =   require('./x83.json');
codemap[parseInt('84', 16)] =   require('./x84.json');
codemap[parseInt('85', 16)] =   require('./x85.json');
codemap[parseInt('86', 16)] =   require('./x86.json');
codemap[parseInt('87', 16)] =   require('./x87.json');
codemap[parseInt('88', 16)] =   require('./x88.json');
codemap[parseInt('89', 16)] =   require('./x89.json');
codemap[parseInt('90', 16)] =   require('./x90.json');
codemap[parseInt('91', 16)] =   require('./x91.json');
codemap[parseInt('92', 16)] =   require('./x92.json');
codemap[parseInt('93', 16)] =   require('./x93.json');
codemap[parseInt('94', 16)] =   require('./x94.json');
codemap[parseInt('95', 16)] =   require('./x95.json');
codemap[parseInt('96', 16)] =   require('./x96.json');
codemap[parseInt('97', 16)] =   require('./x97.json');
codemap[parseInt('98', 16)] =   require('./x98.json');
codemap[parseInt('99', 16)] =   require('./x99.json');
codemap[parseInt('a0', 16)] =   require('./xa0.json');
codemap[parseInt('a', 16)] =    require('./xa.json');
codemap[parseInt('a1', 16)] =   require('./xa1.json');
codemap[parseInt('a2', 16)] =   require('./xa2.json');
codemap[parseInt('a3', 16)] =   require('./xa3.json');
codemap[parseInt('a4', 16)] =   require('./xa4.json');
codemap[parseInt('ac', 16)] =   require('./xac.json');
codemap[parseInt('ad', 16)] =   require('./xad.json');
codemap[parseInt('ae', 16)] =   require('./xae.json');
codemap[parseInt('af', 16)] =   require('./xaf.json');
codemap[parseInt('b0', 16)] =   require('./xb0.json');
codemap[parseInt('b', 16)] =    require('./xb.json');
codemap[parseInt('b1', 16)] =   require('./xb1.json');
codemap[parseInt('b2', 16)] =   require('./xb2.json');
codemap[parseInt('b3', 16)] =   require('./xb3.json');
codemap[parseInt('b4', 16)] =   require('./xb4.json');
codemap[parseInt('b5', 16)] =   require('./xb5.json');
codemap[parseInt('b6', 16)] =   require('./xb6.json');
codemap[parseInt('b7', 16)] =   require('./xb7.json');
codemap[parseInt('b8', 16)] =   require('./xb8.json');
codemap[parseInt('b9', 16)] =   require('./xb9.json');
codemap[parseInt('ba', 16)] =   require('./xba.json');
codemap[parseInt('bb', 16)] =   require('./xbb.json');
codemap[parseInt('bc', 16)] =   require('./xbc.json');
codemap[parseInt('bd', 16)] =   require('./xbd.json');
codemap[parseInt('be', 16)] =   require('./xbe.json');
codemap[parseInt('bf', 16)] =   require('./xbf.json');
codemap[parseInt('c0', 16)] =   require('./xc0.json');
codemap[parseInt('c', 16)] =    require('./xc.json');
codemap[parseInt('c1', 16)] =   require('./xc1.json');
codemap[parseInt('c2', 16)] =   require('./xc2.json');
codemap[parseInt('c3', 16)] =   require('./xc3.json');
codemap[parseInt('c4', 16)] =   require('./xc4.json');
codemap[parseInt('c5', 16)] =   require('./xc5.json');
codemap[parseInt('c6', 16)] =   require('./xc6.json');
codemap[parseInt('c7', 16)] =   require('./xc7.json');
codemap[parseInt('c8', 16)] =   require('./xc8.json');
codemap[parseInt('c9', 16)] =   require('./xc9.json');
codemap[parseInt('ca', 16)] =   require('./xca.json');
codemap[parseInt('cb', 16)] =   require('./xcb.json');
codemap[parseInt('cc', 16)] =   require('./xcc.json');
codemap[parseInt('cd', 16)] =   require('./xcd.json');
codemap[parseInt('ce', 16)] =   require('./xce.json');
codemap[parseInt('cf', 16)] =   require('./xcf.json');
codemap[parseInt('d0', 16)] =   require('./xd0.json');
codemap[parseInt('d', 16)] =    require('./xd.json');
codemap[parseInt('d1', 16)] =   require('./xd1.json');
codemap[parseInt('d2', 16)] =   require('./xd2.json');
codemap[parseInt('d3', 16)] =   require('./xd3.json');
codemap[parseInt('d4', 16)] =   require('./xd4.json');
codemap[parseInt('d5', 16)] =   require('./xd5.json');
codemap[parseInt('d6', 16)] =   require('./xd6.json');
codemap[parseInt('d7', 16)] =   require('./xd7.json');
codemap[parseInt('e', 16)] =    require('./xe.json');
codemap[parseInt('f', 16)] =    require('./xf.json');
codemap[parseInt('f9', 16)] =   require('./xf9.json');
codemap[parseInt('fa', 16)] =   require('./xfa.json');
codemap[parseInt('fb', 16)] =   require('./xfb.json');
codemap[parseInt('fc', 16)] =   require('./xfc.json');
codemap[parseInt('fd', 16)] =   require('./xfd.json');
codemap[parseInt('fe', 16)] =   require('./xfe.json');
codemap[parseInt('ff', 16)] =   require('./xff.json');

var defaultOptions = {
  unknown: '[?]',
  replace: [],
  replaceAfter: [],
  ignore: []
};
var configOptions = {};

/* istanbul ignore next */
var replaceStr = exports.replaceStr = function replaceStr(str, replace) {
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = replace[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var item = _step.value;

      if (item[0] instanceof RegExp) {
        var flag = item[0].flags;
        if (!item[0].global) {
          flag += 'g';
          item[0] = new RegExp(item[0].toString().replace(/^\/|\/$/), flag);
        }
      } else if (typeof item[0] === 'string') {
        item[0] = new RegExp((0, _utils.escapeRegExp)(item[0]), 'g');
      }
      if (item[0] instanceof RegExp) {
        str = str.replace(item[0], item[1]);
      }
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  return str;
};

/**
 * @param {string} str The string which is being transliterated
 * @param options options
 */
/* istanbul ignore next */
var transliterate = function transliterate(str, options) {
  options = options ? (0, _utils.mergeOptions)(defaultOptions, options) : (0, _utils.mergeOptions)(defaultOptions, configOptions);
  str = String(str);
  if (options.ignore instanceof Array && options.ignore.length > 0) {
    for (var i in options.ignore) {
      var splitted = str.split(options.ignore[i]);
      var result = [];
      for (var j in splitted) {
        var ignore = options.ignore.slice(0);
        ignore.splice(i, 1);
        result.push(transliterate(splitted[j], (0, _utils.mergeOptions)(options, { ignore: ignore })));
      }
      return result.join(options.ignore[i]);
    }
  }
  str = replaceStr(str, options.replace);
  var strArr = (0, _utils.ucs2decode)((0, _utils.fixChineseSpace)(str));
  var strArrNew = [];

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = strArr[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var ord = _step2.value;

      // These characters are also transliteratable. Will improve it later if needed
      if (ord > 0xffff) {
        strArrNew.push(options.unknown);
        continue;
      }
      var offset = ord >> 8;
      if (typeof codemap[offset] === 'undefined') {
        try {
          codemap[offset] = require('x' + offset.toString(16) + '.json.js');
        } catch (e) {
          codemap[offset] = [];
        }
      }
      ord = 0xff & ord;
      var t = codemap[offset][ord];
      if (typeof t === 'undefined' || t === null) {
        strArrNew.push(options.unknown);
      } else {
        strArrNew.push(codemap[offset][ord]);
      }
    }
    // trim spaces at the begining and ending of the string
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  if (strArrNew.length > 1) {
    options.replaceAfter.push([/(^ +?)|( +?$)/g, '']);
  }
  var strNew = strArrNew.join('');

  strNew = replaceStr(strNew, options.replaceAfter);
  return strNew;
};

transliterate.setCodemap = function (customCodemap) {
  codemap = customCodemap || codemap;
  return codemap;
};

transliterate.config = function (options) {
  if (options === undefined) {
    return configOptions;
  }
  configOptions = (0, _utils.mergeOptions)(defaultOptions, options);
  return configOptions;
};

exports.default = transliterate;