local ns = artifact

local chests = {}

minetest.register_entity(":artifact:chest_slot", {
    initial_properties = {
        static_save = false,
        visual = "mesh",
        mesh = "artifact_animator.gltf",
        selectionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}
    },
    _interact_time = 0.25,
    on_activate = function(e, item)
        e._visual = minetest.add_entity(e.object:get_pos(), "display")
        e._visual:set_properties {
            visual = "item",
            wield_item = item,
            pointable = false
        }
        e._visual:set_attach(e.object, "root")
        --  That's _one_ way to get a unique ID...
        e._name = ""..math.random()
    end,
    on_deactivate = function(e)
        e._visual:remove()
    end,
    on_hover = function(e, m)
        e.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.15, 0.15, 0.15), interpolation = 0.2, absolute = true
            },
            position = {
                vec = vector.new(0, 0.01, 0), interpolation = 0.2, absolute = true
            }
        })
    end,
    on_unhover = function(e, m)
        e.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.2, absolute = true
            },
            position = {
                vec = vector.new(0, 0.01, 0), interpolation = 0.2, absolute = true
            }
        })
    end
})

minetest.register_entity(":artifact:chest_display", {
    initial_properties = {
        visual = "mesh",
        mesh = "artifact_chest.gltf",
        textures = {"artifact_chest_wood.png"},
    },
    _interact_time = 0.6,
    _interact_marker_offset = function(e)
        return vector.new(0, 0, 0.5):rotate(e.object:get_rotation())
    end,
    on_activate = function(e, data)
        if not minetest.get_node(e.object:get_pos()).name:find "chest" then
            e.object:remove()
            return
        end
        e.object:set_armor_groups{immortal = 1}
        e._pos = minetest.deserialize(data)
        chests[vector.to_string(e._pos)] = e
    end,
    on_deactivate = function(e)
        chests[vector.to_string(e._pos)] = nil
    end,
    get_staticdata = function(e)
        return minetest.serialize(e._pos)
    end,
    on_interact = function(e)
        e:open()
    end,
    on_step = function(e)
        if e._open then
            local found = false
            for obj in minetest.objects_inside_radius(e.object:get_pos(), 5) do
                if minetest.is_player(obj) then
                    found = true
                    break
                end
            end
            if not found then
                e:close()
            end
        end
    end,
    open = function(e)
        e._open = true
        e._no_interact = true
        e.object:set_properties{pointable = false}
        e.object:set_animation({x=0,y=0.5}, 1, 0.1, false)
        local pos = e.object:get_pos()
        local rot = e.object:get_rotation()
        e._slot_main = minetest.add_entity(pos +vector.new(0.2, 0.1, 0):rotate(rot), "artifact:chest_slot", "artifact:stone"):get_luaentity()
        e._slot_main.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.01, 0.01, 0.01), absolute = true
            },
            position = {
                vec = vector.new(0, -5, 0), absolute = true
            }
        })
        minetest.after(0, function()
        e._slot_main.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.4, absolute = true
            },
            position = {
                vec = vector.new(0, 0.01, 0), interpolation = 0.4, absolute = true
            }
        })
        end)
        e._slot_main.master = e
        e._slot_main.on_interact = function()
            
        end
        e._slot_cancel = minetest.add_entity(pos +vector.new(-0.2, 0.1, 0):rotate(rot), "artifact:chest_slot", "artifact:cancel"):get_luaentity()
        e._slot_cancel.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.01, 0.01, 0.01), absolute = true
            },
            position = {
                vec = vector.new(0, -5, 0), absolute = true
            }
        })
        minetest.after(0, function()
        e._slot_cancel.object:set_bone_override("root", {
            scale = {
                vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.4, absolute = true
            },
            position = {
                vec = vector.new(0, 0.01, 0), interpolation = 0.4, absolute = true
            }
        })
        end)
        e._slot_cancel.master = e
        e._slot_cancel.on_interact = function()
            e:close()
        end
    end,
    close = function(e)
        e._open = false
        e._no_interact = nil
        e.object:set_properties{pointable = true}
        e.object:set_animation({x=0.5,y=1}, 1, 0.1, false)
        e._slot_main.object:remove()
        e._slot_cancel.object:remove()
    end
})

artifact.register_node("chest", {
    drawtype = "airlike",
    paramtype = "light",
    paramtype2 = "facedir",
    pointable = false,
    groups = {call_on_load = 1},
    on_construct = function(pos)
        local m = minetest.get_meta(pos)
        m:set_string("initialized", "true")
        local rot = minetest.facedir_to_dir(minetest.get_node(pos).param2):dir_to_rotation()
        rot.y = rot.y -math.pi
        minetest.add_entity(pos, "artifact:chest_display", minetest.serialize(pos)):set_rotation(rot)
    end,
    on_destruct = function(pos)
        chests[pos:to_string()].object:remove()
        chests[pos:to_string()] = nil
    end,
    on_load = function(pos)
        local m = minetest.get_meta(pos)
        -- Dynamically initialize chests that were mapgen'd in.
        if not m:contains("initialized") then
            m:set_string("initialized", "true")
            local rot = minetest.facedir_to_dir(minetest.get_node(pos).param2):dir_to_rotation()
            rot.y = rot.y -math.pi
            minetest.add_entity(pos, "artifact:chest_display", minetest.serialize(pos)):set_rotation(rot)
        end
    end
})
