
---@class OptionList
ExtraClasses.OptionList = {
	total = 0.0,
	last_index = 1,
	last_value = nil,
	random = function() return math.random() end,
	type = "OptionList",
}

---Chooses a random option from the list and returns it.
---@param self OptionList
---@return any
ExtraClasses.OptionList.get_random = function(self)
	local r = self.random() * self.total
	for i, entry in ipairs(self) do
		r = r - entry[2]
		if r <= 0 then
			self.last_index = i
			self.last_value = entry[1]
			return self.last_value
		end
	end
end

---Gets the next option in the list sequentially without randomness. Can loop indefinitely.
---@param self OptionList
---@return any
ExtraClasses.OptionList.next = function(self)
	self.last_index = (self.last_index % #self) + 1
	return self[self.last_index][1]
end

--[[
	
	-- Gives a table which allows you to get a random `this:get_random()`.
	ExtraClasses.OptionList.new({
		-- index 1: option to return
		-- index 2: proportion of the probability
		{option_one, 4}, --> 4/5 chance
		{option_two, 1} --> 1/5 chance
	}, function() return math.random() end)

	-- Methods:
	return this:get_random() --> give a random option
	return this:next() --> give next sequential option from the last WITHOUT randomness
--]]
---@param input table
---@param rng function|nil
---@return OptionList
function ExtraClasses.OptionList.new(input, rng)
	input = table.copy(input or {})
	input.total = 0
	if rng then input.random = rng end
	for i, entry in ipairs(input) do
		input.total = input.total + (entry[2] or 0)
	end
	return setmetatable(input, ExtraClasses.OptionList)
end

rawset(ExtraClasses.OptionList, "__index", ExtraClasses.OptionList)
rawset(ExtraClasses.OptionList, "__call", function(self, ...)
	return ExtraClasses.OptionList.new(...)
end)
