'use strict';

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _jsonUtils = require('../utils/json-utils');

var _constants = require('../utils/constants');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * @license
 * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This code is built with Google Material Design Lite,
 * which is Licensed under the Apache License, Version 2.0
 */

var JS_FORMAT_FIELD = 'mdlext-js-formatfield';
var FORMAT_FIELD_COMPONENT = 'MaterialExtFormatfield';

/**
 * Detect browser locale
 * @returns {string} the locale
 * @see http://stackoverflow.com/questions/1043339/javascript-for-detecting-browser-language-preference
 */
var browserLanguage = function browserLanguage() {
  return navigator.languages ? navigator.languages[0] : navigator.language || navigator.userLanguage;
};

/**
 * The formatfield  formats an input field  using language sensitive number formatting.
 */

var FormatField = function () {
  function FormatField(element) {
    var _this = this;

    (0, _classCallCheck3.default)(this, FormatField);
    this.options_ = {};

    this.clickHandler = function () {
      clearTimeout(FormatField.timer);
    };

    this.focusInHandler = function () {
      if (!(_this.input.readOnly || _this.input.disabled)) {
        _this.input.value = _this.unformatInput();
        //setTimeout(() => this.input.setSelectionRange(0, this.input.value.length), 20);
        FormatField.timer = setTimeout(function () {
          return _this.input.select();
        }, 200);
      }
    };

    this.focusOutHandler = function () {
      clearTimeout(FormatField.timer);

      if (!(_this.input.readOnly || _this.input.disabled)) {
        _this.formatValue();
      }
    };

    this.element_ = element;
    this.init();
  }

  (0, _createClass3.default)(FormatField, [{
    key: 'stripSeparatorsFromValue',
    value: function stripSeparatorsFromValue() {
      var _this2 = this;

      var doReplace = function doReplace() {
        return _this2.input.value.replace(/\s/g, '').replace(new RegExp(_this2.options.groupSeparator, 'g'), '').replace(_this2.options.decimalSeparator, '.');
      };
      //.replace(this.intlGroupSeparator_, ''),
      //.replace(this.intlDecimalSeparator_, '.');

      return this.input.value ? doReplace() : this.input.value;
    }
  }, {
    key: 'fixSeparators',
    value: function fixSeparators(value) {
      var _this3 = this;

      var doReplace = function doReplace() {
        return value.replace(new RegExp(_this3.intlGroupSeparator_, 'g'), _this3.options.groupSeparator).replace(_this3.intlDecimalSeparator_, _this3.options.decimalSeparator);
      };

      return value ? doReplace() : value;
    }
  }, {
    key: 'formatValue',
    value: function formatValue() {
      if (this.input.value) {
        var v = new Intl.NumberFormat(this.options.locales, this.options).format(this.stripSeparatorsFromValue());

        if ('NaN' !== v) {
          this.input.value = this.fixSeparators(v);
        }
      }
    }
  }, {
    key: 'unformat',
    value: function unformat() {
      var _this4 = this;

      var doReplace = function doReplace() {
        return _this4.input.value.replace(/\s/g, '').replace(new RegExp(_this4.options.groupSeparator, 'g'), '').replace(_this4.options.decimalSeparator, '.');
      };

      return this.input.value ? doReplace() : this.input.value;
    }
  }, {
    key: 'unformatInput',
    value: function unformatInput() {
      var _this5 = this;

      var doReplace = function doReplace() {
        return _this5.input.value.replace(/\s/g, '').replace(new RegExp(_this5.options.groupSeparator, 'g'), '');
      };

      return this.input.value ? doReplace() : this.input.value;
    }
  }, {
    key: 'removeListeners',
    value: function removeListeners() {
      this.input.removeEventListener('click', this.clickHandler);
      this.input.removeEventListener('focusin', this.focusInHandler);
      this.input.removeEventListener('focusout', this.focusOutHandler);
    }
  }, {
    key: 'init',
    value: function init() {
      var _this6 = this;

      var addListeners = function addListeners() {
        _this6.input.addEventListener('click', _this6.clickHandler);
        _this6.input.addEventListener('focusin', _this6.focusInHandler);
        _this6.input.addEventListener('focusout', _this6.focusOutHandler);
      };

      var addOptions = function addOptions() {
        var opts = _this6.element.getAttribute('data-formatfield-options') || _this6.input.getAttribute('data-formatfield-options');
        if (opts) {
          _this6.options_ = (0, _jsonUtils.jsonStringToObject)(opts, _this6.options);
        }
      };

      var addLocale = function addLocale() {
        if (!_this6.options.locales) {
          _this6.options.locales = browserLanguage() || 'en-US'; //'nb-NO', //'en-US',
        }
      };

      var addGrouping = function addGrouping() {
        var s = 1234.5.toLocaleString(_this6.options.locales, {
          style: 'decimal',
          useGrouping: true,
          minimumFractionDigits: 1,
          maximumFractionDigits: 1
        });

        _this6.intlGroupSeparator_ = s.charAt(1);
        _this6.intlDecimalSeparator_ = s.charAt(s.length - 2);
        _this6.options.groupSeparator = _this6.options.groupSeparator || _this6.intlGroupSeparator_;
        _this6.options.decimalSeparator = _this6.options.decimalSeparator || _this6.intlDecimalSeparator_;

        if (_this6.options.groupSeparator === _this6.options.decimalSeparator) {
          var e = 'Error! options.groupSeparator, "' + _this6.options.groupSeparator + '" ' + 'and options.decimalSeparator, ' + ('"' + _this6.options.decimalSeparator + '" should not be equal');
          throw new Error(e);
        }
      };

      this.input_ = this.element.querySelector('input') || this.element;

      addOptions();
      addLocale();
      addGrouping();
      this.formatValue();
      addListeners();
    }
  }, {
    key: 'downgrade',
    value: function downgrade() {
      this.removeListeners();
    }
  }, {
    key: 'element',
    get: function get() {
      return this.element_;
    }
  }, {
    key: 'input',
    get: function get() {
      return this.input_;
    }
  }, {
    key: 'options',
    get: function get() {
      return this.options_;
    }
  }]);
  return FormatField;
}();

