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

function aom_picknode.get_eyepos(player)
    local eyepos = vector.add(player:get_pos(), vector.multiply(player:get_eye_offset(), 0.1))
    eyepos.y = eyepos.y + player:get_properties().eye_height
    return eyepos
end

function aom_picknode.get_tool_range(player)
    local hand = minetest.registered_items[""]
    local wield = player:get_wielded_item():get_definition()
    return math.max(wield.range or 4, hand.range or 4)
end

function aom_picknode.get_pointed_thing(player, eyepos, liquids)
    if not eyepos then eyepos = aom_picknode.get_eyepos(player) end
    local range = aom_picknode.get_tool_range(player)
    local ray = minetest.raycast(eyepos, vector.add(eyepos, vector.multiply(player:get_look_dir(), range)), false, (liquids == true))
    for pointed_thing in ray do
        if pointed_thing.type == "node" then
            return pointed_thing
        end
    end
    return nil
end

function aom_picknode.get_picked_list_index(inv, node)
    for listname, list in pairs(inv:get_lists()) do
        for i, stack in ipairs(list) do
            if stack:get_name() == node.name then
                return listname, i
            end
        end
    end
    return nil, nil
end

function aom_picknode.swap_items(inv, list1, index1, list2, index2)
    local stack1 = inv:get_stack(list1, index1)
    local stack2 = inv:get_stack(list2, index2)
    inv:set_stack(list1, index1, stack2)
    inv:set_stack(list2, index2, stack1)
end

-- based on the pointed node, try to swap items
function aom_picknode.pick_pointed(player, pointed_thing, force)
    local node = minetest.get_node(pointed_thing.under)
    local inv = player:get_inventory()
    local list1, index1 = player:get_wield_list(), player:get_wield_index()
    local list2, index2 = aom_picknode.get_picked_list_index(inv, node)
    if not list2 then
        -- creative
        if force then
            local leftover_stack = inv:get_stack(list1, index1)
            inv:set_stack(list1, index1, ItemStack(node.name))
            leftover_stack = inv:add_item(list1, leftover_stack)
            if leftover_stack:get_count() > 0 then
                minetest.add_item(player:get_pos(), leftover_stack)
            end
            return true
        end
        -- not creative
        return false
    end
    aom_picknode.swap_items(inv, list1, index1, list2, index2)
    return true
end
