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


-- make sure the rope isn"t floating
function pmb_rope.rope_update(pos, cause, user, count, payload)
    local node = minetest.get_node(pos)
    local ndef = minetest.registered_nodes[node.name]
    local above_pos = vector.offset(pos, 0, 1, 0)
    local above = minetest.get_node(above_pos)
    local below_node = minetest.get_node(vector.offset(pos, 0, -1, 0))
    if above and minetest.get_item_group(above.name, "rope") == 0
    and minetest.get_item_group(above.name, "anchor") == 0
    and minetest.get_item_group(above.name, "solid") == 0 then
        -- look for an anchor above
        if  pmb_util.has_to_side(pos,       "solid") == 0
        and pmb_util.has_to_side(above_pos, "solid") == 0 then
            minetest.dig_node(pos)
        elseif (minetest.registered_nodes[above.name] or {}).buildable_to
        and pmb_util.has_to_side(above_pos, "solid") ~= 0 then
            minetest.dig_node(above_pos)
            minetest.set_node(above_pos, {name="pmb_rope:rope_anchor"})
        -- look for an anchor here
        elseif pmb_util.has_to_side(pos, "solid") ~= 0
        and minetest.get_item_group(below_node.name, "rope") ~= 0 then
            minetest.dig_node(pos)
            minetest.set_node(pos, {name=(ndef._rope_anchor or "pmb_rope:rope_anchor")})
        else
            minetest.dig_node(pos)
        end
    end
end


-- go down from the place position and find the first node you can place at, then place there and take an item
function pmb_rope.rope_extend(itemstack, _placer, pos)
    for i=0, 64 do
        local p = vector.offset(pos, 0, -i, 0)
        local node = minetest.get_node(p)
        local def = minetest.registered_nodes[node.name]
        if (not def) or def.walkable then return itemstack end
        if node.name == "air" or def.buildable_to then
            minetest.dig_node(p)
            minetest.set_node(p, {name = itemstack:get_name()})
            itemstack:take_item()
            return itemstack
        end
    end
    return itemstack
end


function pmb_rope.rope_place(itemstack, placer, pointed_thing)
    local ret = pmb_util.try_rightclick(itemstack, placer, pointed_thing, false)
    if ret then
        return ret, nil
    end
    local node = minetest.get_node(pointed_thing.under)

    -- try to place more rope on the existing rope
    if minetest.get_item_group(node.name, "rope") ~= 0 then
        return pmb_rope.rope_extend(itemstack, placer, pointed_thing.under)
    -- otherwise, if it can"t be placed here, don"t
    else
        -- gets complicated
        local above_pos = vector.offset(pointed_thing.above, 0, 1, 0)
        local above = minetest.get_node(above_pos)
        local place_node = minetest.get_node(pointed_thing.above)
        local below_pos = vector.offset(pointed_thing.above, 0, -1, 0)
        local below_node = minetest.get_node(below_pos)

        if pmb_util.has_to_side(above_pos, "solid") > 0 then
            return minetest.item_place(itemstack, placer, pointed_thing)
        elseif pmb_util.has_to_side(pointed_thing.above, "solid") > 0
        and (minetest.registered_nodes[below_node.name] or {}).buildable_to
        and (minetest.registered_nodes[place_node.name] or {}).buildable_to then
            local ndef = minetest.registered_nodes[itemstack:get_name()]
            minetest.set_node(pointed_thing.above, {name=(ndef._rope_anchor or "pmb_rope:rope_anchor")})
            minetest.set_node(below_pos, {name=itemstack:get_name()})
            itemstack:take_item()
            return itemstack
        elseif above and (pmb_util.has_to_side(above_pos, "solid") == 0 and minetest.get_item_group(above.name, "rope") == 0
        and minetest.get_item_group(above.name, "solid") == 0) then
            return itemstack
        end
    end
end

function pmb_rope.on_use(itemstack, user, pointed_thing)
    local ct = player_info.get(user)
    if ct and ct.ctrl.aux1 and ct.ctrl.sneak then
        if itemstack:get_count() >= 8 then
            local inv = user:get_inventory()
            itemstack:take_item(8)
            local ret = inv:add_item("main", ItemStack({name="pmb_rope:rope_coil", count=1}))
            if ret:get_count() > 0 then
                minetest.add_item(user:get_pos(), ret)
            end
        end
    end
    return itemstack
end


minetest.register_node("pmb_rope:rope", {
    description = S("Rope"),
    _tt_long_desc = S("Can be climbed on"),
    groups = { item_rope = 1, solid = 0, snappy = 3, flammable = 1, tool = 1, player_place_only = 1, oddly_breakable_by_hand = 1, rope = 1 },
    tiles = { "pmb_rope.png" },
    drawtype = "plantlike",
    collision_box = {0, 0, 0, 0, 0, 0},
    walkable = false,
    floodable = true,
    sunlight_propagates = true,
    paramtype = "light",
    use_texture_alpha = "clip",
    selection_box = {
        type = "fixed",
        fixed = {
            -1/16, -8/16, -1/16,
            1/16,  8/16,  1/16,
        }
    },
    sounds = pmb_sounds.default_fabric(),
    climbable = true,
    _on_node_update = function(pos, cause, user, count, payload)
        minetest.after(0.01, pmb_rope.rope_update, pos, cause, user, count, payload)
    end,
    on_place = pmb_rope.rope_place,
    on_secondary_use = pmb_rope.on_use,
})


local anchor_box = {
    type = "fixed",
    fixed = {
        -2/16, -8/16, -2/16, 2/16, -4/16, 8/16,
    }
}

minetest.register_node("pmb_rope:rope_anchor", {
    description = S("Rope"),
    _tt_color = 2,
    _tt_long_desc = S("Can be climbed on"),
    groups = { item_rope_anchor = 1, solid = 0, snappy = 3, oddly_breakable_by_hand = 1, anchor = 1, not_in_creative_inventory = 1, },
    tiles = { "pmb_rope_anchor.png" },
    drawtype = "nodebox",
    node_box = anchor_box,
    selection_box = anchor_box,
    drop = "",
    buildable_to = true,
    paramtype2 = "facedir",
    -- place_param2 = 0,
    collision_box = {0, 0, 0, 0, 0, 0},
    walkable = false,
    floodable = true,
    sunlight_propagates = true,
    paramtype = "light",
    use_texture_alpha = "clip",
    sounds = pmb_sounds.default_metal(),
    -- climbable = true,
    on_construct = function (pos)
        pmb_util.rotate_to_any_walkable(pos)
    end,
    _on_node_update = function(pos, cause, user, count, payload)
        if pmb_util.has_to_side(pos, "solid") == 0
        or (minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, -1, 0)).name, "rope") <= 0) then
            minetest.set_node(pos, {name="air"})
            return true
        else
            pmb_util.rotate_to_any_walkable(pos)
        end
        return false
    end,
    on_place = function(itemstack, placer, pointed_thing)
        minetest.rotate_and_place(itemstack, placer, pointed_thing)
    end,
    after_dig_node = function (pos, oldnode, oldmetadata, digger)
        if not digger:is_player() then return end
        local below_pos = vector.offset(pos, 0, -1, 0)
        local below_node = minetest.get_node(below_pos)
        if minetest.get_item_group(below_node.name, "rope") ~= 0 then
        minetest.dig_node(below_pos)
        end
    end
})




minetest.register_craft({
    output = "pmb_rope:rope 3",
    recipe = {
        {"pmb_items:plant_fibre"},
        {"pmb_items:plant_fibre"},
        {"pmb_items:plant_fibre"},
    }
})
