local S = minetest.get_translator("hades_trees")

hades_trees.register_trunk = function(id, def)
	local flammable = 2
	if def.is_flammable == false then
		flammable = nil
	end
	minetest.register_node("hades_trees:"..id, {
		description = def.description,
		tiles = def.tiles,
		paramtype = "light",
		drawtype = "nodebox",
		node_box = {
			type = "fixed",
			fixed = {
				{-0.5,-0.5,-3/16, 0.5,0.5,3/16},
				{-7/16,-0.5,-5/16, 7/16,0.5,5/16},
				{-6/16,-0.5,-6/16, 6/16,0.5,6/16},
				{-5/16,-0.5,-7/16, 5/16,0.5,7/16},
				{-3/16,-0.5,-0.5, 3/16,0.5,0.5},
			},
		},
		collision_box = {
			type = "fixed",
			fixed = {{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }},
		},
		is_ground_content = false,
		groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=flammable},
		sounds = def.sounds or hades_sounds.node_sound_wood_defaults(),
	})
end

hades_trees.register_bark = function(id, def)
	local flammable = 2
	if def.is_flammable == false then
		flammable = nil
	end
	minetest.register_node("hades_trees:"..id, {
		description = def.description,
		paramtype2 = "facedir",
		tiles = {{ name = def.image, align_style = "node" }},
		is_ground_content = false,
		groups = { bark=1, choppy = 3, oddly_breakable_by_hand = 1, flammable = flammable },
		sounds = def.sounds or hades_sounds.node_sound_wood_defaults(),
	})
end

hades_trees.register_sapling = function(id, def)
	if def.growtype then
		def._growtype = def.growtype
		minetest.log("warning", "[hades_trees] 'growtype' field in hades_trees.register_sapling def is deprecated. Use '_growtype' instead (id="..tostring(id)..")")
	end
	local tth
	if def._growtype == "none" then
		-- Doesn't grow
	elseif def._growtype == "ash" then
		tth = S("Needs Dirt, Fertile Sand, Volcanic Sand or Volcanic Ash to grow, and light")
	elseif def._growtype == "fertile_sand" then
		tth = S("Needs Dirt or Fertile Sand to grow, and light")
	else
		def._growtype = "dirt"
		tth = S("Needs Dirt and light to grow")
	end
	minetest.register_node("hades_trees:"..id, {
		description = def.description,
		_tt_help = tth,
		drawtype = "plantlike",
		tiles = {def.image},
		inventory_image = def.image,
		wield_image = def.image,
		paramtype = "light",
		walkable = false,
		is_ground_content = false,
		floodable = true,
		selection_box = {
			type = "fixed",
			fixed = def.selbox,
		},
		groups = {snappy=2,oddly_breakable_by_hand=3,flammable=2,attached_node=1, sapling=1},
		sounds = hades_sounds.node_sound_bush_defaults(),
		_hades_grow_sapling = def.grow,
		_hades_growtype = def._growtype,
		_hades_fruit = def.fruit,
		_hades_fruit_chance = def.fruit_chance,
	})
end

