
wield3d.player = {}
wield3d.ent = {}
wield3d.force_visible = false
local pl = wield3d.player
local en = wield3d.ent

local wield_scale = 0.25

local loc = function() return {
    bone =  "armR",
    off =   {x=0, y=5.0, z=-3},
    rot =   {x=-90, y=45, z=-90},
    scale = {x=wield_scale, y=wield_scale, z=wield_scale}}
end

function wield3d.get_wield_def(item_name, override)
    local offset = loc()
    local def = override or minetest.registered_items[item_name]
    if not def then return offset end
    offset.off   = def._wield3d_offset   or offset.off
    offset.scale = def._wield3d_scale    or offset.scale
    offset.rot   = def._wield3d_rotation or offset.rot
    offset.bone  = def._wield3d_bone     or offset.bone
    offset.tex   = def._wield3d_textures or offset.tex
    offset.visual= def._wield3d_visual   or offset.visual
    offset.mesh  = def._wield3d_mesh     or offset.mesh
    return offset
end

function wield3d.update(player, override)
    local wield = player:get_wielded_item()
    wield = (wield and wield:get_name()) or "wield3d:empty"
    if (pl[player].last_wield ~= wield) or (override ~= nil) then
        pl[player].last_wield = wield
        local o = wield3d.get_wield_def(wield, override)
        if wield == "" then wield = "wield3d:empty" end
        pl[player].ent.object:set_properties({
            textures = {o.tex or wield},
            visual_size = o.scale,
            visual = o.visual or "wielditem",
            mesh = o.mesh or nil,
        })
        pl[player].ent.object:set_attach(player, o.bone, o.off, o.rot, o.force_visible or wield3d.force_visible)
    end
end

function wield3d.init(player)
    if pl[player] and pl[player].ent then
        pl[player].ent.object:remove()
    end
    pl[player] = { last_wield = "wield3d:empty" }
    local o = wield3d.get_wield_def("wield3d:empty")
    local obj = minetest.add_entity(player:get_pos(), "wield3d:wield_ENTITY")
    pl[player].ent = obj:get_luaentity()
    en[obj:get_luaentity()] = player
    obj:set_attach(player, o.bone, o.off, o.rot, o.force_visible or wield3d.force_visible)
end

minetest.register_on_joinplayer(wield3d.init)
minetest.register_on_leaveplayer(function(player)
    if pl[player] and pl[player].ent then
        pl[player].ent.object:remove()
    end
end)

minetest.register_globalstep(function(dtime)
    for _, player in pairs(minetest.get_connected_players()) do
        wield3d.update(player)
    end
end)

minetest.register_entity("wield3d:wield_ENTITY", {
    initial_properties = {
        physical = false,
        collisionbox = {-0.125,-0.125,-0.125,
                         0.125, 0.125, 0.125},
        visual = "wielditem",
        textures = { "wield3d:empty"},
        pointable = false,
    },
    on_step = function(self, dtime)
        if not en[self] then
            self.object:remove()
        end
    end,
})
minetest.register_item("wield3d:empty", {
    type = "none",
    wield_image = "blank.png",
})



