
-- modified by dcc to work with hoppers
-- 
-- NOTE: input hopper goes on SIDE not top... to allow punching of barrel - placing hopper to point correctly 
--       may require screwdriver
-- 
-- output hopper goes below barrel
--
-- If testing - please note the abm's only fire every 30 seconds so it can take some time
--




compost = {}
compost.items = {}
compost.groups = {}

function compost.register_item(name)
	compost.items[name] = true
end

function compost.register_group(name)
	compost.groups[name] = true
end

function compost.can_compost(name)
	if compost.items[name] then
		return true
	else
		for k, i in pairs(minetest.registered_items[name].groups) do
			if i > 0 then
				if compost.groups[tostring(k)] then
					return true
				end
			end
		end

		return false
	end
end

-- grass
compost.register_item("default:grass_1")
compost.register_item("default:junglegrass")

-- leaves
compost.register_group("leaves")

-- dirt
compost.register_item("default:dirt")
compost.register_item("default:dirt_with_grass")

-- stick
compost.register_item("default:stick")

-- flowers
compost.register_item("flowers:geranium")
compost.register_item("flowers:tulip")
compost.register_item("flowers:rose")
compost.register_item("flowers:dandelion_yellow")
compost.register_item("flowers:dandelion_white")

-- food
compost.register_item("farming:bread")
compost.register_item("farming:wheat")

-- groups
compost.register_group("plant")
compost.register_group("flower")






-- dcc

local wood_barrel_src_on_construct = function(pos)
	local inv = minetest.get_meta(pos):get_inventory()
	inv:set_size("src", 1)
end



local wood_barrel_dst_on_construct = function(pos)
	local inv = minetest.get_meta(pos):get_inventory()
	inv:set_size("dst", 1)
	
	-- this is for wood barrel #3 which has 1 compost ready for taking
	--
	inv:set_stack('dst', 1, 'compost:compost')


	local meta = minetest.get_meta(pos)
	meta:set_string("formspec", 
		"size[8,5.3]" ..
		default.gui_bg ..
		default.gui_bg_img ..
		default.gui_slots ..
		"list[current_name;dst;3.5,0;1,1;]" ..
		"list[current_player;main;0,1.15;8,1;]" ..
		"list[current_player;main;0,2.38;8,3;8]" ..
		"listring[current_name;main]" ..
		"listring[current_player;main]" ..
		default.get_hotbar_bg(0,1.15)
	)
end





-- Only allow compostable items to be placed in input
-- allow_metadata_inventory_put is a pre-check prior to actual
-- putting...
--
local wood_barrel_allow_metadata_inventory_put = function(pos, listname, index, stack, player)
	--print ("[compost] wood_barrel_allow_metadata_inventory_put ", listname)

	if listname == "src" then
	
		local stackname = stack:get_name()
		--print ("[compost] wood_barrel_allow_metadata_inventory_put ", stackname )
		if compost.can_compost(stackname) then
		--print ("[compost] succeed wood_barrel_allow_metadata_inventory_put ", stackname)
			return 1 -- take only 1 item 
		end
	end
							
	return 0
end



-- actual put
--
local wood_barrel_on_metadata_inventory_put = function(pos, listname, index, stack, player)
	--print ("[compost] wood_barrel_on_metadata_inventory_put ")

	if listname == "src" then

		-- check again just in case
		--
		local stackname = stack:get_name()
	
		if compost.can_compost(stackname) then

			-- we received a compostable item - change to new node type
			--
			minetest.set_node(pos, {name = "compost:wood_barrel_1"})

			return 
		end

	end
end


-- Versions of callbacks for the inaccessible versions of the barrel
--

-- nope
local wood_barrelNope_allow_metadata_inventory_put = function(pos, listname, index, stack, player)
	--print ("[compost] wood_barrelNope_allow_metadata_inventory_put ")					
	return 0
end


-- nope
local wood_barrelNope_on_metadata_inventory_put = function(pos, listname, index, stack, player)
	--print ("[compost] wood_barrelNope_on_metadata_inventory_put ")
	return
end


-- nope
local wood_barrelNope_allow_metadata_inventory_take = function(pos, listname, index, stack, player)

	-- nope you can't take out here
	return 0
end

