-- LUALOCALS < ---------------------------------------------------------
local ItemStack, get_mod_api, minetest, pairs, piredo_map,
      piredo_player, piredo_schems, string
    = ItemStack, get_mod_api, minetest, pairs, piredo_map,
      piredo_player, piredo_schems, string
local string_format, string_gsub
    = string.format, string.gsub
-- LUALOCALS > ---------------------------------------------------------

local api = get_mod_api()

local useitem = api.ratelimit(function(stack, user, pointed)
		piredo_player.player_hand_movement(user)
		if not pointed.under then return end

		local node = minetest.get_node_or_nil(pointed.under)

		local invoked = api.tryinvoke(pointed, node, stack, user, "on_whack_")
		if invoked ~= false then return invoked end
		invoked = api.tryinvoke(pointed, node, stack, user, "on_apply_")
		if invoked ~= false then return invoked end

		api.ratelimitskip()

		local def = node and minetest.registered_nodes[node.name]
		local cb = def and def.on_punch
		if cb then
			minetest.log("action", string_format("player punches %q with %q at %s",
					node.name, stack:get_name(), minetest.pos_to_string(pointed.under)))
			cb(pointed.under, node, user, pointed)
			return
		end

		minetest.log("action", string_format("player swings %q at %q at %s",
				stack:get_name(), node.name, minetest.pos_to_string(pointed.under)))
	end)

local pickup = api.ratelimit(function(pos, node, player)
		-- Cannot pickup "through" invisible barriers
		-- (fix lake crown maze puzzle)
		if api.checkbarriers(pos, player) then
			api.ratelimitskip()
			return
		end

		local room = piredo_map.get_current_room()
		local schem = room and piredo_schems[room]
		if not (schem and not schem.disallow_changes) then
			api.ratelimitskip()
			api.digsound(pos, node)
			return
		end

		local inv = player:get_inventory()
		local stack = ItemStack(node.name)
		stack:get_meta():from_table(minetest.get_meta(pos):to_table())
		if not inv:room_for_item("main", stack) then
			api.ratelimitskip()
			return
		end
		player:get_inventory():add_item("main", stack)
		minetest.remove_node(pos)
		api.pickupeffect(pos, node)
	end)

for name, olddef in pairs(minetest.registered_items) do
	if olddef.groups and olddef.groups.collectable
	and olddef.groups.collectable > 0 then
		local basename = string_gsub(name, ".*:", "")
		local itemkey = string_gsub(string_gsub(basename, ".*__", ""),
			"_?block", "")
		local groups = {}
		for k, v in pairs(olddef.groups or {}) do groups[k] = v end
		groups[itemkey] = 1
		minetest.override_item(name, {
				on_punch = pickup,
				on_drop = function() end,
				on_use = olddef.on_use or useitem,
				on_place = api.placement,
				after_place_node = function(pos, _, stack)
					minetest.get_meta(pos):from_table(stack:get_meta():to_table())
				end,
				node_placement_prediction = "air",
				walkable = olddef.drawtype == "nodebox" or false,
				pointable = true,
				paramtype = "light",
				groups = groups
			})
	end
end
