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

local function fabFor(x)
	local def = ItemStack(x):get_definition()
	assert(def ~= nil, 'invalid item ID ' .. tostring(x))
	return (def._starlit and def._starlit.recover) or starlit.type.fab {}
end

B.stage.link('starlit_building:foundation', {
	tex = {
		'starlit-node-concrete.png';
	};
	begin = {
		part = {
			'starlit_building:concrete';
		};
	};
	build = {
		part = {
			['starlit_building:insulation'] = 'starlit_building:stage_foundation_insulation';
			['starlit_building:concrete'] = 'starlit_building:step_concrete';
			['starlit_building:heating_element'] = 'starlit_building:stage_floor_heater';
		};
	};
	recover = fabFor 'starlit_building:concrete';
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5,         -.5;
			 .5, -.5 + (2/16), .5;
		};
	};
})

B.stage.link('starlit_building:step_concrete', {
	tex = {
		'starlit-node-concrete.png';
	};
	build = {
		part = {
			['starlit_building:concrete'] = 'starlit_building:pillar_concrete';
		};
	};
	recover = fabFor 'starlit_building:concrete' * 2;
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5,         -.5;
			 .5, -.5 + (8/16), .5;
		};
	};
})

B.stage.link('starlit_building:pillar_concrete', {
	tex = {
		'starlit-node-concrete.png';
	};
	recover = fabFor 'starlit_building:concrete' * 3;
})

B.stage.link('starlit_building:stage_foundation_insulation', {
	tex = {
		'starlit-node-insulation-top.png';
		'starlit-node-concrete.png';
		'starlit-node-floor-panel-side.png';
	};
	recover = fabFor 'starlit_building:concrete'
	        + fabFor 'starlit_building:insulation';
	build = {
		part = {
			['starlit_building:panel'] = 'starlit_building:floor';
		};
		tool = {
			object = {
				speed = 2;
				drop = 'starlit_building:insulation';
				swap = 'starlit_building:foundation';
			};
		};
	};
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5,         -.5;
			 .5, -.5 + (12/16), .5;
		};
	};
})

B.stage.link('starlit_building:stage_floor_heater', {
	tex = {
		'starlit-node-recessed-heater.png';
		'starlit-node-concrete.png';
		'starlit-node-concrete.png^starlit-node-recessed-heater-side.png';
	};
	recover = fabFor 'starlit_building:concrete'
	        + fabFor 'starlit_building:heating_element';
	build = {
		part = {
			['starlit_building:panel'] = 'starlit_building:floor_heater';
		};
		tool = {
			object = {
				speed = 2;
				drop = 'starlit_building:heating_element';
				swap = 'starlit_building:foundation';
			};
		};
	};
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5,         -.5;
			 .5, -.5 + (12/16), .5;
		};
	};
})

B.stage.link('starlit_building:floor_heater', {
	tex = {
		'starlit-node-floor-panel-top.png^starlit-node-vent.png';
		'starlit-node-concrete.png';
		'starlit-node-floor-panel-side.png';
	};
	recover = fabFor 'starlit_building:concrete'
	        + fabFor 'starlit_building:heating_element'
	        + fabFor 'starlit_building:panel';
	build = {
		tool = {
			unscrew = {
				speed = 2;
				drop = 'starlit_building:panel';
				swap = 'starlit_building:stage_floor_heater';
			};
		};
	};
})

