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

aom_picknode = {}

dofile(mod_path .. "/system.lua")

local has_aom_settings = minetest.get_modpath("aom_settings")
if has_aom_settings then
    aom_settings.register_setting("gameplay_allow_picking_nodes", true, "Allow picking nodes (aux1 + dig)", "server")
    aom_settings.register_setting("gameplay_enable_nodepicker", false, "Allow picking nodes (aux1 + dig)")
end
function aom_picknode.get_setting(player, settingname, default)
    if not has_aom_settings then return default end
    return aom_settings.get_setting(player, settingname)
end


local pl = {}
aom_picknode.pl = pl

function aom_picknode.check_player(player)
    local pi = pl[player]
    if pi == nil then pi = {}; pl[player] = pi end
    return pi
end

-- this is used to alter how the controls work
function aom_picknode.is_player_just_picked_node(player, pi)
    local ctrl = player:get_player_control()
    -- don't pick constantly, only if you've only just started pressing dig
    if (ctrl.aux1) and (ctrl.dig) and (not pi.last_ctrl.dig) then
        return true
    end
    return false
end

-- actually do all the logic and actions to swap items to select a picked node
function aom_picknode.try_player_pick_node(player, dtime)
    local pi = aom_picknode.check_player(player)
    -- to prevent digging immediately on pick if using ctrl.dig
    pi.since_picked = (pi.since_picked or 0) + dtime
    if pi.since_picked > 2000 then pi.since_picked = pi.since_picked - 1000 end
    if not aom_picknode.get_setting(player, "gameplay_enable_nodepicker", false) then return end
    -- controls
    if pi.last_ctrl == nil then pi.last_ctrl = {} end
    local ctrl = player:get_player_control()
    if not aom_picknode.is_player_just_picked_node(player, pi) then
        pi.last_ctrl = ctrl
        return
    end
    pi.last_ctrl = ctrl
    -- get the info you need about stacks and inventories
    local stack = player:get_inventory():get_stack(
        player:get_wield_list(), player:get_wield_index()
    )
    local idef = stack:get_definition()
    local pointed_thing = aom_picknode.get_pointed_thing(
        player, aom_picknode.get_eyepos(player), idef and idef.liquids_pointable
    )
    if not pointed_thing then return end
    -- actually swap stacks around based on the pointed_thing / node
    local force = minetest.is_creative_enabled(player:get_player_name())
    local success = aom_picknode.pick_pointed(player, pointed_thing, force)
    if not success then return end
    pi.since_picked = 0
    -- minetest.log("picked")
    return true
end

-- main loop
minetest.register_globalstep(function(dtime)
    if not aom_picknode.get_setting(nil, "gameplay_allow_picking_nodes", false) then return end
    for i, player in ipairs(minetest.get_connected_players()) do
        aom_picknode.try_player_pick_node(player, dtime)
    end
end)

-- prevent digging if you just picked a node, so that picking the node doesn't cause you to dig it
local builtin_dig = minetest.node_dig
minetest.node_dig = function(pos, node, digger)
    if minetest.is_player(digger) and aom_picknode.get_setting(nil, "gameplay_allow_picking_nodes", false) then
        local pi = aom_picknode.check_player(digger)
        if (pi.since_picked or 0) < 0.15 then return end
        local is_immediate = minetest.get_item_group(node.name, "dig_immediate") >= 3
        if is_immediate and aom_picknode.try_player_pick_node(digger, 1) then return end
    end
    return builtin_dig(pos, node, digger)
end
