--[[

	TechAge
	=======

	Copyright (C) 2019 Joachim Stolberg

	GPL v3
	See LICENSE.txt for more information
	
	Gravel Sieve, sieving gravel to find ores
	
]]--

-- for lazy programmers
local P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S

local get_random_gravel_ore = techage.gravelsieve_get_random_gravel_ore
local get_random_basalt_ore = techage.gravelsieve_get_random_basalt_ore

-- handle the sieve animation
local function swap_node(pos)
	local node = minetest.get_node(pos)
	local idx = string.byte(node.name, -1) - 48
	idx = (idx + 1) % 4
	minetest.swap_node(pos, {name = "techage:sieve"..idx, param2 = node.param2})
	return idx == 3  -- true if done
end

local function push_items(pos, items)
	local pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
	local node = minetest.get_node(pos1)
	minetest.add_item({x=pos.x, y=pos.y-0.4, z=pos.z}, items)
end

local function keep_running(pos, elapsed)
	local inv = M(pos):get_inventory()
	if swap_node(pos) then
		local src, dst
		
		if inv:contains_item("src", ItemStack("techage:basalt_gravel")) then
			dst, src = get_random_basalt_ore(), ItemStack("techage:basalt_gravel")
		elseif inv:contains_item("src", ItemStack("default:gravel")) then
			dst, src = get_random_gravel_ore(), ItemStack("default:gravel")
		elseif not inv:is_empty("src") then
			src = inv:get_stack("src", 1):take_item(1)
			dst = src
		else
			return false
		end
		push_items(pos, dst)
		inv:remove_item("src", src)
	end
	return not inv:is_empty("src")
end

local function on_construct(pos)
	local meta = minetest.get_meta(pos)
	meta:set_string("infotext", S("TA1 Gravel Sieve"))
	local inv = meta:get_inventory()
	inv:set_size('src', 1)
end

local function on_punch(pos, node, puncher, pointed_thing)
	local wielded_item = puncher:get_wielded_item():get_name()
	if wielded_item == "default:gravel" or wielded_item == "techage:basalt_gravel" then
		local inv = M(pos):get_inventory()
		local stack = ItemStack(wielded_item)
		if inv:room_for_item("src", stack) then
			inv:add_item("src", stack)
			minetest.swap_node(pos, {name = "techage:sieve0"})
			minetest.get_node_timer(pos):start(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
end

local tiles_data = {
	-- up, down, right, left, back, front
	"techage_sieve_gravel_ta1.png",
	"techage_sieve_gravel_ta1.png",
	"techage_sieve_sieve_ta1.png",
	"techage_sieve_sieve_ta1.png",
	"techage_sieve_sieve_ta1.png",
	"techage_sieve_sieve_ta1.png",
}

local nodebox_data = {
	{ -8/16, -3/16, -8/16,   8/16, 4/16, -6/16 },
	{ -8/16, -3/16,  6/16,   8/16, 4/16,  8/16 },
	{ -8/16, -3/16, -8/16,  -6/16, 4/16,  8/16 },
	{  6/16, -3/16, -8/16,   8/16, 4/16,  8/16 },
	
	{ -8/16, -8/16, -8/16,  -6/16, -3/16, -6/16 },
	{  6/16, -8/16, -8/16,   8/16, -3/16, -6/16 },
	{ -8/16, -8/16,  6/16,  -6/16, -3/16,  8/16 },
	{  6/16, -8/16,  6/16,   8/16, -3/16,  8/16 },
	
	{ -6/16, -2/16, -6/16,   6/16, 8/16,  6/16 },
}

for idx = 0,3 do
	nodebox_data[9][5] = (8 - 2*idx) / 16
	if idx == 3 then
		tiles_data[1] = "techage_sieve_top_ta1.png"
	end

	minetest.register_node("techage:sieve"..idx, {
		description =  S("TA1 Gravel Sieve"),
		tiles = tiles_data,
		drawtype = "nodebox",
		node_box = {
			type = "fixed",
			fixed = nodebox_data,
		},
		selection_box = {
			type = "fixed",
			fixed = { -8/16, -3/16, -8/16,   8/16, 4/16, 8/16 },
		},

		on_construct = idx == 3 and on_construct or nil, 
		on_punch = idx == 3 and on_punch or nil,
		on_timer = keep_running,

		paramtype = "light",
		sounds = default.node_sound_wood_defaults(),
		paramtype2 = "facedir",
		sunlight_propagates = true,
		is_ground_content = false,
		groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, not_in_creative_inventory = (idx == 3) and 0 or 1},
		drop = "techage:sieve3",
	})
end

techage.register_node({"techage:sieve0", "techage:sieve1", "techage:sieve2", "techage:sieve3"}, {
	on_push_item = function(pos, in_dir, stack)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()
		if inv:room_for_item("src", stack) then
			inv:add_item("src", stack)
			minetest.get_node_timer(pos):start(1)
			return true
		end
		return false
	end,
})	

minetest.register_node("techage:sieved_gravel", {
	description = S("Sieved Gravel"),
	tiles = {"default_gravel.png"},
	groups = {crumbly=2, falling_node=1, not_in_creative_inventory=1},
	sounds = default.node_sound_gravel_defaults(),
})

minetest.register_node("techage:compressed_gravel", {
	description = S("Compressed Gravel"),
	tiles = {"techage_compressed_gravel.png"},
	groups = {cracky=2, crumbly = 2},
	sounds = default.node_sound_gravel_defaults(),
})

minetest.register_craft({
	output = "techage:sieve",
	recipe = {
		{"group:wood", "",                   "group:wood"},
		{"group:wood", "techage:iron_ingot", "group:wood"},
		{"group:wood", "",                   "group:wood"},
	},
})

minetest.register_craft({
	output = "techage:compressed_gravel",
	recipe = {
		{"techage:sieved_gravel", "techage:sieved_gravel"},
		{"techage:sieved_gravel", "techage:sieved_gravel"},
	},
})

minetest.register_craft({
	type = "cooking",
	output = "default:cobble",
	recipe = "techage:compressed_gravel",
	cooktime = 10,
})

minetest.register_alias("techage:sieve", "techage:sieve3")
minetest.register_alias("techage:auto_sieve", "techage:auto_sieve3")

techage.register_entry_page("ta1", "sieve",
	S("TA1 Gravel Sieve"), 
	S("To sieve Gravel and Basalt Gravel to get ores. Punch the sieve with wielded gravel to start sieving. "..
		"Sieving can be automated by means of the TA1 Hopper. Gravel can be found in caves or "..
		"generated by means of a TA1 Hammer."), 
	"techage:sieve3")