local lib = starlit.mod.lib
local B = {}
starlit.mod.building = B

B.path = {}
-- this maps stage IDs to tables of the following form
--[[ {
	part = {
		['starlit_building:pipe'] = 'myMod:stage3';
	};
	tool = {
		['starlit:scredriver'] = 'myMod:otherThing_stage1';
		['starlit:saw'] = function(node, tool)
			minetest.replace_node(node, {name='myMod:stage1'})
			minetest.drop_item(node, 'starlit_building:pipe')
		end;
		['myMod:laserWrench'] = {
			allow = function(node, tool) ... end;
			handle = function(node, tool) ... end;
		};
	};
} ]]
-- it should only be written by special accessor functions!

B.stage = lib.registry.mk 'starlit_building:stage'
-- a stage consists of a list of pieces and maps from possible materials
-- / tool usages to succeeding stages in the build tree. note that all
-- used pieces must be defined before a stage is defined currently, due
-- to a lack of cross-registry dependency mechanisms. i will hopefully
-- improve vtlib to handle this condition eventually.
--[[
	starlit.mod.building.stage.link(id, {
		pieces = {
			'starlit_building:foundation';
			'starlit_building:insulation'; -- offset             ofsFac
			{'starlit_building:pipe',      vector.new(-.5, 0, 0), 0};--
			{'starlit_building:pipe',      vector.new(-.5, 0, 0), 1};
			'starlit_building:insulation';
			'starlit_building:panel';
		};
	})
]]

B.piece = lib.registry.mk 'starlit_building:piece'
-- a piece is used to produce stage definitions, by means of appending
-- nodeboxes with appropriate offsets. it also lists the recoverable
-- materials which can be obtained by destroying a stage containing
-- this piece using nano. part IDs should correspond with piece IDs
-- where possible
--[[
	starlit.mod.building.piece.link(id, {
		tex = 'myMod_part.png';
		height = 0.1; -- used for auto-offset
		fab = {
			element = {iron=10};
		};	
		shape = {
			type = "fixed";
			fixed = { ... };
		};
	})
]]

B.part = lib.registry.mk 'starlit_building:part'
-- a part is implemented as a special craftitem with the proper callbacks
-- to index the registries and place/replace noes by reference to the
-- build tree.
--[[
	starlit.mod.building.part.link(id, {
		name = ''; -- display name
		desc = ''; -- display desc
		img = ''; -- display image
	})
]]

B.stage.foreach('starlit:stageGen', {}, function(id, e)
	local box = {type = 'fixed', fixed = {}}
	local tex = {}
	local ofs = vector.new(0,0,0)
	for idx, p in ipairs(e.pieces) do
		local ho, pieceID, pos
		if type(p) == 'string' then
			pieceID, pos, ho = p, vector.zero(), 1.0
		else
			pieceID, pos, ho = pc[1],pc[2],pc[3]
		end
		local pc = B.piece.db[pieceID]
		pos = pos + ofs
		if ho ~= 0.0 then
			ofs = vector.offset(ofs, 0, pc.height)
		end
		local sh = lib.node.boxwarped(pc.shape, function(b)
			-- { -x, -y, -z;
			--   +x, +y, +z }
			b[1] = b[1] + ofs.x  b[4] = b[4] + ofs.x
			b[2] = b[2] + ofs.y  b[5] = b[5] + ofs.y
			b[3] = b[3] + ofs.z  b[6] = b[6] + ofs.z
		end)
		table.insert(box, sh)
		if type(pc.tex) == 'string' then
			table.insert(tex, pc.tex)
		else
			for i,t in ipairs(pc.tex) do
				table.insert(tex, t or '')
			end
		end
	end
	minetest.register_node(id, {
		description = 'Construction';
		drawtype = 'nodebox';
		paramtype  = 'light';
		paramtype2 = e.stateful or 'none';
		textures = tex;
		node_box = box;
		group = { stage = 1 };
		_starlit = {
			stage = id;
		};
	})
end)

function B.pathLink(from, kind, what, to)
	if not B.path[from] then
		B.path[from] = {part={}, tool={}}
	end
	local k = B.path[from][kind]
	assert(k[what] == nil)
	k[what] = to
end

function B.pathFind(from, kind, what)
	if not B.path[from] then return nil end
	return B.path[from][kind][what]
end

