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

aom_trees.grow_tree = {}

aom_trees.schematics = {}

function aom_trees.register_sapling(name)
    local node_name = string.lower(name)
    aom_trees.grow_tree[node_name] = aom_trees.grow_tree[node_name] or function() return nil end

    core.register_node(("aom_trees:" .. node_name .. "_sapling"), {
        description = S("@1 Sapling", name),
        drawtype = "plantlike",
        waving = 1,
        visual_scale = 1.0,
        tiles = {"aom_sapling_" .. node_name .. ".png"},
        inventory_image = "aom_sapling_" .. node_name .. ".png",
        wield_image = "aom_sapling_" .. node_name .. ".png",
        paramtype = "light",
        sunlight_propagates = true,
        walkable = false,
        groups = { nature = 1, ["item_"..node_name.."_sapling"] = 1, attached_node = 1, player_place_only = 1, dig_immediate = 3, sapling = 1,},
        -- drop = {"aom_trees:" .. node_name .. "_sapling"},
        -- sounds = {},
        selection_box = {
            type = "fixed",
            fixed = {-5/16, -8/16, -5/16, 5/16, 1/16, 5/16},
        },
        is_ground_content = true,
        _tree_type = node_name,
        _tree_grow = function(pos, node)
            if type(aom_trees.grow_tree[name]) == "function" then
                aom_trees.grow_tree[name](pos, node)
            else
                aom_trees.grow_tree.general(pos, node_name)
            end
        end,
        on_place = function(itemstack, placer, pointed_thing)
            return aom_util.only_place_above(itemstack, placer, pointed_thing, {"soil"})
        end,
    })
end

aom_trees.register_sapling("Oak")
aom_trees.register_sapling("Ash")
aom_trees.register_sapling("Spruce")
aom_trees.register_sapling("Hem")


-- schematics and growing trees
local sch = aom_sch.get_schematic_path

function aom_trees.register_tree_schematic(kind, name, height)
    aom_trees.schematics[kind] = aom_trees.schematics[kind] or {}
    aom_trees.schematics[kind][#aom_trees.schematics[kind]+1] = {
        schem = sch(name),
        height = height or 10,
    }
end

-- OAK
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h8_0", 8)
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h8_1", 8)
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h10_0", 10)
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h12_0", 12)
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h12_1", 12)
aom_trees.register_tree_schematic("oak", "aom_tree_oak_h14_0", 14)
-- aom_trees.register_tree_schematic("oak", "aom_tree_oak_h19_0", 19)
-- aom_trees.register_tree_schematic("oak", "aom_tree_oak_h23_0", 23)

-- ASH
aom_trees.register_tree_schematic("ash", "aom_tree_ash_h12_0", 12)
aom_trees.register_tree_schematic("ash", "aom_tree_ash_h15_0", 15)
aom_trees.register_tree_schematic("ash", "aom_tree_ash_h18_0", 18)
-- aom_trees.register_tree_schematic("ash", "aom_tree_ash_h19_0", 19)
-- aom_trees.register_tree_schematic("ash", "aom_tree_ash_h31_0", 31)

-- SPRUCE
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_h9_0", 9)
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_h9_1", 9)
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_h9_2", 9)
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_h15_0", 9)
-- aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_tall_h28_0", 28)
-- aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_tall_h25_0", 25)
-- aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_tall_h23_0", 23)
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_tall_h20_0", 20)
aom_trees.register_tree_schematic("spruce", "aom_tree_spruce_tall_h18_0", 18)

-- HEM
aom_trees.register_tree_schematic("hem", "aom_tree_hem_h9_0", 9)
aom_trees.register_tree_schematic("hem", "aom_tree_hem_h12_0", 12)
aom_trees.register_tree_schematic("hem", "aom_tree_hem_h15_0", 15)

local function is_air_above(pos, limit)
    local v = vector.copy(pos)
    v.y = v.y + limit - 1
    local nodes = core.find_nodes_in_area(pos, v, {"group:solid"})
    if #nodes > 0 then return false end
    return true
end

function aom_trees.grow_tree.general(pos, name)
    local schems = aom_trees.schematics[name]
    if not schems then
        core.log("error", "Warning, unable to place sapling type " .. tostring(name) .. " at " .. dump(pos))
        return end
    local max_limit = 80
    local offset = math.random(1, #schems)
    local entry
    for k = 1, #schems do
        local i = (k + offset - 1) % #schems + 1
        local schem = schems[i]
        if schem.height < max_limit then
            if is_air_above(pos, schem.height) then
                entry = schem
                break
            else
                max_limit = schem.height
            end
        end
    end
    if not entry then return end
    core.set_node(pos, {name = "air"})
    core.place_schematic(pos, entry.schem, "random", nil, false, {place_center_x=true, place_center_z=true})
end