FormatField.timer = null;


(function () {
  'use strict';

  /**
   * @constructor
   * @param {HTMLElement} element The element that will be upgraded.
   */

  var MaterialExtFormatfield = function MaterialExtFormatfield(element) {
    this.element_ = element;
    this.formatField_ = null;

    // Initialize instance.
    this.init();
  };
  window['MaterialExtFormatfield'] = MaterialExtFormatfield;

  /**
   * Initialize component
   */
  MaterialExtFormatfield.prototype.init = function () {
    if (this.element_) {
      this.element_.classList.add(_constants.IS_UPGRADED);
      this.formatField_ = new FormatField(this.element_);

      // Listen to 'mdl-componentdowngraded' event
      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
    }
  };

  /**
   * Get options object
   *
   * @public
   *
   * @returns {Object} the options object
   */
  MaterialExtFormatfield.prototype.getOptions = function () {
    return this.formatField_.options;
  };
  MaterialExtFormatfield.prototype['getOptions'] = MaterialExtFormatfield.prototype.getOptions;

  /**
   * A unformatted value is a string value where the locale specific decimal separator
   * is replaced with a '.' separator and group separators are stripped.
   * The returned value is suitable for parsing to a JavaScript numerical value.
   *
   * @example
   * input.value = '1 234,5';
   * inputElement.MaterialExtFormatfield.getUnformattedValue();
   * // Returns '1234.5'
   *
   * @public
   *
   * @returns {String} the unformatted value
   */
  MaterialExtFormatfield.prototype.getUnformattedValue = function () {
    return this.formatField_.unformat();
  };
  MaterialExtFormatfield.prototype['getUnformattedValue'] = MaterialExtFormatfield.prototype.getUnformattedValue;

  /*
   * Downgrade component
   * E.g remove listeners and clean up resources
   */
  MaterialExtFormatfield.prototype.mdlDowngrade_ = function () {
    this.formatField_.downgrade();
  };

  // The component registers itself. It can assume componentHandler is available
  // in the global scope.
  /* eslint no-undef: 0 */
  componentHandler.register({
    constructor: MaterialExtFormatfield,
    classAsString: FORMAT_FIELD_COMPONENT,
    cssClass: JS_FORMAT_FIELD,
    widget: true
  });
})();