function turn_off_lamp(obj_id)
	local obj = get_object_by_id(obj_id)
    if not (obj) then
        return
    end
    if not (obj.get_hanging_lamp) then
        return
    end

	if not hf_obj_manager.get_data(obj_id).is_on then
		obj:get_hanging_lamp():turn_off()
	end
    return true
end

local function get_time_elapsed()
    return game.get_game_time():diffSec(level.get_start_time())
end
gc = game.translate_string
---------------------------------------------------------------------------------------------------
-- Physic objects binding
----------------------------------------------------------------------------------------------------
local lights = {}
local switch = false

local psi_influence_clsid = {

	[clsid.poltergeist_s] = true,
	[clsid.controller_s] = true,
	
}

function need_flicker(lamp_obj)
	
	-- Flicker on Emission Wave or Vortex
	if (level_environment.get_light_flicker()) then return true end
	
	-- Flicker if Psi Mutant nearby
	local psi_influence = false
	local function iterate_func(obj)
		if (obj and psi_influence_clsid[obj:clsid()] and obj:alive()) then 
			psi_influence = true
			return true
		end
	end

	level.iterate_nearest(lamp_obj:position(), 15, iterate_func)
	
	if psi_influence then return true end
	
	return switch
end

function init(obj)
    obj:bind_object(placeable_light_wrapper(obj).binder)
end

---------------------------------------------------------------------------------------------
class "placeable_light_wrapper" (bind_hf_base.hf_binder_wrapper)
function placeable_light_wrapper:__init(obj) super(obj)

	lights[obj:id()] = "light_flicker"

	-- Get paths to sound files
	local section = self.object:section()
	self.humming_snd_path = ini_sys:r_string_ex(section,"snd_on")
	self.turn_on_snd_path = ini_sys:r_string_ex(section,"snd_turn_on")
	self.turn_off_snd_path = ini_sys:r_string_ex(section,"snd_turn_off")
	self.particle_path = ini_sys:r_string_ex(section,"particle")
	self.hide_bone_off = ini_sys:r_string_ex(section,"hide_bone_off")
	
	if self.particle_path then
		self.particles = particles_object(self.particle_path)
	end
	
	self.object:set_tip_text(gc("st_interact"))
	
	
	self.tg = time_global()
	
	self.time_last = get_time_elapsed() -- used to keep track of time difference in between updates
	self.max_duration = ini_sys:r_string_ex(section,"fuel_duration")*3600
	
	-- get data
	local data = hf_obj_manager.get_data(obj:id())
	
	self.fuel = data and data.condition or 1
	self.infinite_fuel = data and data.is_world_obj
	self.last_state = data and data.is_on or false

	-- Turn off lamp is light is turned off
	CreateTimeEvent("hf_light", "turn_off_"..obj:id(), 0, turn_off_lamp, obj:id())
end

function placeable_light_wrapper:update(delta)
	bind_hf_base.hf_binder_wrapper.update(self, delta)
	self.object:set_callback(callback.death, placeable_light_wrapper.death_callback, self)
	
	local lamp_obj = self.object:get_hanging_lamp()
	
	local is_flickering = lamp_obj:is_flickering()
	local is_on = hf_obj_manager.get_data(self.object:id()).is_on
	if (self.fuel <= 0.0 or not is_on) then
		if lamp_obj:is_on() then lamp_obj:turn_off() end
	else
		if not lamp_obj:is_on() then
			 lamp_obj:turn_on()
		end
	end
	
	if (self.last_state ~= is_on) then
	
		-- Play humming sound
		if (is_on) then
			if (self.humming == nil and self.humming_snd_path) then
				self.humming = sound_object(self.humming_snd_path)
			end
			if (self.humming ~= nil and not self.humming:playing()) then
		
				self.humming:play_at_pos(self.object, self.object:position(), 0, sound_object.s3d + sound_object.looped)
				self.humming.volume = 0.0
				self.humming_max = time_global() + 5000
			end
			-- 'Turn on' sound
			if self.turn_on_snd_path then
				sound_object(self.turn_on_snd_path):play_no_feedback(self.object, sound_object.s3d, 0, self.object:position(), math.random(5,8), random_float(0.9, 1.1))
			end

			-- Show bone when on
			if self.hide_bone_off then
				self.object:set_bone_visible(self.hide_bone_off, true, true, false)
			end
		
		-- Stop humming sound
		else
			if (self.humming ~= nil and self.humming:playing()) then
				self.humming:stop()
			end
			-- 'Turn off' sound
			if self.turn_off_snd_path then
				sound_object(self.turn_off_snd_path):play_no_feedback(self.object, sound_object.s3d, 0, self.object:position(), random_float(0.5, 0.9), random_float(0.9, 1.1))
			end

			-- Hide bone when off
			if self.hide_bone_off then
				self.object:set_bone_visible(self.hide_bone_off, false, true, false)
			end
		end
	end
	
	self.last_state = is_on
	
	-- Slow Startup for Humming Sound
	if (self.humming ~= nil and self.humming:playing() and (self.humming_max > time_global())) then
		self.humming.volume = 0.6 - (self.humming_max - time_global()) / 5000.0
	end
	
	local needflicker = need_flicker(self.object)
	
	if (needflicker and not is_flickering) then
		--							color animator			 flicker	on/off chance	on/off base time		 color animator fps
		lamp_obj:set_color_animator(lights[self.object:id()], true, math.random(25,75), random_float(0.75,1.75), math.random(10,20))
	elseif (not needflicker and is_flickering) then
		lamp_obj:reset_color_animator()
	end


	if (self.humming ~= nil and self.humming:playing()) then
		self.humming:set_position(self.object:position())
	end
	
	local time_current = get_time_elapsed()
	local time_diff = time_current - self.time_last
	if is_on then
		-- Create and move particles to bone_light
		if self.particle_path then
			if not self.particles:playing() then
				self.particles:play_at_pos(self.object:bone_position("bone_light"))
			end
			self.particles:move_to(self.object:bone_position("bone_light"), VEC_Z)
		end
		
		-- Deplete light fuel by adjusting condition
		if not self.infinite_fuel then
		self.fuel = self.fuel - (time_diff / self.max_duration)
		end
	else
		-- Stop particles if turned off
		if self.particles and self.particles:playing() then
			self.particles:stop()
		end
	end

	self.time_last = time_current
	self:save_data()
end

function placeable_light_wrapper:net_destroy()
	self:save_data()
	
	if (self.humming) then
		self.humming:stop()
		self.humming = nil
	end
	
	if self.particles and self.particles:playing() then
		self.particles:stop()
	end

	lights[self.object:id()] = nil

end

function placeable_light_wrapper:death_callback(victim, who)
	if (self.humming) then
		self.humming:stop()
		self.humming = nil
	end
	
	lights[self.object:id()] = nil
end

function placeable_light_wrapper:save_data()
	hf_obj_manager.update_data(self.object:id(), {
		condition = self.fuel
	})
end