local ____lualib = require("lualib_bundle")
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____ReadonlySet = require("types.ReadonlySet")
local ReadonlySet = ____ReadonlySet.ReadonlySet
local ____rng = require("functions.rng")
local isRNG = ____rng.isRNG
local newRNG = ____rng.newRNG
--- Returns a random float between 0 and 1. It is inclusive on the low end, but exclusive on the high
-- end. (This is because the `RNG.RandomFloat` method will never return a value of exactly 1.)
-- 
-- If you want to generate an unseeded number, you must explicitly pass `undefined` to the
-- `seedOrRNG` parameter.
-- 
-- @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
-- `RNG.Next` method will be called. If `undefined` is provided, it will default to
-- a random seed.
function ____exports.getRandom(self, seedOrRNG)
    local rng = isRNG(nil, seedOrRNG) and seedOrRNG or newRNG(nil, seedOrRNG)
    return rng:RandomFloat()
end
--- Returns a random float between min and max.
-- 
-- For example:
-- 
-- ```ts
-- const realNumberBetweenOneAndThree = getRandomFloat(1, 3, undefined);
-- ```
-- 
-- If you want to generate an unseeded number, you must explicitly pass `undefined` to the
-- `seedOrRNG` parameter.
-- 
-- @param min The lower bound for the random number (inclusive).
-- @param max The upper bound for the random number (exclusive).
-- @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
-- `RNG.Next` method will be called. If `undefined` is provided, it will default to
-- a random seed.
function ____exports.getRandomFloat(self, min, max, seedOrRNG)
    if min > max then
        local oldMin = min
        local oldMax = max
        min = oldMax
        max = oldMin
    end
    return min + ____exports.getRandom(nil, seedOrRNG) * (max - min)
end
--- Returns a random integer between min and max. It is inclusive on both ends.
-- 
-- For example:
-- 
-- ```ts
-- const oneTwoOrThree = getRandomInt(1, 3);
-- ```
-- 
-- If you want to generate an unseeded number, you must explicitly pass `undefined` to the
-- `seedOrRNG` parameter.
-- 
-- @param min The lower bound for the random number (inclusive).
-- @param max The upper bound for the random number (inclusive).
-- @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
-- `RNG.Next` method will be called. If `undefined` is provided, it will default to
-- a random seed.
-- @param exceptions Optional. An array of elements that will be skipped over when getting the
-- random integer. For example, a min of 1, a max of 4, and an exceptions array of
-- `[2]` would cause the function to return either 1, 3, or 4. Default is an empty
-- array.
function ____exports.getRandomInt(self, min, max, seedOrRNG, exceptions)
    if exceptions == nil then
        exceptions = {}
    end
    local rng = isRNG(nil, seedOrRNG) and seedOrRNG or newRNG(nil, seedOrRNG)
    min = math.ceil(min)
    max = math.floor(max)
    if min > max then
        local oldMin = min
        local oldMax = max
        min = oldMax
        max = oldMin
    end
    local exceptionsSet = __TS__New(ReadonlySet, exceptions)
    local randomInt
    repeat
        do
            randomInt = rng:RandomInt(max - min + 1) + min
        end
    until not exceptionsSet:has(randomInt)
    return randomInt
end
return ____exports
