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

local pl = pmb_wrench.pl

pmb_wrench.max_dist = 16

pmb_wrench.prototype = {
    on_use = function (itemstack, player, pointed_thing)
        if not pl[player] then pl[player] = pmb_wrench.get_shell(player) end
        minetest.sound_play(("pmb_wrench_plip"), {
            gain = 0.1,
            pitch = 0.6,
            object = player,
        })

        pl[player].pos1 = pmb_wrench.get_pointed_position(player)

        if pl[player].pos1 then
            pl[player].build_list = nil
            pl[player].build_index = nil
            pmb_wrench.add_entity(pl[player].pos1, 1, player)
            pmb_wrench.set_position(player, 1)
            pmb_wrench.add_entity(pl[player].pos1, 2, player)
        end
    end,
    -- SELECT A NODE
    on_place = function(itemstack, player, pointed_thing)
        if not minetest.is_player(player) then return itemstack end
        minetest.sound_play(("pmb_wrench_plip"), {
            gain = 0.1,
            pitch = 0.8,
            object = player,
        })
        if not pl[player] then pl[player] = pmb_wrench.get_shell(player) end
        pl[player].node = minetest.get_node(pointed_thing.under)
        pmb_wrench.update_hud(player)
        pl[player].build_list = nil
        pl[player].build_index = nil
        pmb_wrench.chat_send_player(player,
            minetest.colorize("#aaa", "Wrench set to ") ..
            minetest.colorize("#9df", pl[player].node.name or "air")
        )
    end,
    -- SELECT AIR
    on_secondary_use = function(itemstack, player)
        minetest.sound_play(("pmb_wrench_plip"), {
            gain = 0.1,
            pitch = 0.8,
            object = player,
        })
        if not pl[player] then pl[player] = pmb_wrench.get_shell(player) end
        local pt = pmb_wrench.get_pointed_thing(player, nil, true)
        if pt then
            pl[player].node = minetest.get_node(pt.under)
            pmb_wrench.chat_send_player(player,
                minetest.colorize("#aaa", "Wrench set to ") ..
                minetest.colorize("#9df", pl[player].node.name or "air")
            )
            return itemstack
        end
        pl[player].node = {name="air"}
        pmb_wrench.update_hud(player)
        pmb_wrench.chat_send_player(player,
            minetest.colorize("#aaa", "Wrench set to ") ..
            minetest.colorize("#9df", pl[player].node.name or "air")
        )
        return itemstack
    end,
    -- MAIN
    on_step = function(itemstack, player, dtime)
        if not pl[player] then pl[player] = pmb_wrench.get_shell(player) return end
        local ctrl = player:get_player_control()
        local creative = pl[player].creative

        -- show a preview of where you're placing it when you press a key
        if (not pl[player].pos2) and ctrl and (not ctrl.dig) then
            local pointed, at_node = pmb_wrench.get_pointed_position(player)
            if at_node or ctrl.sneak then
                pl[player].pos1 = pointed
                pmb_wrench.set_position(player, 1)
                pmb_wrench.show_entity(player, 1)
            else
                pmb_wrench.hide_entity(player, 1)
            end
        elseif (not pl[player].pos2) and ctrl and ctrl.dig then
            pl[player].pos1 = pmb_wrench.get_pointed_position(player)
            pmb_wrench.set_position(player, 1)
            pmb_wrench.show_entity(player, 1)
        end

        if ctrl and ctrl.dig and pl[player].pos1 then
            pl[player].pos2 = pmb_wrench.get_pointed_position(player)

            -- make sure you're not able to make giant server-crashing cubes:
            local dist = pmb_wrench.squaredist(pl[player].pos1, pl[player].pos2)
            if (not creative) and (dist > pmb_wrench.max_dist^2) or dist > 200^2 then
                local dir = vector.direction(pl[player].pos1, pl[player].pos2)
                pl[player].pos2 = vector.add(vector.multiply(dir, pmb_wrench.max_dist), pl[player].pos1)
            end

            pmb_wrench.set_position(player, 2)
        end

        -- actually place nodes
        if pl[player].pos2 and ctrl and (not ctrl.dig) then
            pl[player].pos1, pl[player].pos2 = pmb_wrench.sort_positions(pl[player].pos1, pl[player].pos2)
            local nodelist = pmb_wrench.all_nodes_in(pl[player].pos1, pl[player].pos2)
            -- set the list of node positions to place at
            pl[player].build_list = (pl[player].node.name ~= "air" or creative) and nodelist
            pl[player].pos1, pl[player].pos2 = nil, nil
            pmb_wrench.remove_all_ents(player)
            if not pmb_wrench.take_item(player, pl[player].node.name, nil) then
                minetest.sound_play(("pmb_wrench_not_allowed"), {
                    gain = 0.4,
                    pitch = 0.95,
                    object = player,
                })
                pl[player].build_list = nil
                pl[player].build_index = nil
            end
            pl[player].pos2 = nil
        end

        -- do the building tick
        pmb_wrench.do_building(player, dtime, itemstack)
    end,
    on_select = function(itemstack, player)
        if not pl[player] then pl[player] = pmb_wrench.get_shell(player) end
        pmb_wrench.update_hud(player)
    end,
    on_deselect = function(itemstack, player)
        pmb_wrench.remove_all_ents(player)
        pl[player].pos2 = nil
        pl[player].pos1 = nil
        if pl[player].build_list then
            minetest.sound_play(("pmb_wrench_not_allowed"), {
                gain = 0.4,
                pitch = 0.95,
                object = player,
            })
            pl[player].build_list = nil
            pl[player].build_index = nil
        end
        if pl[player].node_hud then
            player:hud_remove(pl[player].node_hud)
            player:hud_remove(pl[player].node_hud2)
            pl[player].node_hud = nil
            pl[player].node_hud2 = nil
        end
    end,
}

minetest.register_tool("pmb_wrench:wrench", {
    description = S("Wrench"),
    _tt_color = 5,
    _tt_long_desc = S("Fill tool for faster and more convenient building"),
    _tt_how_to_use =(
        S("[place] to select a node").."\n"..
        S("[dig] and drag to wrench between points").."\n"..
        S("Hold [aux1] to select the \"under\" position").."\n"..
        S("Hold [sneak] to show where you're pointing in air")),
    inventory_image = "pmb_wrench.png",
    wield_image = "pmb_wrench.png",
    groups = { admin_tools = 1 },
    range = 6,
    on_use = pmb_wrench.prototype.on_use,
    on_place = pmb_wrench.prototype.on_place,
    on_secondary_use = pmb_wrench.prototype.on_secondary_use,
    on_step = pmb_wrench.prototype.on_step,
    on_select = pmb_wrench.prototype.on_select,
    on_deselect = pmb_wrench.prototype.on_deselect,
})

if minetest.get_modpath("pmb_tcraft") then
    pmb_tcraft.register_craft({
        output = "pmb_wrench:wrench",
        items = {
            ["pmb_items:iron_bar"] = 10,
        },
    })
end
