local mod_name = core.get_current_modname()
local mod_path = core.get_modpath(mod_name)
local S = core.get_translator(mod_name)

local has_aom_tcraft = (core.get_modpath("aom_tcraft") ~= nil)

aom_wood = {}

local function ends_in(input, ending)
	if string.sub(input, string.len(input) - (string.len(ending)-1), string.len(input)) == ending then
		return true
	end
	return false
end

local function test_for_break_me(pos, cause, user, data)
	-- if not can_tree_fell then return end
	if cause == "treefeller" and data and data.start_pos then
		local cpos = vector.new(pos.x, data.start_pos.y, pos.z)
		if aom_util.math.dist2(cpos, data.start_pos) < (6.4)^2 then
			local node = core.get_node(pos)
			local drops = core.get_node_drops(node, data.tool_name)
			core.set_node(pos, {name="air"})
			-- core.fix_light(pos, pos)
			for i, stack in pairs(drops) do
				local p = vector.offset(pos,
					(math.random()*2-1) * 0.5,
					(math.random()*2-1) * 0.5,
					(math.random()*2-1) * 0.5
				)
				core.add_item(p, stack)
			end
			if ends_in(node.name, "_mesh_leaves") then
				local n = core.find_node_near(pos, 3, {"group:mesh_leaves"})
				if n then
					core.after(2, test_for_break_me, n, cause, user, data)
				end
				return end
			return data
		end
	elseif cause == "treefeller_start" and core.is_player(user) then
		local wieldstack = ItemStack(user:get_wielded_item())
		local wieldname = wieldstack:get_name()
		if core.get_item_group(wieldname, "treefeller") > 0 then
			node_updates.cause_adjacent_update(pos, "treefeller", user, {
				start_pos = pos,
				tool_name = wieldname,
				_count = 30,
				_delay = 0.2,
			})
			return
		end
	end
end


local log_fuel = 10

local planks_per_log = 4
function aom_wood.register_planks(sname, name, tiles)
	local node_name = string.lower(name)
	core.register_node('aom_wood:' .. node_name .. '_planks', {
		-- TL: @1 is type of wood ("Oak")
		description = S("@1 Planks", sname),
		groups = {
			full_solid = 1, oddly_breakable_by_hand = 1, choppy = 1, solid = 1, suffocates = 2,
			wood = 1, material_wood_planks = 1, planks = 1, flammable = 1, fuel = log_fuel/2 },
		tiles = tiles,
		sounds = aom_sounds.default_wood(),
	})
	core.register_craft({
		output = 'aom_wood:' .. node_name .. '_planks ' .. planks_per_log,
		recipe = {
			{'aom_wood:' .. node_name .. '_log'},
		},
	})
end


local plank_box = {
	-8/16,   -8/16, -8/16,
	8/16,   -4/16,  8/16
}
-- local plank_box = {
--   -0.5, -0.5,  4/16,
--   0.5,   0.5,  8/16,
-- }
local plank_per_planks = 2
function aom_wood.register_plank(sname, name, tiles)
	local node_name = string.lower(name)
	core.register_node('aom_wood:' .. node_name .. '_plank', {
		-- TL: @1 is type of wood ("Oak")
		description = S("Single @1 Plank", name),
		groups = {
			oddly_breakable_by_hand = 1, choppy = 1, solid = 1, wood = 1, shape = 1, material_wood_plank = 1,
			plank = 1, flammable = 1, fuel = 1 },
		drawtype = "nodebox",
		paramtype = "light",
		sunlight_propagates = false,
		paramtype2 = "facedir",
		node_box = {
			type = "fixed",
			fixed = plank_box,
		},
		tiles = tiles,
		sounds = aom_sounds.default_wood(),
		on_place = aom_util.rotate_and_place,
	})
	core.register_craft({
		output = 'aom_wood:' .. node_name .. '_plank ' .. plank_per_planks,
		recipe = {
			{'aom_wood:' .. node_name .. '_planks'},
		},
	})
end


function aom_wood.register_log(sname, name, tiles)
	local node_name = string.lower(name)
	core.register_node('aom_wood:' .. node_name .. '_log', {
		-- TL: @1 is type of wood ("Oak")
		description = S("@1 Log", sname),
		groups = {
			full_solid = 1, nature = 1, oddly_breakable_by_hand = 2, choppy = 1, solid = 1, material_wood_log = 1,
			suffocates = 2, wood = 1, ["item_"..name.."_log"] = 1, wood_log = 1, flammable = 1, fuel = log_fuel },
		tiles = tiles,
		sounds = aom_sounds.default_wood_log(),
		paramtype2 = "facedir",
		on_place = aom_util.rotate_and_place,
		_on_node_update = test_for_break_me,
		after_dig_node = function(pos, oldnode, oldmetadata, digger)
			test_for_break_me(pos, "treefeller_start", digger)
		end,
	})
	aom_util.register_slab( 'aom_wood:' .. node_name .. '_log')
	aom_util.register_post( 'aom_wood:' .. node_name .. '_log')
