-- IndustrialTest
-- Copyright (C) 2024 mrkubax10

-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.

-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.

-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

-- Iron Furnace
local def=table.copy(minetest.registered_nodes["industrialtest:iron_furnace"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

local override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(direction.y==1 and "fuel" or "src",stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(direction.y==1 and "fuel" or "src",stack)
		end,
		input_inventory="dst",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}
minetest.override_item("industrialtest:iron_furnace",override)
minetest.override_item("industrialtest:iron_furnace_active",override)

-- Generator
def=table.copy(minetest.registered_nodes["industrialtest:generator"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname=direction.y==1 and "fuel" or "charged"
			if listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname=direction.y==1 and "fuel" or "charged"
			if listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="charged",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:generator",override)
minetest.override_item("industrialtest:generator_active",override)

-- Geothermal Generator
def=table.copy(minetest.registered_nodes["industrialtest:geothermal_generator"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="leftover"
			elseif direction.y==-1 then
				listname="fluid"
			else
				listname="charged"
			end
			if listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="leftover"
			elseif direction.y==-1 then
				listname="fluid"
			else
				listname="charged"
			end
			if listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="leftover",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:geothermal_generator",override)
minetest.override_item("industrialtest:geothermal_generator_active",override)

-- Water Mill
override.groups=minetest.registered_nodes["industrialtest:water_mill"].groups
override.groups.tubedevice=1
override.groups.tubedevice_receiver=1

minetest.override_item("industrialtest:water_mill",override)

-- Wind Mill
def=table.copy(minetest.registered_nodes["industrialtest:wind_mill"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			if not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item("charged",stack)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			if not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item("charged",stack)
		end,
		input_inventory="charged",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:wind_mill",override)

-- Solar Panel
override.groups=minetest.registered_nodes["industrialtest:solar_panel"].groups
override.groups.tubedevice=1
override.groups.tubedevice_receiver=1
override.tube.connect_sides={
	left=1,
	right=1,
	back=1,
	front=1,
	bottom=1
}

minetest.override_item("industrialtest:solar_panel",override)
minetest.override_item("industrialtest:lv_solar_array",override)
minetest.override_item("industrialtest:mv_solar_array",override)
minetest.override_item("industrialtest:hv_solar_array",override)

-- Nuclear Reactor
def=table.copy(minetest.registered_nodes["industrialtest:nuclear_reactor"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname=direction.y==0 and "charged" or "fuel"
			local def=stack:get_definition()
			if (listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
				(listname=="fuel" and (not def.groups or not def.groups._industrialtest_placedInNuclearReactor)) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname=direction.y==0 and "charged" or "fuel"
			local def=stack:get_definition()
			if (listname=="charged" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
				(listname=="fuel" and (not def.groups or not def.groups._industrialtest_placedInNuclearReactor)) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="fuel",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:nuclear_reactor",override)
minetest.override_item("industrialtest:nuclear_reactor_active",override)

-- BatBox
def=table.copy(minetest.registered_nodes["industrialtest:batbox"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname=direction.y==1 and "discharged" or "charged"
			if not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname=direction.y==1 and "discharged" or "charged"
			if not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="charged",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:batbox",override)

-- CESU
override.groups=minetest.registered_nodes["industrialtest:cesu"].groups
override.groups.tubedevice=1
override.groups.tubedevice_receiver=1
minetest.override_item("industrialtest:cesu",override)

-- MFE
override.groups=minetest.registered_nodes["industrialtest:mfe"].groups
override.groups.tubedevice=1
override.groups.tubedevice_receiver=1
minetest.override_item("industrialtest:mfe",override)

-- MFSU
override.groups=minetest.registered_nodes["industrialtest:mfsu"].groups
override.groups.tubedevice=1
override.groups.tubedevice_receiver=1
minetest.override_item("industrialtest:mfsu",override)

-- Canning Machine
def=table.copy(minetest.registered_nodes["industrialtest:canning_machine"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="powerStorage"
			elseif direction.y==-1 then
				listname="fuel"
			else
				listname="target"
			end
			local def=stack:get_definition()
			if (listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
				(listname=="fuel" and (not def.groups or not def.groups._industrialtest_fuel)) or
				(listname=="target" and (not def.groups or not def.groups._industrialtest_fueled)) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="powerStorage"
			elseif direction.y==-1 then
				listname="fuel"
			else
				listname="target"
			end
			local def=stack:get_definition()
			if (listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
				(listname=="fuel" and (not def.groups or not def.groups._industrialtest_fuel)) or
				(listname=="target" and (not def.groups or not def.groups._industrialtest_fueled)) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="target",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:canning_machine",override)
minetest.override_item("industrialtest:canning_machine_active",override)

-- Rotary Macerator
def=table.copy(minetest.registered_nodes["industrialtest:rotary_macerator"])

def.groups.tubedevice=1
def.groups.tubedevice_receiver=1

override={
	groups=def.groups,
	tube={
		insert_object=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="powerStorage"
			elseif direction.y==-1 then
				listname="src"
			else
				listname="modifier"
			end
			local def=stack:get_definition()
			if listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return nil
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			local result=inv:add_item(listname,stack)
			minetest.get_node_timer(pos):start(industrialtest.updateDelay)
			return result
		end,
		can_insert=function(pos,node,stack,direction)
			local listname
			if direction.y==1 then
				listname="powerStorage"
			elseif direction.y==-1 then
				listname="src"
			else
				listname="modifier"
			end
			local def=stack:get_definition()
			if listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
				return false
			end
			local meta=minetest.get_meta(pos)
			local inv=meta:get_inventory()
			return inv:room_for_item(listname,stack)
		end,
		input_inventory="dst",
		connect_sides={
			left=1,
			right=1,
			back=1,
			bottom=1,
			top=1
		}
	},
	after_place_node=pipeworks.after_place,
	after_dig_node=pipeworks.after_dig,
	on_rotate=pipeworks.on_rotate
}

minetest.override_item("industrialtest:rotary_macerator",override)
minetest.override_item("industrialtest:rotary_macerator_active",override)

-- Simple electric item processors
for _,name in ipairs(industrialtest.internal.simpleElectricItemProcessors) do
	local def=table.copy(minetest.registered_nodes[name])
	def.groups.tubedevice=1
	def.groups.tubedevice_receiver=1

	local override={
		groups=def.groups,
		tube={
			insert_object=function(pos,node,stack,direction)
				local listname=direction.y==1 and "powerStorage" or "src"
				if listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
					return nil
				end
				local meta=minetest.get_meta(pos)
				local inv=meta:get_inventory()
				local result=inv:add_item(listname,stack)
				minetest.get_node_timer(pos):start(industrialtest.updateDelay)
				return result
			end,
			can_insert=function(pos,node,stack,direction)
				local listname=direction.y==1 and "powerStorage" or "src"
				if listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
					return false
				end
				local meta=minetest.get_meta(pos)
				local inv=meta:get_inventory()
				return inv:room_for_item(listname,stack)
			end,
			input_inventory="dst",
			connect_sides={
				left=1,
				right=1,
				back=1,
				bottom=1,
				top=1
			}
		},
		after_place_node=pipeworks.after_place,
		after_dig_node=pipeworks.after_dig,
		on_rotate=pipeworks.on_rotate
	}

	minetest.override_item(name,override)
	minetest.override_item(name.."_active",override)
end