B.panelRun = lib.registry.mk 'starlit_building:panelRun'
B.panelRun.foreach('starlit_building:runGen', {}, function(id, run)
	local F = string.format
	assert(run.name, 'missing name for panelrun')
	local name = run.name
	local buildPart = ItemStack(run.buildPart):get_name()
	local plugItem = ItemStack(run.plugItem):get_name()
	local floorStageRaw = id .. '_floor_open'
	local floorStage = id .. '_floor'
	local floorStagePlug = id .. '_floor_plug'

	local wallStageRaw = id .. '_wall_open'
	local wallStage = id .. '_wall'
	local wallStagePlug = id .. '_wall_plug'

	local texRun  = run.run  or F('starlit-node-%s-run.png',  name)
	local texPlug = run.plug or F('starlit-node-%s-plug.png', name)

	local imgRun = lib.image(texRun)
	local imgPlug = lib.image(texPlug)

	local baseMat = fabFor(run.buildPart) + fabFor 'starlit_building:insulation'
	local floorMat = baseMat + fabFor 'starlit_building:concrete'
	local wallMat = baseMat + fabFor 'starlit_building:panel'

	------------------
	-- floor stages --
	------------------
	B.stage.link(floorStageRaw, {
		tex = {
			imgRun:blit(lib.image 'starlit-node-insulation-top.png'):render();
			'starlit-node-concrete.png';
			imgPlug:blit(lib.image 'starlit-node-floor-panel-side.png'):render();
		};
		recover = floorMat;
		build = {
			part = {
				['starlit_building:panel'] = floorStage;
			};
			tool = {
				object = {
					speed = 1;
					drop = run.buildPart;
					swap = floorStageRaw;
				};
			};
		};
		box = {
			type = 'fixed';
			fixed = {
				-.5, -.5,         -.5;
				 .5, -.5 + (12/16), .5;
			};
		};
	})

	local floorBasis = run.floorBasis or 'starlit_building:stage_foundation_insulation'
	B.pathLink(floorBasis, 'part', buildPart, floorStageRaw)

	mat = floorMat + fabFor 'starlit_building:panel';
	B.stage.link(floorStage, {
		tex = {
			'starlit-node-floor-panel-top.png';
			'starlit-node-concrete.png';
			imgPlug:blit(lib.image 'starlit-node-floor-panel-side.png'):render();
		};
		recover = floorMat + fabFor 'starlit_building:panel';
		build = {
			part = {
				[plugItem] = floorStagePlug;
			};
			tool = {
				unscrew = {
					speed = 1;
					drop = 'starlit_building:panel';
					swap = floorBasis;
				};
			};
		};
		groups = run.groups;
	})

	if run.plugGroups then
		B.stage.link(floorStagePlug, {
			tex = {
				imgPlug:blit(lib.image 'starlit-node-floor-panel-top.png'):render();
				'starlit-node-concrete.png';
				imgPlug:blit(lib.image 'starlit-node-floor-panel-side.png'):render();
			};
			recover = floorMat + fabFor(run.plugItem);
			build = {
				tool = {
					unscrew = {
						speed = 1;
						drop = run.plugItem;
						swap = floorStage;
					};
				};
			};
			groups = run.plugGroups;
		})
	end

	-----------------
	-- wall stages --
	-----------------
	local imgPanel = lib.image 'starlit-node-insulated-panels.png'
	B.stage.link(wallStageRaw, {
		tex = {
			imgPlug:blit(imgPanel):render();
			imgPlug:blit(imgPanel):render();

			imgPlug:blit(imgPanel:transform 'R270'):render();
			imgPlug:blit(imgPanel:transform 'R90'):render();

			imgRun:blit(lib.image 'starlit-node-insulation-top.png'):render();
			'starlit-node-wall-panel-side.png';
		};
		recover = wallMat;
		build = {
			part = {
				['starlit_building:panel'] = wallStage;
			};
		};
		groups = run.groups;
		paramtype2 = '4dir';
		box = {
			type = 'fixed';
			fixed = {
				-.5, -.5, -.5;
				0.5, 0.5, -.5 + (12/16);
			};
		};
	})

	local wallBasis = run.wallBasis or 'starlit_building:stage_wall_insulation'
	B.pathLink(wallBasis, 'part', buildPart, wallStageRaw)

	B.stage.link(wallStage, {
		tex = {
			imgPlug:blit(imgPanel):render();
			imgPlug:blit(imgPanel):render();

			imgPlug:blit(imgPanel:transform 'R270'):render();
			imgPlug:blit(imgPanel:transform 'R90'):render();

			'starlit-node-wall-panel-side.png';
			'starlit-node-wall-panel-side.png';
		};
		recover = wallMat + fabFor 'starlit_building:panel';
		build = {
			part = {
				[plugItem] = wallStagePlug;
			};
		};
		paramtype2 = '4dir';
		groups = run.groups;
	})

	if run.plugGroups then
		B.stage.link(wallStagePlug, {
			tex = {
				imgPlug:blit(imgPanel):render();
				imgPlug:blit(imgPanel):render();

				imgPlug:blit(imgPanel:transform 'R270'):render();
				imgPlug:blit(imgPanel:transform 'R90'):render();

				'starlit-node-wall-panel-side.png';
				imgPlug:blit(lib.image 'starlit-node-wall-panel-side.png'):render();
			};
			recover = wallMat + fabFor(plugItem);
			build = {
			};
			paramtype2 = '4dir';
			groups = run.plugGroups;
		})
	end
end)