end

local function leaf_decay(pos, require_adjacent)
	local node = core.get_node(pos)
	if core.get_item_group(node.name, "leaf_decay") == 0 then return end

	local nt = core.get_node_timer(pos)
	if nt:is_started() then return
	else nt:stop() end

	aom_util.did_abm("leaf decay")

	if require_adjacent ~= nil then
		local near = core.find_node_near(pos, 1, require_adjacent, false)
		if not near then
			core.dig_node(pos)
			return
		end
	end

	local n = core.find_node_near(pos, 3, {"group:wood_log"})
	if n then
		return
	end

	local MAP_BLOCKSIZE = vector.new(16, 16, 16)
	local p1 = vector.floor(vector.divide(pos - (MAP_BLOCKSIZE * 0.5), MAP_BLOCKSIZE)) * MAP_BLOCKSIZE
	for i, o in ipairs({
		vector.new(1, 0, 0),
		vector.new(0, 0, 1),
		vector.new(1, 0, 1),
		vector.new(0, 1, 0),
		vector.new(1, 1, 0),
		vector.new(0, 1, 1),
		vector.new(1, 1, 1),
	}) do
		if not core.get_node_or_nil(p1 + (o * MAP_BLOCKSIZE)) then
			return
		end
	end

	n = core.find_node_near(pos, 3, {"group:leaf_decay"})
	nt = n and core.get_node_timer(n)
	if n and nt and not nt:is_started() then
		core.after(math.random() + 0.1, leaf_decay, n, require_adjacent)
	end

	core.dig_node(pos)
	return
end

function aom_wood.leaf_decay_on_timer(pos, elapsed)
	return leaf_decay(pos, {"group:solid"})
end

function aom_wood.mesh_leaves_on_update(pos, cause, user, data)
	local nt = core.get_node_timer(pos)
	if nt:is_started() then return end
	nt:start(math.random(1,2))
	if cause == "treefeller" then
		return leaf_decay(pos, {"group:solid_leaves"})
	else
		return leaf_decay(pos)
	end
end

function aom_wood.leaves_on_update(pos, cause, user, data)
	local nt = core.get_node_timer(pos)
	if nt:is_started() then return end
	nt:start(math.random(1,2))
	if cause == "treefeller" then
		return test_for_break_me(pos, cause, user, data)
	else
		return leaf_decay(pos, {"group:solid"})
	end
end

function aom_wood.register_leaves(sname, name, tiles, tiles_opaque)
	local node_name = string.lower(name)
	local drop = {
		max_items = 1,
		items = {
			{
				items = {'aom_trees:' .. node_name .. '_sapling'},
				rarity = 35,
			},
			{
				items = {'aom_items:stick'},
				rarity = 30,
			},
		},
	}
	core.register_node('aom_wood:' .. node_name .. '_solid_leaves', {
		-- TL: @1 is type of wood ("Oak")
		description = S("@1 Leaves", sname),
		-- drawtype = "allfaces_optional",
		waving = 1,
		tiles = tiles_opaque,
		groups = {
			oddly_breakable_by_hand = 1, nature = 1, snappy = 1, solid = 1, suffocates = 0,
			leaves = 1, solid_leaves = 1, leaf_decay = 1, flammable = 1, material_leaves = 1, },
		is_ground_content = false,
		drop = drop,
		sounds = aom_sounds.default_plant(), -- #TODO add leaf sounds
		_on_node_update = aom_wood.leaves_on_update,
		on_timer = aom_wood.leaf_decay_on_timer,
	})
	core.register_node('aom_wood:' .. node_name .. '_mesh_leaves', {
		-- TL: @1 is type of wood ("Oak")
		description = S("Sparse @1 Leaves", sname),
		drawtype = "mesh",
		mesh = "aom_meshleaves_3poly_bend.obj",
		use_texture_alpha = "clip",
		walkable = false,
		waving = 1,
		tiles = tiles,
		paramtype = "light",
		paramtype2 = "degrotate",
		groups = {
			oddly_breakable_by_hand = 1, nature = 1, snappy = 1, suffocates = 0,
			leaves = 1, mesh_leaves = 1, leaf_decay = 1, flammable = 1, material_leaves = 1, },
		is_ground_content = false,
		drop = drop,
		sounds = aom_sounds.default_plant(), -- #TODO add leaf sounds
		_on_node_update = aom_wood.mesh_leaves_on_update,
		on_timer = aom_wood.leaf_decay_on_timer,
		on_construct =function(pos)
				core.swap_node(pos, {
						name = 'aom_wood:' .. node_name .. '_mesh_leaves',
						param2 = math.random(0, 239)
				})
		end,
	})
	if has_aom_tcraft then
		aom_tcraft.register_craft({
			output = "aom_wood:" .. node_name .. "_solid_leaves 40",
			extra_items = {
				"aom_items:wooden_cup",
			},
			items = {
				["aom_items:wooden_cup_water"] = 1,
				["aom_trees:" .. node_name .. "_sapling"] = 1,
				["aom_items:plant_fibre"] = 4,
			},
				tags = {
					"decor"
				}
		})
		aom_tcraft.register_craft({
			output = "aom_wood:" .. node_name .. "_mesh_leaves 20",
			extra_items = {
				"aom_items:wooden_cup",
			},
			items = {
				["aom_items:wooden_cup_water"] = 1,
				["aom_trees:" .. node_name .. "_sapling"] = 1,
				["aom_items:plant_fibre"] = 4,
			},
				tags = {
					"decor"
				}
		})
	end
