:NAME noise_maker


:PARAM float32						start_delay
:PARAM s_ping_effect@				ping
:PARAM s_ping_effect@				recurring_ping
:PARAM s_function1d					sound_function

:VAR boolean started
:VAR boolean disabled
:VAR float32 start_time
:VAR float32 time

:GLOBAL int16 active_count
:GLOBAL boolean loop_started
:GLOBAL c_sound* start_sound
:GLOBAL c_sound* loop_sound


-- ------------------- globals ------------------- 

k_impulse_scale= 175

-- ------------------- initialization ------------------- 

function param_initialize(p)
--	print("noise_maker param_initialize")
	p.start_delay= 5
end

function var_initialize(v)
--	print("noise_maker var_initialize")
	v.started= false
	v.disabled= false
	v.start_time= 0
	v.time= 0
end

function global_initialize(g)
	g.active_count= 0
	g.start_sound= nil
	g.loop_sound= nil
	g.loop_started= false
end

-- ------------------- component ------------------- 

k_bar_width= 1
k_bar_height= 0.25
k_y_offset= 0.4

k_bar_color= {}
k_bar_color.red= 0.85		-- 0
k_bar_color.blue= 0			-- 1 
k_bar_color.green= 0.17		-- 0

k_empty_color={}
k_empty_color.red= 0.0		-- 0.6 
k_empty_color.blue= 0.0		-- 0.6
k_empty_color.green= 0.0	-- 0.6

function still_running() -- CB_HACK: fix this?
	if(var.started) then
		return var.disabled
	else
		return false
	end
end

function draw_timer(object, time)
	local base_point= object.world_position_get()

	base_point.x = base_point.x - k_bar_width/2
	base_point.y = base_point.y + k_y_offset
	
	local top_left= {}
	top_left.x= base_point.x
	top_left.y= base_point.y + k_bar_height
	
	local end_point= {}
	end_point.x = base_point.x + k_bar_width
	end_point.y = base_point.y
	
	-- args: plate, top-left, bottom-right, color, fill

	render_rectangle(object.plate, top_left, end_point, k_empty_color, true)

	local fraction= 1 - (time - object.placement_time)/param.start_delay
	end_point.x = base_point.x + fraction*k_bar_width
	
	render_rectangle(object.plate, top_left, end_point, k_bar_color, true)

end

function attach(object)

	local sound= object.sound_get()
	if (sound) then
		sound.play_sound("drop", false)
	end
	
	local ws= world_state_get()
	local player= ws.primary_player_get()

	local gear_manager= ws.global_script("gear_manager")
	if (gear_manager and gear_manager.player_proxy) then
		player= gear_manager.player_proxy
	end

	local player_path= nil 
	local throw= true
	
	if (player) then
		player_path= player.path_get()
	end
	
	-- find a direction
	if (player_path and player_path.path_active()) then
		local d= player_path.distance_left()
		if (d > 0.75) then
			throw= false
		end
	end

	if (player and throw) then
		-- impulse myself in the forward direction
		local forward_vector= player.forward_vector_get()
		local physics= object.physics_model
		if (physics) then
			physics.impulse(k_impulse_scale*forward_vector.x, k_impulse_scale*forward_vector.y)
		end
			
	end
	
end

function sound_start(object, time)
	var.started= true
	var.start_time= time
	
	global.active_count = global.active_count + 1
	
	if (global.active_count==1) then
		local sound= object.sound_get()
		if (sound) then
			global.start_sound= sound.play_sound("start", false)
		end
	end
end

function sound_update(object)
	if (not global.loop_started) then
		if (global.start_sound and global.start_sound.is_playing()) then
			-- wait for this to end
		else
			local sound= object.sound_get()
			if (sound) then
				global.loop_sound= sound.play_sound("loop", true)
			end
			global.loop_started= true
		end
	end
end

function sound_end(object)
	global.active_count= global.active_count - 1
	
	if (global.active_count==0) then
		-- actually end the sound
		
		if (global.loop_sound and global.loop_sound.is_playing()) then
			global.loop_sound.stop()
		end
		
		local sound= object.sound_get()
		if (sound) then
			sound.play_sound("end", false)
		end

		global.loop_started= false
	end
end

function disable(object)
	var.disabled= true
	sound_end(object)
end

function update(object)

	if (not var.disabled) then
		local ws= world_state_get()
		local time= ws.time.time
		
		if (not var.started) then
			if ((time - object.placement_time) > param.start_delay) then
				sound_start(object, time)
			end
			
			draw_timer(object, time)
		end
		
		if (var.started) then

			local t= var.time
			if (t > param.sound_function.input_range_max) then
				t= 0
			end
			
			sound_update(object)
			
			local player_iterator= ws.component_cache.component_player.iterator_get()
			while (true) do
				local player= player_iterator.next()
				if (player) then
					local player_object= player.object
					local target= player_object.target_get()
					if (target and target.is_targetable() and target.is_immediate()) then
						-- a player target is visible -- disable myself
						disable(object)
					end
				else
					break
				end
			end
			
			if (not var.disabled) then
				local value= param.sound_function.evaluate(t)
				local player= ws.player[0]
				if (player) then
					local target= player.target_get()
					if (target) then
						local point= object.world_position_get()
						target.make_sound_at_point(point.x, point.y, value, false)
						if(time == var.start_time) then
							--print("CB: First time a noisemaker is going off, so make a big bang")
							target.make_sound_at_point(point.x, point.y, 1, true)
						end
					end
				end
			end

			if (var.start_time == time or t==0) then
				local noisemaker_target= object.target_get()
				if (noisemaker_target and noisemaker_target.distance_map.valid()) then
					if (var.start_time == time and param.ping) then
						noisemaker_target.distance_map.ping(param.ping)
					elseif (t==0 and param.recurring_ping) then
						noisemaker_target.distance_map.ping(param.recurring_ping)
					end					
				end
			end
			
			var.time = t + ws.time.delta_t()
		end
		
		local mytarget= object.target_get()
		if (mytarget and mytarget.is_immediate()) then
			-- I am currently visible to someone. Disable myself
			disable(object)				
		end
	end
end

component_register(attach, update, nil, nil)
