
local time_to_live = tonumber(minetest.settings:get("item_entity_ttl")) or 900

aom_item_entity.LISTEN("get_custom_params", function(self)
    local stack = ItemStack(self.itemstring)
    local def = minetest.registered_items[stack:get_name()]
    if def and def._override_item_entity then
        self.object:set_properties(def._override_item_entity)
    end
end)

aom_item_entity.LISTEN("get_properties", function(self, props)
    local stack = ItemStack(self.itemstring)
    local itemname = (stack:is_known() and stack:get_name()) or "unknown"
    local idef = minetest.registered_items[itemname]
    local glow = idef and idef.light_source and math.floor((idef.light_source + 1) / 2)
    local size = aom_item_entity.get(nil, "item_scale", 0.3)
    local bias = 0.001 * math.random() -- avoid flickering
    local float_height = aom_item_entity.get(nil, "item_float_height", 0.3)
    local collisionbox = {-size, -size-float_height+0.05, -size, size, size, size}
    props.collisionbox = collisionbox
    props.visual_size = {x=size, y=size+bias, z=size}
    props.textures = {itemname}
    props.is_visible = true
    props.glow = glow
    props.wield_item = self.itemstring
    props.infotext = stack:get_description() .. "\nCount: " .. tostring(stack:get_count())
end)

aom_item_entity.LISTEN("set_item", function(self, item, ...)
    local stack = ItemStack(item or self.itemstring)
    self.itemstring = stack:to_string()
    if self.itemstring == "" then
        -- could be unknown item
        return
    end
    local props = {}
    aom_item_entity.SIGNAL("get_properties", self, props)
    self.object:set_properties(props)
    self._collisionbox = props.collisionbox
end)

aom_item_entity.LISTEN("set_item", function(self, item, ...)
    aom_item_entity.SIGNAL("get_custom_params", self)
end)

aom_item_entity.LISTEN("on_activate", function(self, staticdata, dtime_s)
    local data = minetest.deserialize(staticdata, true) or {}
    for i, v in ipairs(aom_item_entity.staticdata_load_list) do
        self[v] = data[v]
    end
    self.object:set_armor_groups({immortal = 1})
    self.object:set_velocity({x = 0, y = 0, z = 0})
    aom_item_entity.SIGNAL("set_item", self, self.itemstring)
    aom_item_entity.SIGNAL("on_wake", self)
end)

aom_item_entity.LISTEN("on_step", function(self, dtime, moveresult, ...)
    self.age = self.age + dtime
    if self.itemstring == "" then
        minetest.log("found empty item ent")
        self.object:remove()
        return "_cancel"
    end

    if self.age > time_to_live then
        self.object:remove()
        return "_cancel"
    end
end)


aom_item_entity.LISTEN("pickup_item", function(self, picker, is_punch)
    local oldstack = ItemStack(self.itemstring)
    local leftoverstack

    local changes = false
    local pickupable = (not is_punch) or aom_item_entity.get(picker, "item_punchable", true)
    if pickupable and minetest.is_player(picker) then
        local inv = picker:get_inventory()
        local idef = oldstack:get_definition()
        local on_pickup = idef and idef.on_pickup or minetest.item_pickup
        leftoverstack = on_pickup(ItemStack(self.itemstring), picker, nil, nil)
        local difference = oldstack:get_count() - leftoverstack:get_count()
        if difference ~= 0 then
            changes = true
        end
        local added_stack = ItemStack(oldstack)
        added_stack:set_count(difference)
        -- signal that this has been picked up
        local ret = aom_item_entity.SIGNAL("on_item_picked_up", self, added_stack, picker)
        if ret == "_cancel" then return ret end
    end
    -- if nothing left, delete
    if leftoverstack and leftoverstack:is_empty() then
        self.itemstring = ""
        self.object:remove()
        return "_cancel"
    elseif changes then
        -- otherwise set this to the new stack
        self:set_item(leftoverstack)
    end
end)

aom_item_entity.LISTEN("on_punch", function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage, ...)
    -- just delete empty ones
    if self.itemstring == "" then
        self.object:remove()
        return "_cancel"
    end
    -- don't pickup by projectiles
    if tool_capabilities and tool_capabilities.damage_groups.projectile then
        return
    end
    -- use pickup signal
    return aom_item_entity.SIGNAL("pickup_item", self, puncher, true)
end)

aom_item_entity.LISTEN("get_staticdata", function(self, data)
    for i, v in ipairs(aom_item_entity.staticdata_load_list) do
        data[v] = self[v]
    end
end)
