"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.create = create;
exports.default = void 0;

var _locale = require("./locale");

var _isAbsent = _interopRequireDefault(require("./util/isAbsent"));

var _schema = _interopRequireDefault(require("./schema"));

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

let isNaN = value => value != +value;

function create() {
  return new NumberSchema();
}

class NumberSchema extends _schema.default {
  constructor() {
    super({
      type: 'number'
    });
    this.withMutation(() => {
      this.transform(function (value) {
        let parsed = value;

        if (typeof parsed === 'string') {
          parsed = parsed.replace(/\s/g, '');
          if (parsed === '') return NaN; // don't use parseFloat to avoid positives on alpha-numeric strings

          parsed = +parsed;
        }

        if (this.isType(parsed)) return parsed;
        return parseFloat(parsed);
      });
    });
  }

  _typeCheck(value) {
    if (value instanceof Number) value = value.valueOf();
    return typeof value === 'number' && !isNaN(value);
  }

  min(min, message = _locale.number.min) {
    return this.test({
      message,
      name: 'min',
      exclusive: true,
      params: {
        min
      },

      test(value) {
        return (0, _isAbsent.default)(value) || value >= this.resolve(min);
      }

    });
  }

  max(max, message = _locale.number.max) {
    return this.test({
      message,
      name: 'max',
      exclusive: true,
      params: {
        max
      },

      test(value) {
        return (0, _isAbsent.default)(value) || value <= this.resolve(max);
      }

    });
  }

  lessThan(less, message = _locale.number.lessThan) {
    return this.test({
      message,
      name: 'max',
      exclusive: true,
      params: {
        less
      },

      test(value) {
        return (0, _isAbsent.default)(value) || value < this.resolve(less);
      }

    });
  }

  moreThan(more, message = _locale.number.moreThan) {
    return this.test({
      message,
      name: 'min',
      exclusive: true,
      params: {
        more
      },

      test(value) {
        return (0, _isAbsent.default)(value) || value > this.resolve(more);
      }

    });
  }

  positive(msg = _locale.number.positive) {
    return this.moreThan(0, msg);
  }

  negative(msg = _locale.number.negative) {
    return this.lessThan(0, msg);
  }

  integer(message = _locale.number.integer) {
    return this.test({
      name: 'integer',
      message,
      test: val => (0, _isAbsent.default)(val) || Number.isInteger(val)
    });
  }

  truncate() {
    return this.transform(value => !(0, _isAbsent.default)(value) ? value | 0 : value);
  }

  round(method) {
    var _method;

    let avail = ['ceil', 'floor', 'round', 'trunc'];
    method = ((_method = method) == null ? void 0 : _method.toLowerCase()) || 'round'; // this exists for symemtry with the new Math.trunc

    if (method === 'trunc') return this.truncate();
    if (avail.indexOf(method.toLowerCase()) === -1) throw new TypeError('Only valid options for round() are: ' + avail.join(', '));
    return this.transform(value => !(0, _isAbsent.default)(value) ? Math[method](value) : value);
  }

}

exports.default = NumberSchema;
create.prototype = NumberSchema.prototype; //
// Number Interfaces
//