-- Kaki Tree (formerly "Jungle Tree").
-- Based on the real-world tree known under
-- the scientific name "Diospyros kaki".
-- The string "jungle" is still used in the node IDs
-- for compatibility reasons.

-- One in <this number> chance that a leaves node is replaced
-- by fruit
local FRUIT_CHANCE = 38

local S = minetest.get_translator("hades_trees")

local pr_j

local function check_node_light(pos, minlight, check)
	if check == false then
		return true
	end
	local l = minetest.get_node_light(pos)
	if not l or l < minlight then
		return false
	end
	return true
end

local function generate_large_kakitree(pos, check_light, trunk, leaves)
	local nu =  minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
	local ret = false
	for _,name in ipairs(hades_trees.DEFAULT_UNDERGROUND) do
		if nu == name then
			ret = true
			break
		end
	end
	if not ret then
		return false
	end

	trunk = trunk or "hades_trees:jungle_tree"
	leaves = leaves or "hades_trees:jungle_leaves"
	local fruit = "hades_refruit:bud_kaki"
	local c_jungletree = minetest.get_content_id(trunk)
	local c_jungleleaves = minetest.get_content_id(leaves)
	local c_fruit = minetest.get_content_id(fruit)

	-- Only grow fruit with default leaves
	local grow_fruit = leaves == "hades_trees:jungle_leaves"

	local param2
	local ndef = minetest.registered_nodes[leaves]
	if ndef and ndef.paramtype2 == "color" then
		param2 = hades_seasons.get_seasonal_palette_color_param2()
	else
		param2 = 0
	end

	local vm = minetest.get_voxel_manip()
	local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y-1, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
	local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
	local data = vm:get_data()
	local data_p2 = vm:get_param2_data()

	if not pr_j then
		local seed = math.random(1,100000)
		pr_j = PseudoRandom(seed)
	end
        local x, y, z = pos.x, pos.y, pos.z

	local lpos = {x=pos.x, y=pos.y+1, z=pos.z}
	if not check_node_light(lpos, 8, check_light) then
		return false
	end

	local c_air = minetest.CONTENT_AIR
	local c_ignore = minetest.CONTENT_IGNORE

	local tmin = 10
	local tmax = 14
        local th = pr_j:next(tmin, tmax)
	local main_trunk = c_jungletree
        for h = 1, th do
		local yy = y + (h - 1)
                local vi = a:index(x, yy, z)
                if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
                        data[vi] = main_trunk
			data_p2[vi] = param2
                else
			if h < tmin then
				-- Fail tree generation if not enough space for trunk
				return false
			else
				main_trunk = c_jungleleaves
			end
		end
        end
        y = y+th-1 -- (x, y, z) is now last piece of trunk
        local leaves_a = VoxelArea:new{MinEdge={x=-3, y=-4, z=-3}, MaxEdge={x=3, y=2, z=3}}
        local leaves_buffer = {}

        -- Force leaves near the trunk
        local d = 1
        for xi = -d, d do
        for yi = -d, d do
        for zi = -d, d do
                leaves_buffer[leaves_a:index(xi, yi, zi)] = true
        end
        end
        end

        -- Add leaves randomly
        for iii = 1, 30 do
                local d = 1
                local xx = pr_j:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
                local yy = pr_j:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
                local zz = pr_j:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)

                for xi = 0, d do
                for yi = 0, d do
                for zi = 0, d do
                        leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
                end
                end
                end
        end

        -- Add the leaves
        for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
        for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
        for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
                if a:contains(x+xi, y+yi, z+zi) then
                        local vi = a:index(x+xi, y+yi, z+zi)
                        if data[vi] == c_air or data[vi] == c_ignore then
                                if leaves_buffer[leaves_a:index(xi, yi, zi)] then
					if grow_fruit and math.random(1, FRUIT_CHANCE) == 1 then
						data[vi] = c_fruit
					else
						data[vi] = c_jungleleaves
						data_p2[vi] = param2
					end
                                end
                        end
                end
        end
        end
        end

	minetest.log("action", "[hades_trees] A kaki sapling grows into a tree at "..minetest.pos_to_string(pos))
	vm:set_data(data)
	vm:set_param2_data(data_p2)
	vm:write_to_map()
	vm:update_map()
	return true
