local storage = minetest.get_mod_storage()

local day = storage:get_int("day")

function mob_spawning_director.reset_day_count()
	day = 0
	storage:set_int("day", 0)
end


local spawning_events = {}

function mob_spawning_director.register_spawning_event(evt)
	assert(type(evt.single_strength) == "number" and
		evt.single_strength > 0,
		"Error registering spawning event: invalid value for field 'single_strength'")
	assert(evt.spawn,
		"Error registering spawning event: Field 'spawn' not defined")
	assert(evt.get_spawn_position,
		"Error registering spawning event: Field 'get_spawn_position' not defined")
	table.insert(spawning_events, evt)
end


local function calculate_pressure(player)
	mobs = 0
	players = 0
	local pos = player:get_pos()
	local objs = minetest.get_objects_inside_radius(pos, 12)
	for i, obj in ipairs(objs)
	do
		if obj:is_player()
		then
			--less dangerous
			players = players + 1
		elseif obj:get_luaentity().is_monster
		then
			--more dangerous
			mobs = mobs + 1
		end
	end
	return mobs / (players + 1)
end

local target_pressure_cap = 100

local function calculate_target_pressure()
	local time = minetest.get_timeofday()
	--relax during day
	if time > 0.2 and time < 0.8
	then
		--return 0
	end
	--number between 0 and 1 that gets higher nearing the end of the night
	local nighttime = (time > 0.8 and time - 0.8 or time + 0.2) * 2.5
	
	return math.min(nighttime * 2 ^ day, target_pressure_cap)
end

local function spawn_monsters(player, strength)
	local event = spawning_events[math.random(#spawning_events)]
	local pos = event.get_spawn_position(player)
	if not pos
	then
		return
	end
	
	while(strength > 0)
	do
		event.spawn(pos)
		strength = strength - event.single_strength
	end
end

local function adjust_pressure()
	local target_pressure = calculate_target_pressure()
	
	local players = minetest.get_connected_players()
	
	for i, p in ipairs(players)
	do
		local actual_pressure = calculate_pressure(p)
		if actual_pressure < target_pressure
		then
			spawn_monsters(p, target_pressure - actual_pressure)
		end
	end
end

local should_advance_daytime = storage:get_int("should_advance_daytime") == 1
local function update_day_counter()
	local time = minetest.get_timeofday()
	if should_advance_daytime and time > 0.2
	then
		should_advance_daytime = false
		day = day + 1
		storage:set_int("day", day)
		storage:set_int("should_advance_daytime", 0)
	elseif time < 0.2 and not should_advance_daytime
	then
		should_advance_daytime = true
		storage:set_int("should_advance_daytime", 1)
	end
end

--[[
local time_since_update = 0
minetest.register_globalstep(function(dtime)
		time_since_update = time_since_update + dtime
		if time_since_update < 2
		then
			return
		end
		time_since_update = 0
		update_day_counter()
		adjust_pressure()
	end)
]]
