local S = minetest.get_translator("lzr_doors")
local F = minetest.formspec_escape
local FS = function(...) return minetest.formspec_escape(S(...)) end

lzr_doors = {}

--[[ Basic doors for Lazarr!

The doors in Lazarr! are much simpler than in other games. This
is neccessary to ensure laser compatibility.

There are two types of doors: Locked doors play a sound when
interacting with them and exit doors that allow the player
to exit the level.

A major limitation is that doors cannot be opened or closed.

A door is basically just 2 panes (using `lzr_panes`),
with a top segment and a bottom one. Panes are useful because
they are laser-compatible.

Door segments are completely standalone, it is the reponsibility
of the map author to construct correct doors.

Trapdoors are like doors, except they only have one segment
and are intended to be placed horizontally.
]]

local on_punch_exit = function(pos, node, clicker)
	local state = lzr_gamestate.get_state()
	if state ~= lzr_gamestate.LEVEL then
		return
	end
	if not clicker and not clicker:is_player() then
		return
	end

	local message = S("Do you want to return to your ship?")

	local form = "formspec_version[7]size[8,2.5]"..
	"textarea[0.5,0.5;7,0.8;;;"..F(message).."]"..
	"button_exit[1.25,1.5;2,0.6;return_to_ship;"..FS("Yes").."]"..
	"set_focus[cancel]"..
	"button_exit[4.75,1.5;2,0.6;cancel;"..FS("No").."]"

	minetest.show_formspec(clicker:get_player_name(), "lzr_doors:leave_level", form)
end


local on_punch_locked = function(pos, node, clicker)
	local state = lzr_gamestate.get_state()
	if state ~= lzr_gamestate.LEVEL and state ~= lzr_gamestate.LEVEL_COMPLETE and state ~= lzr_gamestate.LEVEL_TEST then
		return
	end
	minetest.sound_play({name="lzr_doors_door_locked", gain=0.3}, {pos=pos}, true)
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
	local state = lzr_gamestate.get_state()
	if state ~= lzr_gamestate.LEVEL then
		return
	end
	if formname == "lzr_doors:leave_level" then
		if fields.return_to_ship then
			lzr_levels.leave_level()
		end
	end
end)

local help_exit = S("Allows to exit the level")
local help_locked = S("Cannot be opened")

local break_door_node = function(pos, node, signal)
	-- Break door when receiving ON or TOGGLE signal,
	-- but not for OFF signal
	if signal == "OFF" then
		return
	end
	local actions = {}
	-- Don't break door in the editor so the user doesn't have to
	-- annoyingly rebuild it again to repair the level
	if lzr_gamestate.get_state() == lzr_gamestate.EDITOR then
		return actions
	end
	local node = minetest.get_node(pos)
	local def = minetest.registered_nodes[node.name]
	if not def then
		minetest.log("error", "[lzr_doors] Tried to break door node at "..minetest.pos_to_string(pos).." but no known node found there")
		return
	end
	if def.sounds_break then
		table.insert(actions, {type="sound_play", sound=def.sounds_break})
	else
		table.insert(actions, {type="sound_play", sound={name="lzr_laser_crate_old_break", gain=0.35}})
	end
	local boxes = minetest.get_node_boxes("node_box", pos, node)
	local box = boxes[1]
	table.insert(actions, { type = "add_particlespawner", particlespawner = {
		amount = 24,
		time = 0.001,
		minpos = vector.add(pos, vector.new(box[1], box[2], box[3])),
		maxpos = vector.add(pos, vector.new(box[4], box[5], box[6])),
		minvel = vector.new(-0.5, -0.2, -0.5),
		maxvel = vector.new(0.5, 0.2, 0.5),
		minacc = vector.new(0, -lzr_globals.GRAVITY, 0),
		maxacc = vector.new(0, -lzr_globals.GRAVITY, 0),
		minsize = 0.8,
		maxsize = 0.8,
		minexptime = 0.5,
		maxexptime = 0.55,
		node = node,
	}})
	table.insert(actions, { type = "set_node", node = {name="air", param2=0}})
	table.insert(actions, { type = "remove_trigger" })
	return actions
end