B.stage.link('starlit_building:floor', {
	tex = {
		'starlit-node-floor-panel-top.png';
		'starlit-node-concrete.png';
		'starlit-node-floor-panel-side.png';
	};
	recover = fabFor 'starlit_building:concrete'
	        + fabFor 'starlit_building:insulation'
	        + fabFor 'starlit_building:panel';
	build = {
		tool = {
			unscrew = {
				speed = 2;
				drop = 'starlit_building:panel';
				swap = 'starlit_building:stage_foundation_insulation';
			};
		};
	};
})

B.stage.link('starlit_building:stage_wall_panel', {
	tex = {
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png^[transformR270';
		'starlit-node-insulated-panels.png^[transformR90';
		'starlit-node-wall-panel-side.png';
	};
	recover = fabFor 'starlit_building:panel';
	begin = {
		part = {'starlit_building:panel'};
	};
	build = {
		part = {
			['starlit_building:insulation'] = 'starlit_building:stage_wall_insulation';
		};
	};
	paramtype2 = '4dir';
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5, -.5;
			0.5, 0.5, -.5 + (2/16);
		};
	};
})

B.stage.link('starlit_building:stage_wall_insulation', {
	tex = {
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png^[transformR270';
		'starlit-node-insulated-panels.png^[transformR90';
		'starlit-node-insulation-top.png';
		'starlit-node-wall-panel-side.png';
	};
	recover = fabFor 'starlit_building:panel'
	        + fabFor 'starlit_building:insulation';
	build = {
		part = {
			['starlit_building:panel'] = 'starlit_building:wall';
		};
	};
	paramtype2 = '4dir';
	box = {
		type = 'fixed';
		fixed = {
			-.5, -.5, -.5;
			0.5, 0.5, -.5 + (12/16);
		};
	};
})

B.stage.link('starlit_building:wall', {
	tex = {
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png';
		'starlit-node-insulated-panels.png^[transformR270';
		'starlit-node-insulated-panels.png^[transformR90';
		'starlit-node-wall-panel-side.png';
		'starlit-node-wall-panel-side.png';
	};
	recover = (fabFor 'starlit_building:panel' * 2)
	        + fabFor 'starlit_building:insulation';
	build = {
	};
	paramtype2 = '4dir';
})


B.panelRun.link('starlit_building:conduit_power', {
	name = 'cable';
	buildPart = 'starlit_building:cable_electric';
	plugItem = 'starlit_building:electrode';
	groups = {
		conduit_power = 1;
		conduit_data = 1;
	};
	plugGroups = {
		conduit_power = 2;
		conduit_data = 2;
	};
})

B.panelRun.link('starlit_building:conduit_fluid', {
	name = 'pipe';
	buildPart = 'starlit_building:pipe';
	plugItem = 'starlit_building:pipe';
	groups = {
		conduit_fluid = 1;
	};
	plugGroups = {
		conduit_fluid = 2;
	};
})