-- nope
local wood_barrelNope_on_metadata_inventory_take = function(pos, listname, index, stack, player)

 	return
end


-- Versions of callbacks for when compost is ready....

-- nope
local wood_barrel_allow_metadata_inventory_take = function(pos, listname, index, stack, player)

	-- YES you can take out here - we know it is 1 because we put it there with the constructor
	return 1
end

-- nope
local wood_barrel_on_metadata_inventory_take = function(pos, listname, index, stack, player)

	-- when emptied we revert to a plain wood barrel

	local node = minetest.get_node (pos)

	if node.name == "compost:wood_barrel_3" then
		minetest.set_node(pos, {name = "compost:wood_barrel"})
		return ItemStack("compost:compost")
	end

 	return
end






minetest.register_node("compost:wood_barrel", {
	description = "Wood Barrel",
	tiles = {"default_wood.png"},
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2},
			{-1/2, -1/2, -1/2, -3/8, 1/2, 1/2},
			{3/8, -1/2, -1/2, 1/2, 1/2, 1/2},
			{-1/2, -1/2, -1/2, 1/2, 1/2, -3/8},
			{-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}},
	},
	paramtype = "light",
	is_ground_content = false,
	groups = {choppy = 3},
	sounds =  default.node_sound_wood_defaults(),

	on_construct = wood_barrel_src_on_construct,	-- dcc
	allow_metadata_inventory_put = wood_barrel_allow_metadata_inventory_put, -- dcc
	on_metadata_inventory_put = wood_barrel_on_metadata_inventory_put, -- dcc
	allow_metadata_inventory_take = wood_barrelNope_allow_metadata_inventory_take, -- dcc
	on_metadata_inventory_take = wood_barrelNope_on_metadata_inventory_take, -- dcc

	on_punch = function(pos, node, puncher, pointed_thing)
		local wielded_item = puncher:get_wielded_item():get_name()
		if compost.can_compost(wielded_item) then
			minetest.set_node(pos, {name = "compost:wood_barrel_1"})
			local w = puncher:get_wielded_item()
			if not(minetest.setting_getbool("creative_mode")) then
				w:take_item(1)
				puncher:set_wielded_item(w)
			end
		end
	end
})






minetest.register_node("compost:wood_barrel_1", {
	description = "Wood Barrel with compost",
	tiles = {"default_wood.png^compost_compost_1.png", "default_wood.png"},
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2},
			{-1/2, -1/2, -1/2, -3/8, 1/2, 1/2},
			{3/8, -1/2, -1/2, 1/2, 1/2, 1/2},
			{-1/2, -1/2, -1/2, 1/2, 1/2, -3/8},
			{-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
			{-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}},
	},
	paramtype = "light",
	is_ground_content = false,

	allow_metadata_inventory_put = wood_barrelNope_allow_metadata_inventory_put, -- dcc
	on_metadata_inventory_put = wood_barrelNope_on_metadata_inventory_put, -- dcc
	allow_metadata_inventory_take = wood_barrelNope_allow_metadata_inventory_take, -- dcc
	on_metadata_inventory_take = wood_barrelNope_on_metadata_inventory_take, -- dcc


	groups = {choppy = 3},
	sounds =  default.node_sound_wood_defaults(),
})

minetest.register_node("compost:wood_barrel_2", {
	description = "Wood Barrel with compost",
	tiles = {"default_wood.png^compost_compost_2.png", "default_wood.png"},
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2},
			{-1/2, -1/2, -1/2, -3/8, 1/2, 1/2},
			{3/8, -1/2, -1/2, 1/2, 1/2, 1/2},
			{-1/2, -1/2, -1/2, 1/2, 1/2, -3/8},
			{-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
			{-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}},
	},
	paramtype = "light",
	is_ground_content = false,

	allow_metadata_inventory_put = wood_barrelNope_allow_metadata_inventory_put, -- dcc
	on_metadata_inventory_put = wood_barrelNope_on_metadata_inventory_put, -- dcc
	allow_metadata_inventory_take = wood_barrelNope_allow_metadata_inventory_take, -- dcc
	on_metadata_inventory_take = wood_barrelNope_on_metadata_inventory_take, -- dcc


	groups = {choppy = 3},
	sounds =  default.node_sound_wood_defaults(),
})