--[[ Register leaves with node name `id`.
Leaves are the foliage that belong to trees. Leaves are associated with a tree trunk node
and may decay if no matching tree trunk node is nearby. Leaves can either be colorable
or have a fixed color.

The param2 of leaves stores two things: First, is stores if they are "natural"
or placed by a player. Colorable leaves also store the color in param2.
For all leaves:

* param2 = 0..5: Leaves are natural
* param2 = 6..11: Leaves are placed by player

Natural leaves are subject to decay (die when no tree nearby), but leaves
placed by a player (according to param2) won’t decay.

For colorable leaves, a palette texture must be used with 6 colors, used twice.
param2 values 0 to 5 are identical in meaning to grass (see hades_grass).
param2 values 6 to 11 MUST be the same colors repeated.

def is a definition table with:
* drop_item: Drop this item alternatively to the leaves themselves. If nil, node will always drop itself.
* drop_rarity: Drop def.drop_item with chance of 1/def.drop_rarity.
* leafdecay: Value of leafdecay group (see GROUPS.md) (default: 3)
* leafdecay_any: Value of leafdecay_any group (see GROUPS.md) (default: nil)
* ash_fertilizer: Value of ash_fertilizer group (see GROUPS.md) (default: nil)
* trunk: Name of tree trunk this node belongs to

* colorable: If true, leaves change color according to season
* palette: Only for colorable leaves. Palette of the leaves. Only palette indexes
  0 to 5 need to be used here (same meaning as in hades_grass).
  MUST be a 16×16 texture.
* color_stereotype: Only for colorable leaves. A colorstring for the 'stereotypical'
  color that represents the leaves node in inventory or the wieldhand.
  Recommended: Use the palette’s summer color
* leaves_group: Rough classification of leaves for grouping:
  * "lush": Leaves suited for lush biomes (jungle, temperate climate) (default)
  * "volcanic": Leaves for volcanic environments (pale leaves, etc.)
  * Node will be added to correspnding "leaves_<group>=1" group
]]
hades_trees.register_leaves = function(id, def)
	local drop
	if def.drop_item then
		drop = {
			max_items = 1,
			items = {
			{
					-- player will get def.drop_item with chance of (1/def.drop_rarity)
					items = {def.drop_item},
					rarity = def.drop_rarity,
				},
				{
					-- player will get leaves only if they get no def.drop_item,
					-- this is because max_items is 1
					items = {"hades_trees:"..id},
				}
			}
		}
	else
		-- explicit drop required in case node is colorable, because
		-- colored nodes drop with metadata by default
		drop = "hades_trees:"..id
	end

	local groups = {snappy=3, leafdecay=def.leafdecay or 3, leafdecay_any=def.leafdecay_any, flammable=2, leaves=1, ash_fertilizer=def.ash_fertilizer, porous=1}
	if def.leaves_group == "volcanic" then
		groups.leaves_volcanic = 1
	else
		groups.leaves_lush = 1
	end
	local paramtype2, on_place, place_param2
	if def.colorable then
		paramtype2 = "color"
		groups.leafseasonal = 1
		on_place = function(itemstack, placer, pointed_thing)
			-- Pick the correct seasonal plant color
			local name = itemstack:get_name()
			local param2 = hades_seasons.get_seasonal_palette_color_param2()
			-- Mark leaves as placed-by-player
			param2 = param2 + hades_trees.LEAVES_PALETTE_REPEAT
			local ret = minetest.item_place(itemstack, placer, pointed_thing, param2)
			return ItemStack(name.." "..ret:get_count())
		end
	else
		-- Mark leaves as placed-by-player
		place_param2 = hades_trees.LEAVES_PALETTE_REPEAT
	end

	-- Use a custom wield image for the leaves instead of the default
	-- 3D cube. This is a workaround for a Luanti bug that causes
	-- colored nodes to have the wrong color in the wieldhand,
	-- as of Luanti 5.11.0 <https://github.com/luanti-org/luanti/issues/12578>
	-- TODO: Remove the workaround and remove the custom wield_image, wield_overlay
	-- as soon the Luanti bug is fixed.
	local image, overlay_tiles
	if def.color_stereotype then
		image = "("..def.image..")^[multiply:"..def.color_stereotype
	else
		image = def.image
	end
	if def.overlay_image then
		overlay_tiles = { { name = def.overlay_image, color = "white" } }
		image = "("..image .. ")^" .. def.overlay_image
	end

	local double_palette
	if def.palette then
		-- Automatically duplicate the first 6 pixels of the palette texture
		-- so that param2 values 6 to 11 get color with the same colors.
		-- Assumes the palette uses size 16x16.
		double_palette = "[combine:16x16:0,0="..def.palette..":6,0="..def.palette
	end

	minetest.register_node("hades_trees:"..id, {
		description = def.description,
		drawtype = "allfaces_optional",
		tiles = {def.image},
		overlay_tiles = overlay_tiles,
		wield_image = image,
		wield_overlay = image,
		paramtype = "light",
		waving = 1,
		is_ground_content = false,
		paramtype2 = paramtype2,
		place_param2 = place_param2,
		on_place = on_place,
		palette = double_palette,
		color = def.color_stereotype,
		groups = groups,
		drop = drop,
		sounds = def.sounds or hades_sounds.node_sound_leaves_defaults(),
		-- Store node name of corresponding trunk node
		_hades_trees_trunk = def.trunk,
	})
end

