-- IndustrialTest
-- Copyright (C) 2023 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/>.

local S=minetest.get_translator("industrialtest")

industrialtest.Upgrade={}

function industrialtest.Upgrade.createDefinitionTable(self)
	local def={
		description=self.description,
		inventory_image=self.inventoryImage,
		groups={
			_industrialtest_machineUpgrade=1
		},
		_industrialtest_self=self
	}

	return def
end

function industrialtest.Upgrade.register(self)
	local def=self:createDefinitionTable()
	minetest.register_craftitem(self.name,def)
end

function industrialtest.Upgrade.apply(self,pos)
	-- dummy function
end

function industrialtest.Upgrade.remove(self,pos)
	-- dummy function
end

industrialtest.OverclockerUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.OverclockerUpgrade,{
	name="industrialtest:overclocker_upgrade",
	description=S("Overclocker Upgrade"),
	inventoryImage="industrialtest_overclocker_upgrade.png",
	_speed=1
})

function industrialtest.OverclockerUpgrade.apply(self,pos)
	local meta=minetest.get_meta(pos)
	local speed=industrialtest.api.getMachineSpeed(meta)
	meta:set_int("industrialtest.speed",math.min(4,speed+self._speed))
end

function industrialtest.OverclockerUpgrade.remove(self,pos)
	local meta=minetest.get_meta(pos)
	local speed=industrialtest.api.getMachineSpeed(meta)
	meta:set_int("industrialtest.speed",math.max(1,speed-self._speed))
end

industrialtest.OverclockerUpgrade:register()

minetest.register_craft({
	type="shaped",
	output="industrialtest:overclocker_upgrade",
	recipe={
		{"industrialtest:coolant_cell","industrialtest:coolant_cell","industrialtest:coolant_cell"},
		{"industrialtest:insulated_copper_cable","industrialtest:electronic_circuit","industrialtest:insulated_copper_cable"}
	}
})

industrialtest.TransformerUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.TransformerUpgrade,{
	name="industrialtest:transformer_upgrade",
	description=S("Transformer Upgrade"),
	inventoryImage="industrialtest_transformer_upgrade.png"
})

function industrialtest.TransformerUpgrade.apply(self,pos)
	local meta=minetest.get_meta(pos)
	local flows={
		industrialtest.api.lvPowerFlow,
		industrialtest.api.mvPowerFlow,
		industrialtest.api.hvPowerFlow,
		industrialtest.api.evPowerFlow,
		industrialtest.api.ivPowerFlow
	}
	local machineFlow=meta:get_int("industrialtest.powerFlow")
	local upgradedFlow=machineFlow
	for _,flow in ipairs(flows) do
		if flow>machineFlow then
			upgradedFlow=flow
			break
		end
	end
	meta:set_int("industrialtest.powerFlow",upgradedFlow)
	local networks=industrialtest.api.isAttachedToNetwork(meta)
	if networks then
		for _,network in ipairs(networks) do
			industrialtest.api.createNetworkMapForNode(network)
		end
	end
end

function industrialtest.TransformerUpgrade.remove(self,pos)
	local meta=minetest.get_meta(pos)
	local flows={
		industrialtest.api.lvPowerFlow,
		industrialtest.api.mvPowerFlow,
		industrialtest.api.hvPowerFlow,
		industrialtest.api.evPowerFlow,
		industrialtest.api.ivPowerFlow
	}
	local machineFlow=meta:get_int("industrialtest.powerFlow")
	local downgradedFlow=machineFlow
	for i=#flows,1,-1 do
		local flow=flows[i]
		if flow<machineFlow then
			downgradedFlow=flow
			break
		end
	end
	meta:set_int("industrialtest.powerFlow",downgradedFlow)
	local networks=industrialtest.api.isAttachedToNetwork(meta)
	if networks then
		for _,network in ipairs(networks) do
			industrialtest.api.createNetworkMapForNode(network)
		end
	end
end

industrialtest.TransformerUpgrade:register()

minetest.register_craft({
	type="shaped",
	output="industrialtest:transformer_upgrade",
	recipe={
		{industrialtest.elementKeys.glass,industrialtest.elementKeys.glass,industrialtest.elementKeys.glass},
		{"industrialtest:insulated_gold_cable","industrialtest:mv_transformer","industrialtest:insulated_gold_cable"},
		{industrialtest.elementKeys.glass,"industrialtest:electronic_circuit",industrialtest.elementKeys.glass}
	}
})

industrialtest.PowerStorageUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.PowerStorageUpgrade,{
	name="industrialtest:power_storage_upgrade",
	description=S("Power Storage Upgrade"),
	inventoryImage="industrialtest_power_storage_upgrade.png",
	_storage=10000
})

function industrialtest.PowerStorageUpgrade.apply(self,pos)
	local meta=minetest.get_meta(pos)
	meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")+self._storage)
	local node=minetest.get_node(pos)
	local def=minetest.registered_nodes[node.name]
	if def._industrialtest_self then
		def._industrialtest_self:updateFormspec(pos)
		if def._industrialtest_self.requestPower then
			def._industrialtest_self:requestPower(pos)
		end
	end
end

function industrialtest.PowerStorageUpgrade.remove(self,pos)
	local meta=minetest.get_meta(pos)
	meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")-self._storage)
	meta:set_int("industrialtest.powerAmount",math.min(meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerCapacity")))
	local node=minetest.get_node(pos)
	local def=minetest.registered_nodes[node.name]
	if def._industrialtest_self then
		def._industrialtest_self:updateFormspec(pos)
	end
end

industrialtest.PowerStorageUpgrade:register()

minetest.register_craft({
	type="shaped",
	output="industrialtest:power_storage_upgrade",
	recipe={
		{"group:wood","group:wood","group:wood"},
		{"industrialtest:insulated_copper_cable","industrialtest:re_battery","industrialtest:insulated_copper_cable"},
		{"group:wood","industrialtest:electronic_circuit","group:wood"}
	}
})
