:NAME clone_gear

:PARAM float32			lifetime
:PARAM float32			too_close_distance
:PARAM s_ping_effect@	creation_ping
:PARAM s_ping_effect@	death_ping

:VAR boolean			creation_ping_pending
:VAR boolean			played_expiring_sound


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

function param_initialize(p)
	p.lifetime= 5
	p.too_close_distance= 1.0
end

function var_initialize(v)
	v.creation_ping_pending= false
	v.played_expiring_sound= false
end

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

k_game_time_mode= e_value("e_time_mode", "_time_mode_game")
k_expiring_time_left= 2.0

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

k_circle_color={}
k_circle_color.red= 0.6
k_circle_color.blue= 0.6
k_circle_color.green= 0.1

k_path_offset= 2

local vectorlib = require "scripts/vector_math"

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


function still_running()
	return true -- CB_HACK: fix this.
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.lifetime
	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 ws= world_state_get()
	local gear_manager= ws.global_script("gear_manager")
	local path= object.path_get()
	local player= ws.primary_player_get()
	local find_direction= true

	-- eugh	
	if (gear_manager.player_proxy) then
		player= gear_manager.player_proxy
	end

	local player_path= player.path_get()
	local player_control= object._c.player_control
	if (player_control) then
		-- HACK: make myself not a pre-condition for successfully beating the level
		player_control.exited= true
	end
	
	-- sound
	local sound= object.sound_get()	
	if (sound) then
		local deploy_sound= sound.get_sound_by_name("deploy")
		if (deploy_sound) then
			deploy_sound.play(k_game_time_mode)
		end
	end
	
	var.creation_ping_pending= (param.creation_ping~=nil)
	
	if (player_path and player_path.path_active()) then
		local d= player_path.distance_left()
		if (d > 0.75) then
			find_direction= false
		end
	end
	
	if (find_direction and path) then
		local arena_state= nil
		local static_arena= world_get().arena
		
		if (static_arena) then
			arena_state= static_arena.arena_state_get()
		end
		
		if (arena_state) then
			local directions= {}
			local success= false
			local forward_vector= object.forward_vector_get()
			local horizontal = true
			local target_point= {}
			
			local position= path.get_origin()
			
			directions[0]= {}
			directions[1]= {}
			directions[2]= {}
			directions[3]= {}
			
			horizontal= (math.abs(forward_vector.x) > math.abs(forward_vector.y))
			
			local hoffset= 0
			local voffset= 0
			
			if (horizontal) then
				voffset= 2
			else
				hoffset= 2
			end
			
			if (forward_vector.x >= 0) then
				directions[hoffset].x= 1
				directions[hoffset+1].x= -1
			else
				directions[hoffset].x= -1
				directions[hoffset+1].x= 1
			end
			directions[hoffset].y= 0
			directions[hoffset+1].y= 0
			
			if (forward_vector.y >= 0) then
				directions[voffset].y= 1
				directions[voffset+1].y= -1
			else
				directions[voffset].y= -1
				directions[voffset+1].y= 1
			end
			directions[voffset].x= 0
			directions[voffset+1].x= 0
			
			for i= 0, 3 do
				target_point.x= position.x + k_path_offset*directions[i].x
				target_point.y= position.y + k_path_offset*directions[i].y
				
				if (arena_state.trace_line(path.definition.path_radius, position.x, position.y, target_point.x, target_point.y)) then
					success= true
					break;				
				end
			end

			if (success) then
				local cell= static_arena.cell_get(target_point.x, target_point.y)
				path.add_step(static_arena, target_point.x, target_point.y, cell.x, cell.y)
			end
		end
	end
end

function delete_clone(object)

	local player_control= object._c.player_control
	if (player_control) then
		if (player_control.rendered_line) then
			object_delete(player_control.rendered_line)
		end
		if (player_control.endpoint) then
			object_delete(player_control.endpoint)
		end
		if (player_control.target) then
			object_delete(player_control.target)
		end
	end

	-- try and do a death ping
	if (param.death_ping) then
		local distance_map= object.distance_map_get()
		if (distance_map) then
			local world_pos= object.world_position_get()
			distance_map.compute_at_point(world_pos.x, world_pos.y)
			distance_map.distance_map.ping(param.death_ping)
		end
	end

	object.delete_all_children()
	object_delete(object)

end

function update(object)

	local ws= world_state_get()
	local time= ws.time.time
	
	if (var.creation_ping_pending and param.creation_ping) then	
		local target= object.target_get()
		if (target) then
			if (not target.is_distance_map_dirty()) then
				target.distance_map.ping(param.creation_ping)
				var.creation_ping_pending= false
			end
		end
	end
	
	local time_lived= time - object.placement_time
	if (time_lived > param.lifetime) then
		-- delete myself after my lifetime is expired
		delete_clone(object)
	else
		-- possible launch the "expiring" sound
		if ((not var.played_expiring_sound) and ((param.lifetime - time_lived) < k_expiring_time_left)) then
			var.played_expiring_sound= true
			local sound= object.sound_get()
			if (sound) then
				local expiring_sound= sound.get_sound_by_name("expiring")
				if (expiring_sound) then
					expiring_sound.play(k_game_time_mode)
				end
			end
		end
	
		-- if I am being target by somebody and they can see me and they're really close, then disappear!
		local object_pos= object.world_position_get()
		local iterator= world_state_get().component_cache.component_perception.iterator_get()
		while (true) do
			local perception= iterator.next()
			if (perception) then
				local target_cache= perception.target_cache
				if (target_cache and target_cache.is_visible() and target_cache.target.target_object==object) then
					local enemy_pos= perception.object.world_position_get()
					if (vectorlib.distance2d(object_pos, enemy_pos) < param.too_close_distance) then
						delete_clone(object)
					end
				end
			else
				break
			end
		end
		
	end
	
	draw_timer(object, time)
end

component_register(attach, update, nil, nil)
