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

-- max number for `paramtype2 = "degrotate"`
local DEGROT_MAX = 239

local grass_box = {
	type = "fixed",
	fixed = {
		-6/16, -8/16, -6/16,
		6/16, 16/16, 6/16,
	}
}

-- param2 is used for degrotate
-- if % 3 == 0, it is naturally generated and drops seeds
-- if % 3 == 1, it is growing
-- if % 3 == 2, it is player placed as decoration and doesn't grow or drop seeds

local np = {
	offset = 0.5,
	scale = 0.5,
	spread = {x = 2, y = 2, z = 2},
	seed = 324 + (core.get_mapgen_setting("seed") or 0),
	octaves = 2,
	persist = 0.1,
	lacunarity = 2.317,
}
local iperlin = PerlinNoise(np)

local function clamp(v, min, max)
	return math.min(math.max(v, min), max)
end

local variant_count = 2

local function on_generated(pos, force_variant)
	local nv
	if force_variant then
		nv = force_variant
	else
		nv = clamp(iperlin:get_3d(pos), 0, 0.99)
		nv = math.floor(nv * (variant_count+1))
	end
	core.swap_node(pos, {
		name = "aom_flora:" .. "aelum_grass_" .. nv,
		param2 = math.floor(math.random(0, DEGROT_MAX) / 3) * 3 + 0
	})
end

local drop_tables = {
	full = {
		max_items = 4,
		items = {
			{
				items = {"aom_flora:aelum_grass_seeds 1"},
			},
			{
				items = {"aom_flora:aelum_grass_seeds 1"},
			},
			{
				items = {"aom_flora:aelum_grass_seeds 1"},
				rarity = 3
			},
		},
	},
	partial = {
		max_items = 1,
		items = {
			{
				items = {"aom_flora:aelum_grass_seeds"},
				rarity = 2
			},
			{
				items = {"aom_flora:aelum_grass_seeds"},
				rarity = 3
			},
		},
	},
}

local function random_grow_time()
	return (math.random(400, 500))
end

local crop_fail_chance = 0.0

local function grow_plant(pos, node, active_object_count, active_object_count_wider)
	if (node.param2 % 3) ~= 1 then return false end
	aom_util.did_abm("crop")
	local light = core.get_node_light(pos, 0.5)
	if light > 8 then
		local def = core.registered_nodes[node.name]
		local next_stage = (def and def._growth_stage + 1) or 1
		-- random chance to leave as immature plant
		if (next_stage >= 1) and (math.random() < crop_fail_chance) then
			if next_stage >= variant_count - 1 then
				node.param2 = math.floor(node.param2 / 3) * 3 + 0
				core.set_node(pos, node)
			end
			return false
		end
		node.name = "aom_flora:aelum_grass_" .. next_stage
		if not core.registered_nodes[node.name] then return false end
		if next_stage >= variant_count then
			node.param2 = math.floor(node.param2 / 3) * 3 + 0
		end
		core.set_node(pos, node)
	end
	return true
end

-- aom_flora:aelum_grass_0
for i = 0, variant_count do
	core.register_node("aom_flora:aelum_grass_" .. i, {
		-- TL: tall grass
		description = S("Aelum Grass"),
		_tt_long_desc = S("A sweet smelling plant which makes you feel sleepy."),
		mesh = "2node_3poly_foliage.b3d",
		tiles = {"aom_aelum_" .. i .. ".png"},
		use_texture_alpha = "clip",
		drawtype = "mesh",
		walkable = false,
		waving = 1,
		paramtype = "light",
		paramtype2 = "degrotate",
		is_ground_content = true,
		sunlight_propagates = true,
		selection_box = grass_box,
		groups = {nature = 1, attached_node = 1, flamamble = 1, item_grass = 1, aelum_grass = 1,
			player_place_only = 1, dig_immediate = 3, flora = 1, decoration = 1, },
		drop = drop_tables.full,
		_get_node_drops = function(node, toolname)
			local drops = {}
			if node.param2 % 3 == 0 then
				table.insert(drops, ItemStack("aom_flora:aelum_grass_0"))
				table.insert(drops, ItemStack("aom_flora:aelum_grass_seeds"))
			elseif node.param2 % 3 == 1 then
				table.insert(drops, ItemStack("aom_flora:aelum_grass_seeds"))
			else
				table.insert(drops, ItemStack("aom_flora:aelum_grass_0"))
			end
			return drops
		end,
		_growth_stage = i,
		buildable_to = true,
		sounds = aom_sounds.default_plant(),
		on_place = function(itemstack, placer, pointed_thing)
			return aom_util.only_place_above(itemstack, placer, pointed_thing, {"soil", "gravel"})
		end,
		on_timer = function(pos, elapsed)
			if grow_plant(pos, core.get_node(pos)) then
				local timer = core.get_node_timer(pos)
				timer:start(random_grow_time())
			end
		end,
		after_place_node = function(pos, placer, itemstack, pointed_thing)
			local nv = math.random(0, variant_count)
			core.swap_node(pos, {
				name = "aom_flora:" .. "aelum_grass_" .. nv,
				param2 = math.floor(math.random(0, DEGROT_MAX) / 3) * 3 + 2
			})
		end,
		_after_generated = function(pos)
			on_generated(pos, (i==0) and 0)
		end,
	})
end


core.register_node("aom_flora:aelum_grass_seeds", {
	-- TL: seeds for tall grass called aelum
	description = S("Aelum Grass Seeds"),
	drawtype = "plantlike",
	tiles = {"aom_aelum_seeds.png"},
	inventory_image = "aom_aelum_seeds.png",
	walkable = false,
	waving = 1, --1
	paramtype = "light",
	paramtype2 = "degrotate",
	is_ground_content = true,
	sunlight_propagates = true,
	selection_box = grass_box,
	groups = {nature = 1, attached_node = 1, flamamble = 1, item_grass = 1,
		player_place_only = 1, dig_immediate = 3, flora = 1, decoration = 1, },
	drop = "aom_flora:aelum_grass_seeds",
	buildable_to = true,
	sounds = aom_sounds.default_plant(),
	on_place = function(itemstack, placer, pointed_thing)
		return aom_util.only_place_above(itemstack, placer, pointed_thing, {"soil", "gravel"})
	end,
	after_place_node = function(pos, placer, itemstack, pointed_thing)
		core.set_node(pos, {
			name = "aom_flora:aelum_grass_0",
			param2 = math.floor(math.random(0, DEGROT_MAX) / 3) * 3 + 1
		})
		core.get_node_timer(pos):start(random_grow_time())
	end,
    node_placement_prediction = "air",
})

aom_tcraft.register_craft({
    output = "aom_items:plant_fibre 2",
    items = {
        ["aom_flora:aelum_grass_0"] = 1,
    },
	tags = {"goods"},
})
