local NAME = minetest.get_current_modname()
local MAX_ENERGY = 300
local modifier = 10 -- Cooking cost modifier
local time_modifier = 1.5 -- Cooking time modifier

local formspec_no_energy = sparktech.add_inventory(6,1.5,
	"list[current_name;source;0,0;2,1;]" ..
	"list[current_name;product;7.5,0;2,1;]")

local formspec_energy = sparktech.add_inventory(6,1.5,
	"image[0,1.125;9.75,0.25;energy2.png]" ..
	"list[current_name;source;0,0;2,1;]" ..
	"list[current_name;product;7.5,0;2,1;]")

local function is_smeltable(items)
	if not items then return false end
	local cooked, _
	cooked, _ = minetest.get_craft_result(
	{method = "cooking", width = 1, items = items})
	return cooked.time ~= 0
end

local function is_item_allowed(pos, target, _, stack)
	if target ~= "source" or not sparktech.getoption(pos, "acceptInput") then return 0 end 
	
	if not is_smeltable({stack}) then
		return 0
	else
		return stack:get_count()
	end
end

local function is_item_allowed_move(pos, src, sidx, target, tidx, c, p)
	local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()
	local stack = inv:get_stack(src, sidx)
	return is_item_allowed(pos, target, tidx, stack, p)
end

local function ongetitem(pos)
	local meta = minetest.get_meta(pos)
	if not sparktech.getoption(pos, "enabled") then return end
	if meta:get_int("energy") < modifier then return end
	local timer = minetest.get_node_timer(pos)
	timer:start(1.0)
end

local function mytime(pos, elapsed)
	local meta = minetest.get_meta(pos)
	
	if not sparktech.getoption(pos, "enabled") then return end -- TODO: show in the gui somehow
	local energy = meta:get_int("energy")
	local inventory = meta:get_inventory()
	local source = inventory:get_list("source")
	local product = inventory:get_list("product")

	for item=1,2 do
		if energy >= modifier then
			local cooked
			local aftercooked
			local progress = meta:get_int("progress_" .. item)
			cooked, aftercooked = minetest.get_craft_result(
				{method = "cooking", width = 1, items = 
					{inventory:get_stack("source", item)}})
			if progress >= math.ceil(cooked.time * time_modifier) then
				if inventory:room_for_item("product", cooked.item) then
					inventory:add_item("product", cooked.item)
					inventory:set_stack("source", item, aftercooked.items[1])
					meta:set_int("progress_" .. item, 0)
				end
			else
				meta:set_int("progress_" .. item, progress + 1)
				energy = energy - modifier
			end
		end
	end

	-- TODO set no_energy formspec here if energy is lower than modifier
	-- and have energy wakeup set new online formspec
	meta:set_int("energy", energy)
	
	if energy > 1 then
		meta:set_string("formspec", formspec_energy)
	else
		meta:set_string("fomspec", formspec_no_energy)
	end

	local has_items = false
	for _, e in pairs(meta:get_inventory():get_list("source")) do
		has_items = has_items or not e:is_empty()
	end
	if has_items then
		minetest.get_node_timer(pos):start(1.0)
	end
	return
end

minetest.register_node( NAME .. ":furnace", {
	description = "Electric furnace",

	tiles = {
		NAME .. "_steel_sideplate.png",
		NAME .. "_steel_sideplate.png",
		NAME .. "_steel_sideplate.png",
		NAME .. "_steel_sideplate.png",
		NAME .. "_steel_backplate.png",
		NAME .. "_furnace_frontplate.png"
	},
	paramtype2 = "facedir",

	groups = {
		sparktech_techy = WRENCHABLE,
		sparktech_energy_type = ENERGY_CONSUMER,
		sparktech_net_trigger = TRUE,
		sparktech_energy_max = MAX_ENERGY,
		sparktech_energy_wakeup = 10
	},

	on_timer = mytime,

	on_construct = function(pos, placer)
	  local meta = minetest.get_meta(pos)
	  meta:set_string("formspec", formspec_no_energy)
	  local inventory = meta:get_inventory()
	  inventory:set_size('source',2)
	  inventory:set_size('product',2)
	end,

	allow_metadata_inventory_put = is_item_allowed,
	allow_metadata_inventory_move = is_item_allowed_move,
	allow_metadata_inventory_take = function(pos, listname, index, stack, player) 
		if listname ~= "product" then return stack:get_count() end
		if not sparktech.getoption(pos, "acceptRemoval") then return 0 end
		return stack:get_count()
	end,	
	on_metadata_inventory_put = ongetitem,
	_sparkoptionchanged = function(pos, name)
		if name == "enabled" then
			local timer = minetest.get_node_timer(pos)
			if sparktech.getoption(pos, name) then
				timer:start(1.0)
			else
				timer:stop()
			end
		end
	end,
	_sparkoption = {
		enabled = true,
		acceptInput = true,
		acceptRemoval = true
	},
	_sparkoutput = {
		inputItems = function(nodepos)
			local inventory = minetest.get_meta(nodepos):get_inventory()
			return inventory:get_list("source")
		end,
		outputItems = function(nodepos)
			local inventory = minetest.get_meta(nodepos):get_inventory()
			return inventory:get_list("product")
		end
	},
	_sparkoutputtype = {
		inputItems = "InventoryList",
		outputItems = "InventoryList"
	}
})

minetest.register_craft({
	output = NAME .. ":furnace",
	recipe = {
		{ "orioncraft:iron_bar", "", "orioncraft:iron_bar" },
		{ "orioncraft:iron_bar", "orioncraft:copper_bar", "orioncraft:iron_bar" },
		{ "orioncraft:iron_bar", "sparkcore:cable", "orioncraft:iron_bar" }
	}
})