hades_trees.register_fruit = function(id, def)
	local sat = def.satiation
	local on_use, food
	if def.satiation then
		food = 2
		on_use = minetest.item_eat(sat)
	end
	local groups = {dig_immediate=3,flammable=2,leafdecay=def.leafdecay or 3,leafdecay_drop=1,food=food,eatable=sat}
	if def.groups then
		for k,v in pairs(def.groups) do
			if v == 0 then
				v = nil
			end
			groups[k] = v
		end
	end
	minetest.register_node("hades_trees:"..id, {
		description = def.description,
		drawtype = def.drawtype,
		tiles = {def.image},
		inventory_image = def.image,
		wield_image = def.image,
		paramtype = "light",
		sunlight_propagates = true,
		walkable = false,
		is_ground_content = false,
		floodable = true,
		selection_box = {
			type = "fixed",
			fixed = def.selbox,
		},
		groups = groups,
		on_use = on_use,
		sounds = def.sounds or hades_sounds.node_sound_leaves_defaults(),
		place_param2 = 1,
	})
end

hades_trees.register_grow_abms = function(def)
	if def.growtype then
		def._growtype = def.growtype
		minetest.log("warning", "[hades_trees] 'growtype' field in hades_trees.register_grow_abms def is deprecated. Use '_growtype' instead")
	end
	minetest.register_abm({
		label = def.label,
		nodenames = {def.sapling, def.seed},
		interval = def.interval,
		chance = def.chance,
		action = function(pos, node)
			local bnode = minetest.get_node(vector.offset(pos, 0, -1, 0))
			local is_seed = node.name == def.seed

			-- Check if sapling or seed is on correct ground. If not, kill it
			if bnode.name == "hades_furniture:plant_pot" then
				if not is_seed then
					-- Preserve sapling node on plant pot, but don't grow
					return
				end
			else
				local undergrounds = table.copy(hades_trees.DEFAULT_UNDERGROUND)
				if def._growtype == "none" then
					undergrounds = {}
				elseif def._growtype == "ash" then
					table.insert(undergrounds, "hades_core:ash")
					table.insert(undergrounds, "hades_core:volcanic_sand")
					table.insert(undergrounds, "hades_core:fertile_sand")
				elseif def._growtype == "fertile_sand" then
					table.insert(undergrounds, "hades_core:fertile_sand")
				end
				local u_ok = hades_trees.check_underground(pos, undergrounds)
				if not u_ok then
					if is_seed then
						minetest.remove_node(pos)
					else
						minetest.set_node(pos, {name="hades_trees:dead_sapling"})
					end
				end
			end

			if is_seed then
				-- Grow seed
				local ll = minetest.get_node_light(pos)
				if ll >= 8 then
					minetest.set_node(pos, {name=def.sapling})
				end
			else
				-- Grow sapling
				hades_trees.grow_sapling(pos)
			end
		end
	})
end

hades_trees.register_seed = function(name, def)
	if def.growtype then
		def._growtype = def.growtype
		def.growtype = nil
		minetest.log("warning", "[hades_trees] 'growtype' field in hades_trees.register_seed def is deprecated. Use '_growtype' instead (name="..tostring(name)..")")
	end
	local fullname = "hades_trees:"..name
	local sdef = table.copy(def)

	-- Register seed growing info to node definition
	if def._growtype == "none" then
		-- Seed won't grow
	elseif def._growtype == "ash" then
		sdef.surface_check = function(node)
			if minetest.get_item_group(node.name, "ash") ~= 0 or minetest.get_item_group(node.name, "sand") ~= 0 or minetest.get_item_group(node.name, "dirt") ~= 0
				or node.name == "hades_furniture:plant_pot" then
				return true
			else
				return false
			end
		end
		sdef._tt_help = def._tt_help or S("Needs Dirt, Fertile Sand, Volcanic Sand or Volcanic Ash to grow")
	elseif def._growtype == "fertile_sand" then
		sdef.surface_check = function(node)
			if node.name == "hades_core:fertile_sand" or minetest.get_item_group(node.name, "dirt") ~= 0
				or node.name == "hades_furniture:plant_pot" then
				return true
			else
				return false
			end
		end
		sdef._tt_help = def._tt_help or S("Needs Dirt or Fertile Sand to grow")
	else
		sdef.surface_check = function(node)
			if minetest.get_item_group(node.name, "dirt") ~= 0
				or node.name == "hades_furniture:plant_pot" then
				return true
			else
				return false
			end
		end
		sdef._tt_help = def._tt_help or S("Needs dirt to grow")
		sdef._growtype = "dirt"
	end
	sdef._hades_growtype = sdef._growtype
	sdef._growtype = nil
	hades_seeds.register_seed(fullname, sdef)
end


