local S = minetest.get_translator("lzr_laser")

local TEX_LASER, TEX_LASER_NOCENTER
local ALPHA_LASER
if lzr_globals.OPAQUE_LASERS then
	TEX_LASER = "lzr_laser_laser_opaque.png"
	TEX_LASER_NOCENTER = "lzr_laser_laser_nocenter_opaque.png"
	ALPHA_LASER = "clip"
else
	TEX_LASER = "lzr_laser_laser.png"
	TEX_LASER_NOCENTER = "lzr_laser_laser_nocenter.png"
	ALPHA_LASER = "blend"
end

-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P
local LASER_RADIUS = -1/16

-- Returns a nodebox for the given dirs table
local function dirs_to_nodebox(dirs)
	local boxes = {}
	local x = dirs[1] == 1
	local y = dirs[2] == 1
	local z = dirs[3] == 1

	-- True if 2 or more axes are used
	local multidir = (x and y) or (x and z) or (y and z)

	-- Center block
	if multidir and (x or y or z) then
		table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
	end

	-- Axes (X, Y, Z)
	if x then
		if not multidir then
			table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
		else
			table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
			table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
		end
	end
	if y then
		if not multidir then
			table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
		else
			table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
			table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
		end
	end
	if z then
		if not multidir then
			table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, 0.5 })
		else
			table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
			table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, 0.5 })
		end
	end
	return boxes
end

-- Register laser nodes
-- 7 nodes because (2^3)-1 (2 states for each of 3 axes, minus the state when there's no laser (=air))
for i=1, 7 do
	local dirstring = lzr_laser.dec2bin(i, 3)
	local dirs = lzr_laser.dirstring_to_dirs(dirstring)

	-- Check which textures to render.
	-- This looks complicated but serves a simple purpose: To prevent the laser cross-section
	-- to render, so there is a "clean" laser beam look.
	-- This works because lzr_laser_laser_nocenter.png.
	local axes = 0
	local axes_active = {x=false,y=false,z=false}
	for a=1,3 do
		if dirs[a] ~= 0 then
			axes = axes + 1
			if a == 1 then
				axes_active.x = true
			elseif a == 2 then
				axes_active.y = true
			elseif a == 3 then
				axes_active.z = true
			end
		end
	end
	local tex
	if axes == 1 then
		if axes_active.x then
			tex = { TEX_LASER, TEX_LASER, "blank.png", "blank.png", TEX_LASER }
		elseif axes_active.y then
			tex = { "blank.png", "blank.png", TEX_LASER }
		else
			tex = { TEX_LASER, TEX_LASER, TEX_LASER, TEX_LASER, "blank.png" }
		end
	elseif axes == 2 then
		if axes_active.x == false then
			tex = { TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER, TEX_LASER, TEX_LASER_NOCENTER }
		elseif axes_active.y == false then
			tex = { TEX_LASER, TEX_LASER, TEX_LASER_NOCENTER }
		else
			tex = { TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER }
		end

	elseif axes == 3 then
		tex = { TEX_LASER_NOCENTER }
	end

	-- Finally register the laser
	minetest.register_node("lzr_laser:laser_"..dirstring, {
		description = S("Laser (@1)", dirstring),
		paramtype = "light",
		light_source = lzr_globals.LASER_GLOW,
		drawtype = "nodebox",
		sunlight_propagates = true,
		walkable = false,
		use_texture_alpha = ALPHA_LASER,
		tiles = tex,
		pointable = false,
		buildable_to = true,
		node_box = {
			type = "fixed",
			fixed = dirs_to_nodebox(dirs),
		},
		groups = { laser = i, not_in_creative_inventory = 1 },
		drop = "",
	})
end