lzr_doors.register_door = function(basename, modname, def)
	lzr_panes.register_pane(modname..":door_"..basename.."_exit_top", {
		description = S("@1 (top segment, exit)", def.base_description),
		_tt_help = help_exit,
		textures = def.textures_top,
		inventory_image = "("..def.image_top .. ")^lzr_doors_overlay_exit.png",
		wield_image = "("..def.image_top .. ")^lzr_doors_overlay_exit.png",
		sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_door_"..basename.."_exit_top",
		on_punch = on_punch_exit,
		groups = { door = 2, door_exit = 1 },
	})
	lzr_panes.register_pane(modname..":door_"..basename.."_exit_bottom", {
		description = S("@1 (bottom segment, exit)", def.base_description),
		_tt_help = help_exit,
		textures = def.textures_bottom,
		inventory_image = "("..def.image_bottom.. ")^lzr_doors_overlay_exit.png",
		wield_image = "("..def.image_bottom.. ")^lzr_doors_overlay_exit.png",
		sounds = lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_door_"..basename.."_exit_bottom",
		on_punch = on_punch_exit,
		groups = { door = 1, door_exit = 1 },
	})

	lzr_panes.register_pane(modname..":door_"..basename.."_locked_top", {
		description = S("@1 (top segment, locked)", def.base_description),
		_tt_help = help_locked,
		textures = def.textures_top,
		inventory_image = "("..def.image_top .. ")^lzr_doors_overlay_locked.png",
		wield_image = "("..def.image_top .. ")^lzr_doors_overlay_locked.png",
		sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_door_"..basename.."_locked_top",
		on_punch = on_punch_locked,
		groups = { door = 2, door_locked = 1, receiver = 1},

		_lzr_on_toggle = break_door_node,
		_lzr_call_always_on_toggle = true,
	})
	lzr_panes.register_pane(modname..":door_"..basename.."_locked_bottom", {
		description = S("@1 (bottom segment, locked)", def.base_description),
		_tt_help = help_locked,
		textures = def.textures_bottom,
		inventory_image = "("..def.image_bottom.. ")^lzr_doors_overlay_locked.png",
		wield_image = "("..def.image_bottom.. ")^lzr_doors_overlay_locked.png",
		sounds = lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_door_"..basename.."_locked_bottom",
		on_punch = on_punch_locked,
		groups = { door = 1, door_locked = 1, receiver = 1 },

		_lzr_on_toggle = break_door_node,
		_lzr_call_always_on_toggle = true,
	})
end

lzr_doors.register_trapdoor = function(basename, modname, def)
	lzr_panes.register_pane(modname..":trapdoor_"..basename.."_exit", {
		description = S("@1 (exit)", def.base_description),
		_tt_help = help_exit,
		textures = def.textures,
		inventory_image = "("..def.image .. ")^lzr_doors_overlay_exit.png",
		wield_image = "("..def.image .. ")^lzr_doors_overlay_exit.png",
		sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_trapdoor_"..basename.."_exit",
		on_punch = on_punch_exit,
		groups = { door = 3, door_exit = 1 },
		-- orient horizontally by default
		place_param2 = 4,
	})

	lzr_panes.register_pane(modname..":trapdoor_"..basename.."_locked", {
		description = S("@1 (locked)", def.base_description),
		_tt_help = help_locked,
		textures = def.textures,
		inventory_image = "("..def.image .. ")^lzr_doors_overlay_locked.png",
		wield_image = "("..def.image .. ")^lzr_doors_overlay_locked.png",
		sounds = def.sounds or lzr_sounds.node_sound_wood_defaults(),
		element_group = "laser_element_trapdoor_"..basename.."_locked",
		on_punch = on_punch_locked,
		groups = { door = 3, door_locked = 1, receiver = 1},
		-- orient horizontally by default
		place_param2 = 4,

		_lzr_on_toggle = break_door_node,
		_lzr_call_always_on_toggle = true,
	})
end


lzr_doors.register_door("wood_frame", "lzr_doors", {
	base_description = S("Wooden Frame Door"),
	textures_top = {"lzr_doors_door_wood_frame_top.png", "lzr_doors_door_wood_frame_sides.png", "lzr_doors_door_wood_frame_sides.png", "lzr_doors_door_wood_frame_top.png^[transformFX"},
	textures_bottom = {"lzr_doors_door_wood_frame_bottom.png", "lzr_doors_door_wood_frame_sides.png", "lzr_doors_door_wood_frame_sides.png", "lzr_doors_door_wood_frame_bottom.png^[transformFX"},
	image_top = "lzr_doors_door_wood_frame_top.png",
	image_bottom = "lzr_doors_door_wood_frame_bottom.png",
})

lzr_doors.register_trapdoor("wood", "lzr_doors", {
	base_description = S("Wooden Trapdoor"),
	textures = {"lzr_doors_trapdoor_wood.png", "lzr_doors_trapdoor_wood_sides.png", "lzr_doors_trapdoor_wood_sides.png", "lzr_doors_trapdoor_wood.png^[transformFX"},
	image = "lzr_doors_trapdoor_wood.png",
})

