lzr_gamestate = {}

-- List of game states
lzr_gamestate.INIT = 0			-- When the game is still initializing
lzr_gamestate.MENU = 1			-- When in the main menu
lzr_gamestate.LEVEL = 2			-- When playing a level
lzr_gamestate.LEVEL_COMPLETE = 3	-- When a level was won and waiting for the next level
lzr_gamestate.EDITOR = 4		-- When making a level in the level editor
lzr_gamestate.SHUTDOWN = 5		-- When game is shutting down (used to trigger exit events of other states)
lzr_gamestate.DEV = 6			-- For development (free building, no laser update, no protection)
lzr_gamestate.LEVEL_TEST = 7		-- When the game is testing the level solutions for validity

-- Always start at the INIT state
local current_state = lzr_gamestate.INIT
minetest.log("action", "[lzr_gamestate] Game state initialized to "..tostring(current_state))

-- Whether the game is currently loading
local loading = false

-- Number of seconds the game is in this game state
-- (floating point) while not loading.
-- Timer resets whenever a state is set (even if
-- setting to a state we're already in).
local time_in_state = 0

-- Registered callbacks
lzr_gamestate.registered_on_enter_states = {}
lzr_gamestate.registered_on_exit_states = {}

------------
-- API calls
------------

lzr_gamestate.set_state = function(new_state)
	local state_changed = current_state ~= new_state
	local old_state = current_state

	if state_changed then
		for _, callback in pairs(lzr_gamestate.registered_on_exit_states) do
			callback(old_state)
		end
		for _, callback in pairs(lzr_gamestate.registered_on_enter_states) do
			callback(new_state)
		end
	end

	time_in_state = 0
	current_state = new_state
	minetest.log("action", "[lzr_gamestate] Game state changed to "..tostring(current_state))
end

lzr_gamestate.get_state = function()
	return current_state
end

lzr_gamestate.set_loading = function(is_loading)
	loading = is_loading
	minetest.log("action", "[lzr_gamestate] Loading state set to "..tostring(loading))
end

lzr_gamestate.is_loading = function()
	return loading
end

lzr_gamestate.register_on_enter_state = function(callback)
	table.insert(lzr_gamestate.registered_on_enter_states, callback)
end

lzr_gamestate.register_on_exit_state = function(callback)
	table.insert(lzr_gamestate.registered_on_exit_states, callback)
end

lzr_gamestate.get_time_in_state = function()
	return time_in_state
end

------------------------------
-- Built-in state: shutdown --
------------------------------

minetest.register_on_shutdown(function()
	lzr_gamestate.set_state(lzr_gamestate.SHUTDOWN)
end)

-- For time_in_state

minetest.register_globalstep(function(dtime)
	if not loading then
		time_in_state = time_in_state + dtime
	end
end)
