
aom_wire.wirecutters = {}
aom_wire.wirecutters.max_targets = 5
aom_wire.wirecutters.pl = {}
local pl = aom_wire.wirecutters.pl


function aom_wire.wirecutters.check_player(player)
    if not pl[player] then
        pl[player] = {
        }
    end
    return pl[player]
end


function aom_wire.wirecutters.on_use(itemstack, player, pointed_thing)
    if (not pointed_thing) or (not pointed_thing.under) then return itemstack end
    local pi = aom_wire.wirecutters.check_player(player)
    local node = minetest.get_node_or_nil(pointed_thing.under)
    -- by definition, can only link from output nodes
    if node and (minetest.get_item_group(node.name, "wire_output") > 0) then
        local meta = minetest.get_meta(pointed_thing.under)
        meta:set_string("aom_wire_target", "")
        minetest.sound_play("pmb_fire_extinguish", {
            gain = 0.5,
            to_player = player:get_player_name(),
        })
    end
end

function aom_wire.wirecutters.show_connections_particles_for_pos(pos, target, player)
    local dir = vector.direction(pos, target)
    local vel = ((vector.distance(target, pos)-0.1)) * dir
    local playername = player:get_player_name()
    minetest.add_particlespawner({
        playername = playername,
        amount = 20,
        time = 2,
        vertical = false,
        texture = "blank.png^[noalpha^[colorize:#fe8:255",
        glow = 1,
        pos = pos,
        vel = vel,
        minexptime = 1,
        maxexptime = 1,
        minsize = 0.2,
        maxsize = 0.2,
    })
    local l = 0.2
    minetest.add_particlespawner({
        playername = playername,
        amount = 40,
        time = -1,
        vertical = false,
        texture = "blank.png^[noalpha^[colorize:#fe8:255",
        glow = 1,
        collisiondetection = true,
        attract = {
            kind = "point",
            origin = target,
            strength = 1.2,
            die_on_contact = false,
        },
        drag = vector.new(1,1,1),
        radius = 1.7,
        pos = target,
        -- minpos = vector.offset(target, -l, -l, -l),
        -- maxpos = vector.offset(target,  l,  l,  l),
        -- vel = -vel,
        minexptime = 4,
        maxexptime = 5,
        minsize = 0.4,
        maxsize = 0.4,
    })
end

function aom_wire.wirecutters.show_connections_particles(pos, player)
    if not minetest.is_player(player) then return end
    local outputs = aom_wire.get_outputs(pos)
    for i, target in ipairs(outputs or {}) do
        aom_wire.wirecutters.show_connections_particles_for_pos(pos, target, player)
    end
end

function aom_wire.wirecutters.on_place(itemstack, player, pointed_thing)
    local pi = aom_wire.wirecutters.check_player(player)
    local node = minetest.get_node_or_nil(pointed_thing.under)
    if not node then return end

    if not pi.source then
        -- by definition, can only link from output nodes
        if (minetest.get_item_group(node.name, "wire_output") > 0) then
            pi.source = {
                node = node,
                pos = vector.round(pointed_thing.under),
            }
            minetest.sound_play("pmb_wrench_plip", {
                gain = 0.5,
                to_player = player:get_player_name(),
            })
        else
            minetest.sound_play("pmb_not_allowed", {
                gain = 0.5,
                to_player = player:get_player_name(),
            })
        end
        pi.t = 0
        aom_wire.wirecutters.show_connections_particles(pointed_thing.under, player)
    else
        local success
        -- don't let player link nodes that are too far apart
        if aom_wire.dist2(pi.source.pos, pointed_thing.under) < 16 * 16 then
            success = aom_wire.add_output(pi.source.pos, pointed_thing.under, aom_wire.wirecutters.max_targets)
        end
        if success then
            aom_wire.wirecutters.show_connections_particles_for_pos(pi.source.pos, pointed_thing.under, player)
            pi.source = nil
            minetest.sound_play("pmb_wrench_plip", {
                gain = 0.5,
                to_player = player:get_player_name(),
            })
        else
            minetest.sound_play("pmb_not_allowed", {
                gain = 0.5,
                to_player = player:get_player_name(),
            })
        end
    end
end

function aom_wire.wirecutters.on_secondary_use(itemstack, player)
    local pi = aom_wire.wirecutters.check_player(player)

    if pi.source then pi.source = nil end

    minetest.sound_play("pmb_wrench_plip", {
        gain = 0.5,
        to_player = player:get_player_name(),
    })
end

function aom_wire.wirecutters.on_step(itemstack, player, dtime)
    local pi = aom_wire.wirecutters.check_player(player)
    if not pi.source then return end

    pi.t = (pi.t or 0) - dtime
    if pi.t < 0 then pi.t = pi.t + 1 else return end

    local pos = pi.source.pos
    local eyepos = aom_wire.get_eyepos(player)
    local dir = vector.direction(eyepos, pos)
    local vel = ((vector.distance(eyepos, pos)-1.5)) * dir
    minetest.add_particle({
        -- pos = eyepos + dir,
        pos = pos,
        velocity = dir * -10,
        expirationtime = 0.1,
        size = 2,
        collisiondetection = false,
        vertical = false,
        texture = "aom_wire_particle_highlight.png^[multiply:#fe8",
    })
end

function aom_wire.wirecutters.on_select(itemstack, player)
    local pi = aom_wire.wirecutters.check_player(player)
end

function aom_wire.wirecutters.on_deselect(itemstack, player)
    local pi = aom_wire.wirecutters.check_player(player)
    pi.source = nil
end