minetest.register_node("compost:wood_barrel_3", {
	description = "Wood Barrel",
	tiles = {"default_wood.png^compost_compost_3.png", "default_wood.png"},
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2},
			{-1/2, -1/2, -1/2, -3/8, 1/2, 1/2},
			{3/8, -1/2, -1/2, 1/2, 1/2, 1/2},
			{-1/2, -1/2, -1/2, 1/2, 1/2, -3/8},
			{-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
			{-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}},
	},
	paramtype = "light",
	is_ground_content = false,
	groups = {choppy = 3},


	on_construct = wood_barrel_dst_on_construct,	-- dcc
	allow_metadata_inventory_put = wood_barrelNope_allow_metadata_inventory_put, -- dcc
	on_metadata_inventory_put = wood_barrelNope_on_metadata_inventory_put, -- dcc
	allow_metadata_inventory_take = wood_barrel_allow_metadata_inventory_take, -- dcc
	on_metadata_inventory_take = wood_barrel_on_metadata_inventory_take, -- dcc

	sounds =  default.node_sound_wood_defaults(),
	on_punch = function(pos, node, player, pointed_thing)
		local p = {x = pos.x + math.random(0, 5)/5 - 0.5, y = pos.y+1, z = pos.z + math.random(0, 5)/5 - 0.5}
		minetest.add_item(p, {name = "compost:compost"})
		minetest.set_node(pos, {name = "compost:wood_barrel"})
	end
})

minetest.register_abm({
	nodenames = {"compost:wood_barrel_1"},
	interval = 30,
	chance = 5,
	action = function(pos, node, active_object_count, active_object_count_wider)
		minetest.set_node(pos, {name = "compost:wood_barrel_2"})
	end,
})

minetest.register_abm({
	nodenames = {"compost:wood_barrel_2"},
	interval = 30,
	chance = 3,
	action = function(pos, node, active_object_count, active_object_count_wider)
		minetest.set_node(pos, {name = "compost:wood_barrel_3"})
	end,
})

minetest.register_craft({
	output = "compost:wood_barrel",
	recipe = {
		{"default:wood", "", "default:wood"},
		{"default:wood", "", "default:wood"},
		{"default:wood", "stairs:slab_wood", "default:wood"}
	}
})

minetest.register_node("compost:compost", {
	description = "Compost",
	tiles = {"compost_compost.png"},
	groups = {crumbly = 3},
	sounds =  default.node_sound_dirt_defaults(),
})

minetest.register_node("compost:garden_soil", {
	description = "Garden Soil",
	tiles = {"compost_garden_soil.png"},
	groups = {crumbly = 3, soil=3, grassland = 1, wet = 1},
	sounds =  default.node_sound_dirt_defaults(),
})

minetest.register_craft({
	output = "compost:garden_soil",
	recipe = {
		{"compost:compost", "compost:compost"},
	}
})

if minetest.get_modpath ("tubelib") and tubelib then
	--print ("[compost] found tubelib")

	-- Thanks to @joe7575
	tubelib.register_node ("compost:wood_barrel",  {
			"compost:wood_barrel_1",
			"compost:wood_barrel_2",
			"compost:wood_barrel_3"
		}, {
			on_push_item = function  (pos, side, item, player_name)
				local node = minetest.get_node (pos)

				if node.name == "compost:wood_barrel" and compost.can_compost(item:get_name()) then
					minetest.set_node(pos, {name = "compost:wood_barrel_1"})
					return true
				else
					return false
				end
			end,

			on_unpull_item = function  (pos, side, item, player_name)
				minetest.set_node(pos, {name = "compost:wood_barrel_3"})
				return true
			end,

			on_pull_item = function  (pos, side, player_name)
				local node = minetest.get_node (pos)

				if node.name == "compost:wood_barrel_3" then
					minetest.set_node(pos, {name = "compost:wood_barrel"})
					return ItemStack("compost:compost")
				end

				return nil
			end,
	})
end



-- dcc
if minetest.get_modpath ("hopper") and hopper then
	--print ("[compost] found hopper")
	hopper:add_container({
		{"top", "compost:wood_barrel_3", "dst"}, -- take compost from above into hopper below
		{"side", "compost:wood_barrel", "src"}, -- insert compostable items below to be composted from hopper at side

	})
end