end

local function generate_kakitree(pos, check_light, override_trunk, override_leaves, replacement, override_fruit)
	if not override_trunk then
		override_trunk = "hades_trees:jungle_tree"
	end
	if not override_leaves then
		override_leaves = "hades_trees:jungle_leaves"
	end
	hades_trees.generate_tree_variant({
		{ generate_large_kakitree, { pos, check_light, override_trunk, override_leaves } },
		{ hades_trees.generate_tree_schematic, { pos, minetest.get_modpath("hades_trees").."/schems/hades_trees_kaki_tree_small.mts", check_light, "hades_trees:jungle_tree", "hades_trees:jungle_leaves", "hades_refruit:bud_kaki", override_trunk, override_leaves, override_fruit } },
	})
end

hades_trees.register_trunk("jungle_tree", {
	--~ Trunk of the kaki tree (Diospyros kaki)
	description = S("Kaki Tree Trunk"),
	tiles = {"hades_trees_kaki_tree_top.png", "hades_trees_kaki_tree_top.png", "hades_trees_kaki_tree.png"},
})
hades_trees.register_bark("jungle_bark", {
	--~ Bark of the kaki tree (Diospyros kaki)
	description = S("Kaki Bark"),
	image = "hades_trees_kaki_tree.png",
})
hades_trees.register_leaves("jungle_leaves", {
	--~ Leaves of the kaki tree (Diospyros kaki)
	description = S("Kaki Leaves"),
	colorable = true,
	image = "hades_trees_kaki_leaves_colorable.png",
	palette = "hades_trees_kaki_leaves_palette.png",
	color_stereotype = "#83b555",
	ash_fertilizer = 3,
	drop_item = "hades_trees:jungle_seed",
	drop_rarity = 25,
	trunk = "hades_trees:jungle_tree",
})
hades_trees.register_sapling("jungle_sapling", {
	--~ Sapling of the kaki tree (Diospyros kaki)
	description = S("Kaki Tree Sapling"),
	image = "hades_trees_kaki_sapling.png",
	selbox = {-0.25, -0.5, -0.25, 0.25, 0.35, 0.25},
	grow = generate_kakitree,
})
hades_trees.register_seed("jungle_seed", {
	--~ Seed of the kaki tree (Diospyros kaki)
	description = S("Kaki Seed"),
	image = "hades_trees_kaki_seed.png",
	_hades_grows_to = "hades_trees:jungle_sapling",
})
hades_trees.register_fruit("kaki", {
	--~ Fruit of the kaki tree (Diospyros kaki). Also known as "persimmon"
	description = S("Kaki Fruit"),
	drawtype = "plantlike",
	image = "hades_trees_kaki.png",
	selbox = {-3/16, -5/16, -3/16, 3/16, 5/16, 3/16},
	sounds = hades_sounds.node_sound_leaves_defaults(),
	satiation = 1,
})

hades_trees.register_grow_abms({
	label = "Grow kaki tree sapling and seed",
	sapling = "hades_trees:jungle_sapling",
	seed = "hades_trees:jungle_seed",
	interval = 10,
	chance = 50,
})

-- Aliases for the removed "Cultivated Jungle Tree"
minetest.register_alias("hades_trees:cultivated_jungle_leaves", "hades_trees:jungle_leaves")
minetest.register_alias("hades_trees:cultivated_jungle_sapling", "hades_trees:jungle_sapling")
minetest.register_alias("hades_trees:cultivated_jungle_seed", "hades_trees:jungle_seed")
