util = {}

local modpath = minetest.get_modpath("util") .. "/"
dofile(modpath .. "overrides/table.lua")
dofile(modpath .. "overrides/string.lua")
dofile(modpath .. "tests.lua")

--[[ Mapgen ]] --

function util.node_or_ignore(node)
	if type(node) == "string" then
		return {name = node}
	elseif type(node) == "table" then
		return node
	else
		return {name = "ignore"}
	end
end

function util.every_n_mapblocks(n)
	return function(value)
		return (value / 16) % n == 0
	end
end

function util.leave_behind(pos, oldnode, oldmetadata, digger)
	if oldmetadata.fields.leave_behind then
		minetest.set_node(pos, {name = oldmetadata.fields.leave_behind})
	end
end

function util.fill_vmanip_area(data, va, p1, p2, c_id)
	for i in va:iterp(p1, p2) do
		data[i] = c_id
	end
	return data
end

--[[ Noise ]] --

-- Returns The Decimal Places Of A Random Number
function util.tail_perlin(Perlin, x, y, z)
	local num = Perlin:get_3d({x = x, y = y, z = z})
	return num - math.floor(num)
end

-- Returns A Random Number From 1 to limit
function util.bound_perlin(Perlin, limit, x, y, z)
	local num = util.tail_perlin(Perlin, x, y, z)
	return math.floor((num * (limit - 1)) + 0.5) + 1
end

--[[ Misc ]] --

-- Returns A List Of Nodestrings Filtered By Group
function util.get_nodes_by_groups(groups)
	groups = groups or {}
	local results = {}

	for node_name, _ in pairs(minetest.registered_nodes) do
		local should_include = true
		for group, value in pairs(groups) do
			if minetest.get_item_group(node_name, group) ~= value then
				should_include = false
			end
		end
		if should_include then
			table.insert(results, node_name)
		end
	end

	return results
end

do
	local registered_on_tod = {}

	function util.register_on_tod(tod, func)
		if (type(tod) == "number") and (type(func) == "function") then
			registered_on_tod[tod] = registered_on_tod[tod] or {}
			table.insert(registered_on_tod[tod], func)
		end
	end

	local old_tod = 0
	local timer = 0
	minetest.register_globalstep(function(dtime)
		timer = timer + dtime
		if timer >= 1 then
			local tod = math.floor(minetest.get_timeofday() * 24)
			if (tod ~= old_tod) and registered_on_tod[tod] then
				for _, v in ipairs(registered_on_tod[tod]) do
					v()
				end
				old_tod = tod
			end
			timer = 0
		end
	end)
end