end




-- deprecated, for compat only
function aom_wood.register_leaves_old(sname, name, tiles, tiles_simple)
	local node_name = string.lower(name)
	core.register_node('aom_wood:' .. node_name .. '_leaves', {
		-- TL: @1 is type of wood ("Oak")
		description = S("@1 Leaves", sname),
		drawtype = "allfaces_optional",
		waving = 1,
		tiles = tiles,
		special_tiles = tiles_simple,
		paramtype = "light",
		groups = {
			oddly_breakable_by_hand = 1, nature = 1, snappy = 1, solid = 1, suffocates = 0, material_leaves = 1,
			leaves = 1, leaf_decay = 1, flammable = 1, not_in_creative_inventory = 1, },
		is_ground_content = false,
		drop = {
			max_items = 1,
			items = {
				{
					items = {'aom_trees:' .. node_name .. '_sapling'},
					rarity = 35,
				},
				{
					items = {'aom_items:stick'},
					rarity = 30,
				},
			},
		},
		sounds = aom_sounds.default_plant(), -- #TODO add leaf sounds
		_on_node_update = aom_wood.leaves_on_update,
		on_timer = aom_wood.leaf_decay_on_timer,
})
end

core.register_abm({
	nodenames = {"group:leaf_decay"},
	neighbors = {'air'},
	interval = 10.0,
	chance = 100,
	action = function(pos, node, active_object_count, active_object_count_wider)
		leaf_decay(pos)
	end
})

aom_wood.register_log(S("Oak"), "Oak", {'aom_wood_oak_log_top.png', 'aom_wood_oak_log_top.png', 'aom_wood_oak_log_side.png'})
aom_wood.register_leaves_old(S("Oak"), "Oak", {'aom_wood_oak_leaves.png'}, {'aom_wood_oak_leaves.png'}) -- deprecated, for compat only
aom_wood.register_leaves(S("Oak"), "Oak", {'aom_wood_oak_leaves.png'}, {'aom_wood_oak_leaves.png^[noalpha'})
aom_wood.register_planks(S("Oak"), "Oak", {{name='aom_wood_planks_16x4.png', align_style="world", scale=4}})
aom_wood.register_plank(S("Oak"), "Oak", {'aom_wood_oak_plank.png'})
core.register_alias("aom_wood:oak_beam", "aom_wood:oak_planks_beam")

aom_util.register_all_shapes("aom_wood:oak_planks", {}, {remove_groups={"planks"}})


aom_wood.register_log(S("Ash"), "Ash", {'aom_wood_ash_log_top.png', 'aom_wood_ash_log_top.png', 'aom_wood_ash_log_side.png'})
aom_wood.register_leaves_old(S("Ash"), "Ash", {'aom_wood_ash_leaves.png'}, {'aom_wood_ash_leaves.png'}) -- deprecated, for compat only
aom_wood.register_leaves(S("Ash"), "Ash", {'aom_wood_ash_leaves.png'}, {'aom_wood_ash_leaves.png^[noalpha'})
aom_wood.register_planks(S("Ash"), "Ash", {{name='aom_wood_planks_16x4.png^[hsl:6:-20:10', align_style="world", scale=4}})
aom_wood.register_plank(S("Ash"), "Ash", {'aom_wood_ash_plank.png'})
core.register_alias("aom_wood:ash_beam", "aom_wood:ash_planks_beam")

aom_util.register_all_shapes("aom_wood:ash_planks", {}, {remove_groups={"planks"}})


