local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local S = minetest.get_translator(mod_name)


local drop_rarity = 8

local adjacent = {
    -- vector.new(0, 1, 0),
    -- vector.new(0,-1, 0),
    vector.new(0, 0, 1),
    vector.new(0, 0,-1),
    vector.new(1, 0, 0),
    vector.new(-1,0, 0),
}
local function get_adjacent_count(pos, group)
    local count = 0
    for i, p in pairs(adjacent) do
        local node = minetest.get_node(vector.add(pos, p))
        if minetest.get_item_group(node.name, group) > 0 then
            count = count + 1
        end
    end
    return count
end


local time_mult = 600
local function on_update(pos, cause, user, count, payload)

    local timer = minetest.get_node_timer(pos)
    if timer:is_started() then return false end
    if cause == "cavein" then
        local offset = pos.y - (payload and payload.pos.y) or pos.y
        timer:start(1)
        timer:set(10 + (payload and payload.time or 1), 10 - (0.1 + offset * 0.4 + math.random() * 0.4))
        return payload
    elseif (cause == "dig" or cause == "place") then
        -- don't start a cave-in check unless there is air below
        local below = vector.offset(pos, 0, -1, 0)
        if not minetest.registered_nodes[minetest.get_node(below).name].buildable_to then
            return
        end

        local time = math.random(time_mult)

        local spread = (cause == "dig" and math.random(2, 10)) or (cause == "place" and -1)
        if math.random() < 0.005 then
            minetest.get_node_timer(pos):start(math.random() * time_mult)
            pmb_node_update.update_node_propagate(pos, "cavein", nil, spread, 0.1, {pos=pos, time=time})
            return payload
        end

        local adjcountbelow = get_adjacent_count(vector.offset(pos, 0, -1, 0), "full_solid")
        local adjcount = get_adjacent_count(vector.offset(pos, 0, -1, 0), "full_solid")
        if (adjcountbelow == 0) and (adjcount <= 2 or math.random() < 0.1) then
            minetest.get_node_timer(pos):start(0.5)
            pmb_node_update.update_node(pos, "cavein", nil, 0, 0.1, {pos=pos, time=0})
            return false
        end
        return payload
    end
end

-- todo: add damage to falling nodes
local function on_timer(pos, elapsed)
    local thisnode = minetest.get_node(pos)
    local below = vector.offset(pos, 0, -1, 0)
    if minetest.registered_nodes[minetest.get_node(below).name].buildable_to then
        local bool, falling_ent = minetest.spawn_falling_node(pos)
        return false
        -- minetest.dig_node(below)
        -- minetest.set_node(pos, {name="air"})
        -- minetest.set_node(below, thisnode)
        -- local timer = minetest.get_node_timer(below)
        -- timer:start(0.1)
    end
end

minetest.register_node("pmb_stone:loose_stone", {
    description = pmb_util.desc(S("Loose Stone"), "grey"),
    _tt_long_desc = S("Not to be confused with Tight Stone"),
    groups = { full_solid = 1, nature = 1, item_stone = 1, oddly_breakable_by_hand = 1, solid = 1,
            suffocates = 2, cracky = 1, stone = 1, silk_touchable = 1, natural_stone = 1 },
    tiles = {{
            name = "pmb_loose_stone.png",
    }},
    drop = {
        max_items = 4,
        items = {
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    sounds = pmb_sounds.default_rocky(),
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_iron_ore", {
    description = pmb_util.desc(S("Iron Ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_iron_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 2, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_iron_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 4,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:iron_nugget"},
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_tin_ore", {
    description = pmb_util.desc(S("Tin Ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_tin_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 2, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_tin_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 4,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:tin_nugget"},
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_copper_ore", {
    description = pmb_util.desc(S("Copper Ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_copper_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 2, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_copper_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 4,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:copper_nugget"},
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_lapis_ore", {
    description = pmb_util.desc(S("Lapis Lazuli Ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_lapis_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 3, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_lapis_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 7,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:lapis_lazuli 2"},
            },
            {
                items = {"pmb_items:lapis_lazuli 2"},
                rarity = drop_rarity * 1.5
            },
            {
                items = {"pmb_items:lapis_lazuli 3"},
                rarity = drop_rarity * 2
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_diamond_ore", {
    description = pmb_util.desc(S("Diamond Ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_diamond_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 3, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_diamond_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 4,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:diamond"},
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})

minetest.register_node("pmb_stone:loose_stone_coal_ore", {
    description = pmb_util.desc(S("Coal ore"), "grey"),
    groups = { full_solid = 1, nature = 1, item_coal_ore = 1, oddly_breakable_by_hand = 3, solid = 1,
            suffocates = 2, cracky = 2, stone = 1, silk_touchable = 1 },
    tiles = { "pmb_loose_stone.png^pmb_coal_overlay.png" },
    sounds = pmb_sounds.default_rocky(),
    drop = {
        max_items = 4,
        items = {
            {
                rarity = drop_rarity,
                items = {"pmb_items:coal"},
            },
            {
                items = {"pmb_stone:cobble 1"},
            },
        },
    },
    on_timer = on_timer,
    _on_node_update = on_update,
})