-- LUALOCALS < ---------------------------------------------------------
local ipairs, klots, minetest, table, vector
    = ipairs, klots, minetest, table, vector
local table_concat
    = table.concat
-- LUALOCALS > ---------------------------------------------------------

local modname = minetest.get_current_modname()

local cached = {}

local fanfare = {-3, 2, 5, 9, 14}

local function chime_play(pos)
	local lv = klots.level_from_pos(pos)
	for _, player in ipairs(minetest.get_connected_players()) do
		if klots.level_from_pos(player:get_pos()) == lv then
			klots.music_suspend(player, 4)
			for i = 1, #fanfare do
				minetest.after(0.3 * i, function()
						klots.music_playnote(player, fanfare[i],
							0.5, 0.5, 0.5 + i * 0.05)
					end)
			end
		end
	end
end

local checkdirs = {
	{x = 0, y = -1, z = 0},
	{x = 0, y = 1, z = 0},
	{x = -1, y = 0, z = 0},
	{x = 1, y = 0, z = 0},
	{x = 0, y = 0, z = -1},
	{x = 0, y = 0, z = 1},
}

local vector_add = vector.add
local hash = minetest.hash_node_position

local function chime_check(pos)
	minetest.get_node_timer(pos):start(0.25)

	local list = {}
	for i = 1, #checkdirs do
		local p = vector_add(pos, checkdirs[i])
		local node = minetest.get_node_or_nil(p)
		if not node then return end
		list[i] = node.name
	end
	list = table_concat(list, "|")

	local key = hash(pos)
	local old = cached[key]
	if old == nil then
		cached[key] = list
		return
	end
	if old == list then return end

	minetest.remove_node(pos)
end

klots.register_terrain({
		name = "chime",
		drawtype = klots.editmode and "plantlike" or "airlike",
		tiles = klots.editmode and {modname .. "_chime.png"},
		paramtype = "light",
		sunlight_propagates = true,
		pointable = klots.editmode or false,
		walkable = false,
		buildable_to = not klots.editmode,
		description = "Puzzle Chime",
		groups = {auto_timer = 1},
		on_timer = (not klots.editmode) and chime_check or nil,
		on_destruct = (not klots.editmode) and chime_play or nil
	})