aom_wood.register_log(S("Spruce"), "Spruce", {'aom_wood_spruce_log_top.png', 'aom_wood_spruce_log_top.png', 'aom_wood_spruce_log_side.png'})
aom_wood.register_leaves_old(S("Spruce"), "Spruce", {'aom_wood_spruce_leaves.png'}, {'aom_wood_spruce_leaves.png'}) -- deprecated, for compat only
aom_wood.register_leaves(S("Spruce"), "Spruce", {'aom_wood_spruce_leaves.png'}, {'aom_wood_spruce_leaves.png^[noalpha'})
aom_wood.register_planks(S("Spruce"), "Spruce", {{name='aom_wood_planks_16x4.png^[hsl:-7:-20:-40', align_style="world", scale=4}})
aom_wood.register_plank(S("Spruce"), "Spruce", {'aom_wood_spruce_plank.png'})
core.register_alias("aom_wood:spruce_beam", "aom_wood:spruce_planks_beam")

aom_util.register_all_shapes("aom_wood:spruce_planks", {}, {remove_groups={"planks"}})


aom_wood.register_log(S("Hem"), "Hem", {'aom_wood_hem_log_top.png', 'aom_wood_hem_log_top.png', 'aom_wood_hem_log_side.png'})
aom_wood.register_leaves(S("Hem"), "Hem", {'aom_wood_hem_leaves.png'}, {'aom_wood_hem_leaves.png^[noalpha'})
aom_wood.register_planks(S("Hem"), "Hem", {{name='aom_wood_planks_16x4.png^[hsl:-5:-75:-30', align_style="world", scale=4}})
aom_wood.register_plank(S("Hem"), "Hem", {'aom_wood_oak_plank.png'})
core.register_alias("aom_wood:hem_beam", "aom_wood:hem_planks_beam")

aom_util.register_all_shapes("aom_wood:hem_planks", {}, {remove_groups={"planks"}})



-- CHARCOAL
core.register_node('aom_wood:charcoal_block', {
	description = S("Block of Charcoal"),
	groups = {
		full_solid = 1, nature = 1, oddly_breakable_by_hand = 3,
		cracky = 1, solid = 1, suffocates = 2, flammable = 1, fuel = 60 },
	tiles = {"aom_charcoal_block.png"},
	drop = "aom_items:charcoal",
	sounds = aom_sounds.default_stone(),
})

core.register_node('aom_wood:hot_coals', {
	description = S("Hot Coals"),
	groups = {
		full_solid = 1, nature = 1, oddly_breakable_by_hand = 3,
		cracky = 1, solid = 1, suffocates = 2, flammable = 1, fuel = 60 },
	tiles = {"aom_hot_coals.png"},
	drop = {
		max_items = 1,
		items = {
			{
				items = {'aom_items:charcoal 1'},
				rarity = 2
			},
			{
				items = {'aom_items:charcoal 1'},
				rarity = 2
			},
		},
	},
	sounds = aom_sounds.default_stone(),
	light_source = 6,
	paramtype = "light",
	on_timer = function(pos, time)
		local above = core.get_node(vector.offset(pos, 0, 1, 0))
		if core.get_item_group(above.name, "fire") == 0
		and not core.find_node_near(pos, 2, "group:spreads_fire") then
			core.swap_node(pos, {name="aom_wood:charcoal_block"})
			core.get_node_timer(pos):stop()
			return false
		else
			core.get_node_timer(pos):set(10,0)
		end
	end,
	on_construct = function(pos)
		core.get_node_timer(pos):start(math.random(5, 60))
	end,
	_on_node_update = function(pos)
		local nt = core.get_node_timer(pos)
		if nt:is_started() then return end
		nt:start(math.random(5, 60))
	end,
})

dofile(mod_path .. "/scaffolding.lua")
dofile(mod_path .. "/roofs.lua")

do
		local function reg_transmute(a, b, n, c, hide)
				local ig = "aom_items:ignis"
				aom_tcraft.register_craft({
						output = a .. " " .. n, items = {[b] = n, [ig] = c},
						hide_if_not_craftable = hide, tags = {"transmute"},
				})
		end
		local wood_types = {"oak", "ash", "spruce", "hem"}
		local already_set = {}
		for k, a in ipairs(wood_types) do
			for i, b in ipairs(wood_types) do
				if (a ~= b) then
					reg_transmute("aom_wood:" .. a .. "_planks", "aom_wood:" .. b .. "_planks", 10, 1, already_set[a])
					already_set[a] = true
				end
			end
		end
		already_set = {}
		for k, a in ipairs(wood_types) do
			for i, b in ipairs(wood_types) do
				if (a ~= b) then
					reg_transmute("aom_wood:" .. a .. "_log", "aom_wood:" .. b .. "_log", 10, 1, already_set[a])
					already_set[a] = true
				end
			end
		end
end
