import { fromCharCode } from './string.js';
import { floor } from './math.js';

/**
 * Fast Pseudo Random Number Generators.
 *
 * Given a seed a PRNG generates a sequence of numbers that cannot be reasonably predicted.
 * Two PRNGs must generate the same random sequence of numbers if  given the same seed.
 *
 * @module prng
 */


/**
 * Generates a single random bool.
 *
 * @param {PRNG} gen A random number generator.
 * @return {Boolean} A random boolean
 */
const bool = gen => (gen.next() >= 0.5);

/**
 * Generates a random integer with 53 bit resolution.
 *
 * @param {PRNG} gen A random number generator.
 * @param {Number} min The lower bound of the allowed return values (inclusive).
 * @param {Number} max The upper bound of the allowed return values (inclusive).
 * @return {Number} A random integer on [min, max]
 */
const int53 = (gen, min, max) => floor(gen.next() * (max + 1 - min) + min);

/**
 * Generates a random integer with 32 bit resolution.
 *
 * @param {PRNG} gen A random number generator.
 * @param {Number} min The lower bound of the allowed return values (inclusive).
 * @param {Number} max The upper bound of the allowed return values (inclusive).
 * @return {Number} A random integer on [min, max]
 */
const int32 = (gen, min, max) => floor(gen.next() * (max + 1 - min) + min);

/**
 * @deprecated
 * Optimized version of prng.int32. It has the same precision as prng.int32, but should be preferred when
 * openaring on smaller ranges.
 *
 * @param {PRNG} gen A random number generator.
 * @param {Number} min The lower bound of the allowed return values (inclusive).
 * @param {Number} max The upper bound of the allowed return values (inclusive). The max inclusive number is `binary.BITS31-1`
 * @return {Number} A random integer on [min, max]
 */
const int31 = (gen, min, max) => int32(gen, min, max);

/**
 * @param {PRNG} gen
 * @return {string} A single letter (a-z)
 */
const letter = gen => fromCharCode(int31(gen, 97, 122));

/**
 * @param {PRNG} gen
 * @param {number} [minLen=0]
 * @param {number} [maxLen=20]
 * @return {string} A random word (0-20 characters) without spaces consisting of letters (a-z)
 */
const word = (gen, minLen = 0, maxLen = 20) => {
  const len = int31(gen, minLen, maxLen);
  let str = '';
  for (let i = 0; i < len; i++) {
    str += letter(gen);
  }
  return str
};

/**
 * Returns one element of a given array.
 *
 * @param {PRNG} gen A random number generator.
 * @param {Array<T>} array Non empty Array of possible values.
 * @return {T} One of the values of the supplied Array.
 * @template T
 */
const oneOf = (gen, array) => array[int31(gen, 0, array.length - 1)];
/* c8 ignore stop */

export { bool, int31, int32, int53, letter, oneOf, word };
//# sourceMappingURL=prng.js.map
