local S = minetest.get_translator("hades_fertilizer")

-- Call minetest.set_node(pos, node), but only if pos is not protected by playername
local set_node_protected = function(pos, node, playername)
	if not (minetest.is_protected(pos, playername) and not minetest.check_player_privs(playername, "protection_bypass")) then
		minetest.set_node(pos, node)
		return true
	end
	return false
end

-- Returns an on_place function for fertilizer.
-- 'super' parameter is true for Super Fertilizer and false for normal fertilizer
local get_apply_fertilizer = function(super)
	return function(itemstack, placer, pointed_thing)
		if not pointed_thing or pointed_thing.type ~= "node" or not placer then
			return itemstack
		end
		local name = placer:get_player_name()
		local pos = pointed_thing.under
		local nnode = minetest.get_node(pos)
		local nname = nnode.name

		-- Boilerplate to check pointed node's on rightlick function
		local def = minetest.registered_nodes[nname]
		if not def then
			return itemstack
		end
		if def.on_rightclick and
			((not placer) or (placer and not placer:get_player_control().sneak)) then
			return def.on_rightclick(pos, nnode, placer, itemstack,
				pointed_thing) or itemstack
		end

		if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, "protection_bypass") then
			minetest.record_protection_violation(pos, name)
			return itemstack
		end

		if minetest.get_item_group(nname, "sapling") ~= 0 then
			if not super and math.random(1,5) ~= 1 then return itemstack end
			-- Grow sapling to tree
			if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, "protection_bypass") then
				return itemstack
			else
				hades_trees.grow_sapling(pos, false)
			end
		elseif def._hades_grows_to then
			-- Default next growth stage
			if (not super) then
				if math.random(1,3) == 1 then
					return itemstack
				end
			end
			local gtdef = minetest.registered_nodes[def._hades_grows_to]
			if not gtdef then
				minetest.log("error", "[hades_fertilizer] Node '"..nname.."' has _hades_grows_to pointing to an unknown node '"..tostring(def._hades_grows_to).."'")
				return itemstack
			end
			local new_param2
			if minetest.get_item_group(def._hades_grows_to, "seed") ~= 0 then
				new_param2 = gtdef.place_param2
			else
				new_param2 = nnode.param2
			end
			-- Add plant growth stage
			set_node_protected(pos, {name=def._hades_grows_to, param2=new_param2}, name)

		elseif nname == "hades_flowerpots:flower_pot" then
			if not super then return itemstack end
			-- [SUPER] Grow random flower in empty flowerpot
			local flowers = {
				"red", "white", "yellow", "orange", "yellow", "violet",
			}
			local flower = flowers[math.random(1, #flowers)]
			set_node_protected(pos, {name="hades_flowerpots:flower_pot_"..flower}, name)
		elseif minetest.get_item_group(nname, "leaves") == 1 then
			if not super then return itemstack end
			-- [SUPER] Grow leaves
			local posses = {
				{ x=0, y=0, z=1 },
				{ x=0, y=0, z=-1 },
				{ x=0, y=1, z=0 },
				{ x=0, y=-1, z=0 },
				{ x=1, y=0, z=0 },
				{ x=-1, y=0, z=0 },
			}
			for p=1, #posses do
				local ppos = vector.add(pos, posses[p])
				if minetest.get_node(ppos).name == "air" then
					set_node_protected(ppos, {name=nname, param2=nnode.param2}, name)
				end
			end
		elseif nname == "hades_core:papyrus" or nname == "hades_core:sugarcane" or nname == "hades_core:cactus" or minetest.get_item_group(nname, "tree") == 1 then
			if not super then return itemstack end
			-- [SUPER] Grow reeds and tree trunks upwards
			local above
			for i=1,15 do
				above = {x=pos.x,y=pos.y+i,z=pos.z}
				local node = minetest.get_node(above)
				if node.name == "air" then
					set_node_protected(above, {name=nname}, name)
					break
				elseif node.name ~= nname then
					break
				end
			end
		elseif minetest.get_item_group(nname, "vines") ~= 0 or nname == "hades_vines:root" then
			if not super then return itemstack end
			-- [SUPER] Grow vines
			local param2 = nnode.param2
			if param2 >= 2 or def.paramtype2 ~= "wallmounted" then
				-- Grow downwards
				local below
				for i=1,15 do
					below = {x=pos.x,y=pos.y-i,z=pos.z}
					local node = minetest.get_node(below)
					if node.name == "air" then
						set_node_protected(below, {name=nname, param2=param2}, name)
						break
					elseif node.name ~= nname then
						break
					end
				end
			end
		elseif nname == "hades_core:dirt" or minetest.get_item_group(nname, "dirt_with_grass") > 1 then
			-- Grow grass cover on dirt
			local posses = {}
			local minmax
			local dwg2 = minetest.get_item_group(nname, "dirt_with_grass")
			local d2 = minetest.get_item_group(nname, "dirt")
			if super then
				minmax=2
			else
				if d2 == 0 and dwg2 == 0 then
					return itemstack
				end
				minmax=1
			end
			local season_color = hades_seasons.get_seasonal_palette_color_param2()
			for x = pos.x - minmax, pos.x + minmax do
			for y = pos.y, pos.y do
			for z = pos.z - minmax, pos.z + minmax do
				local ppos = {x = x, y = y, z = z}
				if vector.distance(pos, ppos) <= 2.3 then
					local node = minetest.get_node(ppos)
					local above_node = minetest.get_node({x = x, y = y + 1, z = z})
					-- Apply change to same or "compatible" node type as the pointed
					-- node only, e.g. dirt is "compatible" with dirt-with-grass
					local d1 = minetest.get_item_group(node.name, "dirt")
					local dwg1 = minetest.get_item_group(node.name, "dirt_with_grass")
					if ((node.name == nname) or ((dwg1 > 1 or d1 > 0) and (dwg2 > 1 or d2 > 0))) and
							(nname ~= "hades_core:dirt" or
							(minetest.registered_nodes[above_node.name] and
							minetest.registered_nodes[above_node.name].walkable == false)) then
						if nname == "hades_core:dirt" then
							node.name = "hades_core:dirt_with_grass"
							node.param2 = season_color
						elseif dwg2 > 0 then
							node.name = "hades_core:dirt_with_grass"
							node.param2 = season_color
						end
						set_node_protected(ppos, node, name)
					end
				end
			end
			end
			end
		elseif minetest.get_item_group(nname, "mossifyable") ~= 0 or minetest.get_item_group(nname, "mossy") ~= 0 then
			if not super then return itemstack end
			-- [SUPER] Grow moss on stone and other mossifyable nodes
			-- Grow moss on node that supports a moss variant ('mossifyable' node)
			local minmax = 1
			for x = pos.x - minmax, pos.x + minmax do
			for y = pos.y - minmax, pos.y + minmax do
			for z = pos.z - minmax, pos.z + minmax do
				local neighbors = {
					vector.new(0, 0, 1),
					vector.new(0, 0, -1),
					vector.new(0, 1, 0),
					vector.new(0, -1, 0),
					vector.new(-1, 0, 0),
					vector.new(1, 0, 0),
				}
				local ppos = {x = x, y = y, z = z}
				local node = minetest.get_node(ppos)
				local d1 = minetest.get_item_group(node.name, "mossifyable")
				if d1 ~= 0 then
					local air_next = false
					for n=1, #neighbors do
						local neighpos = vector.add(ppos, neighbors[n])
						local neighnode = minetest.get_node(neighpos)
						if neighnode.name == "air" then
							air_next = true
							break
						end
					end
					if air_next then
						local ndef = minetest.registered_nodes[node.name]
						-- mossy variant must be stored in node definition
						if ndef and ndef._hades_mossy then
							node.name = ndef._hades_mossy
						end
						set_node_protected(ppos, node, name)
					end
				end
			end
			end
			end
		elseif nname == "hades_grass:grass" or nname == "hades_core:dirt_with_grass" or nname == "hades_core:fertile_sand" or nname == "hades_core:ash" or nname == "hades_core:volcanic_sand" or nname == "hades_core:gravel" or nname == "hades_core:gravel_volcanic" or nname == "hades_farming:soil" or nname == "hades_farming:soil_wet" then
			-- Grow grass, flowers and other random plants
			for x = pos.x - 2, pos.x + 2 do
			for y = pos.y, pos.y do
			for z = pos.z - 2, pos.z + 2 do
				local ppos = {x = x, y = y, z = z}
				if vector.distance(pos, ppos) <= 2.3 then
					local node = minetest.get_node(ppos)
					local pos_above = {x = x, y = y + 1, z = z}
					local above_node = minetest.get_node(pos_above)
					if above_node.name == "air" and math.random() < 0.2 and node.name == nname then
						local plants
						local p2season = hades_seasons.get_seasonal_palette_color_param2()
						if (node.name == "hades_grass:grass" or node.name == "hades_core:dirt_with_grass") then
							if super then
							plants = {
							{"hades_grass:grass_1", p2season},
							{"hades_grass:grass_2", p2season},
							{"hades_grass:grass_3", p2season},
							{"hades_grass:grass_4", p2season},
							{"hades_grass:grass_5", p2season},
							{"hades_grass:grass_1", p2season},
							{"hades_grass:grass_2", p2season},
							{"hades_grass:grass_3", p2season},
							{"hades_grass:grass_4", p2season},
							{"hades_grass:grass_5", p2season},
							{"hades_grass:grass_1", p2season},
							{"hades_grass:grass_2", p2season},
							{"hades_grass:grass_3", p2season},
							{"hades_grass:grass_4", p2season},
							{"hades_grass:grass_5", p2season},
							{"hades_grass:grass_1", p2season},
							{"hades_grass:grass_2", p2season},
							{"hades_grass:grass_3", p2season},
							{"hades_grass:grass_4", p2season},
							{"hades_grass:grass_5", p2season},
							{"hades_grass:junglegrass_1"},
							{"hades_grass:junglegrass_1"},
							{"hades_grass:junglegrass_1"},
							{"hades_grass:junglegrass_1"},
							{"hades_flowers:red"},
							{"hades_flowers:white"},
							{"hades_flowers:yellow"},
							{"hades_flowers:orange"},
							{"hades_flowers:violet"},
							{"hades_flowers:blue"},
							}
							else
							plants = {
							{"hades_grass:grass_1", p2season},
							{"hades_grass:grass_2", p2season},
							{"hades_grass:grass_3", p2season},
							{"hades_grass:grass_4", p2season},
							{"hades_grass:grass_5", p2season},
							}
							end
						elseif (node.name == "hades_core:ash" or node.name == "hades_core:volcanic_sand" or node.name == "hades_core:gravel_volcanic") then
							if not super then return itemstack end
							plants = {
							{ "hades_bushes:branch_bush"},
							}
						elseif (node.name == "hades_core:fertile_sand" or node.name == "hade_core:gravel") then
							if not super then return itemstack end
							plants = {
							{ "hades_bushes:branch_bush"},
							{ "hades_grass:grass_1", p2season},
							}
						elseif (node.name == "hades_farming:soil" or node.name == "hades_farming:soil_wet") then
							if not super then return itemstack end
							plants = {
							{"hades_farming:seed_wheat"},
							{"hades_farming:seed_cotton"},
							{"hades_farming:seed_tomato"},
							{"hades_farming:seed_strawberry"},
							{"hades_farming:seed_spice"},
							{"hades_farming:seed_potato"},
							}
						end
						if plants then
							local rnd = math.random(1, #plants)
							local plant = plants[rnd][1]
							local pdef = minetest.registered_nodes[plant]
							local p2
							if plants[rnd][2] then
								p2 = plants[rnd][2]
							elseif pdef then
								p2 = pdef.place_param2
							end
							local nnode = {name = plant, param2 = p2}
							set_node_protected(pos_above, nnode, name)
						end
					end
				end
			end
			end
			end
		elseif minetest.get_item_group(nname, "waterlily") ~= 0 or minetest.get_item_group(nname, "seaweed") ~= 0 then
			if not super then return itemstack end
			-- [SUPER] Spread waterlilies and seaweed on water
			for x = pos.x - 3, pos.x + 3 do
			for y = pos.y, pos.y do
			for z = pos.z - 3, pos.z + 3 do
				local ppos = {x = x, y = y, z = z}
				if vector.distance(pos, ppos) <= 3.0 then
					local node = minetest.get_node(ppos)
					local below_node = minetest.get_node({x = x, y = y - 1, z = z})
					if node.name == "air" and
							math.random() < 0.1 and
							minetest.get_item_group(below_node.name, "water") >= 1 and
							minetest.registered_nodes[below_node.name].liquidtype == "source" then
						node.name = nname
						node.param2 = math.random(0,3)
						set_node_protected(ppos, node, name)
					end
				end
			end
			end
			end

		end
		if not super and not minetest.is_creative_enabled(placer:get_player_name()) then
			itemstack:take_item()
		end
		return itemstack
	end
end

-- Fertilizer helps grow a few plants
minetest.register_craftitem("hades_fertilizer:fertilizer", {
	description = S("Fertilizer"),
	_tt_help = S("Makes plants grow"),
	inventory_image = "hades_fertilizer_fertilizer.png",
	on_place = get_apply_fertilizer(false),
	groups = { tool = 1 },
})

-- Super Fertilizer makes almost everything grow; only for Creative Mode
minetest.register_craftitem("hades_fertilizer:super_fertilizer", {
	description = S("Super Fertilizer"),
	_tt_help = S("Makes a lot of plants grow"),
	inventory_image = "hades_fertilizer_super_fertilizer.png",
	on_place = get_apply_fertilizer(true),
	groups = { tool = 1 },
})
