:NAME turret_behavior

:VAR int32		state
:VAR float32	state_time
:VAR float32	state_dt
:VAR float32	delay
:VAR float32	aim_delay

:CONFIG angle32		min_angle
:CONFIG angle32		max_angle

:PARAM float32			undeploy_delay
:PARAM s_function1d		deploy_function
:PARAM s_function1d		barrel1_function
:PARAM s_function1d		barrel2_function

:PARAM s_function1d		undeploy_function
:PARAM s_function1d		barrel1_undeploy_function
:PARAM s_function1d		barrel2_undeploy_function


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

local vectorlib = require "scripts/vector_math"

k_deploy_delay_per_distance= 0.1

k_inactive= 0
k_deploying= 1
k_active= 3
k_undeploying= 4

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

function var_initialize(v)
	v.state= k_inactive
	v.state_time= 0
	v.delay= -1
	v.aim_delay= -1
	v.state_dt= 0
end

function config_initialize(c)
	c.min_angle= -0.5*math.pi		-- +/- 90 degrees
	c.max_angle= 0.5*math.pi
end

function param_initialize(p)
	p.undeploy_delay= 5
end

-- --------------- code ---------------

function deploy()
	var.state= k_deploying
	var.state_time= world_state_get().time.time	
	var.state_dt= 0
	var.delay= math.max(param.deploy_function.input_range_max, math.max(param.barrel1_function.input_range_max, param.barrel2_function.input_range_max))	
	var.aim_delay= param.deploy_function.input_range_max
end

function activate(object)
	var.state= k_active
	var.state_time= world_state_get().time.time
	var.state_dt= 0
	var.delay= param.undeploy_delay
	
	local shooting= object._c.shoot_control
	if (shooting) then
		shooting.disabled= false
	end

end

function undeploy(object)
	var.state= k_undeploying
	var.state_time= world_state_get().time.time
	var.state_dt= 0
	var.delay= math.max(param.undeploy_function.input_range_max, math.max(param.barrel1_undeploy_function.input_range_max, param.barrel2_undeploy_function.input_range_max))	

	local shooting= object._c.shoot_control
	if (shooting) then
		shooting.disabled= true
	end

end

function inactivate()
	var.state= k_inactive
	var.state_time= world_state_get().time.time
	var.state_dt= 0
	var.delay= -1
end


-- --------------- animation ---------------

function deploy_animate(object, t)

	local turret_animation= object.turret_animation_get()
	if (turret_animation) then

		turret_animation.center_x= param.deploy_function.evaluate(t)
		turret_animation.barrel1_x= param.barrel1_function.evaluate(t)
		turret_animation.barrel2_x= param.barrel2_function.evaluate(t)

	end
end

function undeploy_animate(object, t)

	local turret_animation= object.turret_animation_get()
	if (turret_animation) then

		turret_animation.center_x= param.undeploy_function.evaluate(t)
		turret_animation.barrel1_x= param.barrel1_undeploy_function.evaluate(t)
		turret_animation.barrel2_x= param.barrel2_undeploy_function.evaluate(t)

	end
end

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


function attach(object)
	local aim= object.aim_get()
	if (aim) then
		aim.set_angle(object.transform.rotation + math.pi)
	end
	
	deploy_animate(object, 0)
	
	local shooting= object._c.shoot_control
	if (shooting) then
		shooting.disabled= true
	end
	
	-- pass my config information about min and max sweep angle on to my turret aim component
	local turret_aim= object.turret_aim_get()
	if (turret_aim) then
		turret_aim.min_angle= config.min_angle
		turret_aim.max_angle= config.max_angle
	end
end

function update(object)

	local perception= object.perception_get()
	local control= object.control_get()
	local turret_aim= object.turret_aim_get()
	
	if (turret_aim and turret_aim.frozen) then
		-- do nothing?
	elseif (control and perception and turret_aim) then
		local target= perception.get_target()
		local delta_t= world_state_get().time.delta_t()			
		var.state_dt = var.state_dt + delta_t
		
		turret_aim.aim_on_target= false
		
		if (var.state == k_active) then
		
			if (not target) then
				undeploy(object)
			else
				turret_aim.aim_on_target= true

				if (path) then
					path.move_to_target(target)
				end

				if (target.is_immediate() or target.is_making_sound()) then
					var.delay= param.undeploy_delay
				else
					var.delay = var.delay - delta_t
					if (var.delay <= 0) then
						undeploy(object)
					end
				end
			end

		elseif (var.state == k_deploying) then
		
			--local ws= world_state_get()
			--local time= ws.time.time
			--local delta_t= ws.time.delta_t()

			local path= object.path_get()
			if (path and target) then
				path.move_to_target(target)
			end
			
			--local dt= time - var.state_time
			deploy_animate(object, var.state_dt)
			
			var.delay = var.delay - delta_t
			if (var.delay <= 0) then
				activate(object)
			end
			
			if (var.aim_delay <= 0) then
				turret_aim.aim_on_target= true
			else
				var.aim_delay = var.aim_delay - delta_t
			end
		
		elseif (var.state == k_inactive) then

			if (var.delay > 0) then
				--local delta_t= world_state_get().time.delta_t()
				var.delay = var.delay - delta_t
				if (var.delay <= 0) then
					deploy()
				end

			elseif (target and target.is_targetable() and (target.is_making_sound() or target.is_immediate())) then
				local point= object.world_position_get()
				local distance= vectorlib.distance2d(target.location.point, point)
				var.delay= distance*k_deploy_delay_per_distance
			end

		elseif (var.state == k_undeploying) then

			--local ws= world_state_get()		
			--local dt= ws.time.time - var.state_time
			undeploy_animate(object, var.state_dt)
		
			if (var.delay > 0) then
				--local delta_t= ws.time.delta_t()
				var.delay = var.delay - delta_t
				if (var.delay <= 0) then
					inactivate()
				end
			end
		end
		
	end
end

component_register(attach, update, nil, nil)
