namespace BP
{
	namespace Controller
	{
		const float AIM_MAX             = GAME_SCALE * 100.0f;
		const float AIM_MIN             = GAME_SCALE * 20.0f;
		const float AIM_RANGE           = AIM_MAX - AIM_MIN;

		const float AIM_BLEND_MAX       = 0.9f;
		const float AIM_BLEND_MIN       = 0.04f;
		const float AIM_BLEND_RANGE     = AIM_BLEND_MAX - AIM_BLEND_MIN;
		
		class QuadMissileLauncher : ScriptObject
		{
			kActor@ self;
			//------------------------------------------------------------------------------------------------------------------------
			QuadMissileLauncher(kActor@ actor)
			{
				@self = actor;
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnTick(void)
			{
				if (self.GetTarget() is null)
				{
					self.Remove();
					return;
				}
				
				kParticle@ pParticle = self.GetTarget().CastToParticle();
				if (pParticle is null)
				{
					self.Remove();
					return;
				}
				
				if (pParticle.IsStale() || (pParticle.GetTarget() is null))
				{
					self.Remove();
					return;
				}
				
				kActor@ pTarget = pParticle.GetTarget();
				if (pTarget.WorldComponent() is null)
				{
					self.Remove();
					return;
				}
				
				// get destination
				kVec3 vTargetPos = pTarget.Origin();
				vTargetPos.z += pTarget.WorldComponent().HeightOffset();
				vTargetPos.z += pTarget.WorldComponent().Height() * 0.5f;

				// if the missile is close enough to the target, then snap it's
				// origin to the target's origin
				float dist = vTargetPos.Distance(pParticle.Origin());
				if (dist <= GAME_SCALE * 5.0f)
				{
					pParticle.Origin() = pTarget.Origin();
					return;
				}
				
				// get aim vector
				kVec3 vAim = vTargetPos - pParticle.Origin();
				vAim.Normalize();

				float speed = pParticle.Velocity().Unit();
				float blend = 0.0f;

				// determine how much to interpolate
				if(dist <= AIM_MAX)
				{
					blend = Math::Max(0.0f, dist - AIM_MIN) / AIM_RANGE;
					blend = AIM_BLEND_MAX - (blend * AIM_BLEND_RANGE);
				}
				else
				{
					blend = AIM_BLEND_MIN;
				}

				// interpolate direction and change velocity
				pParticle.Direction().Lerp(vAim, blend);
				pParticle.Velocity() = (pParticle.Direction() * speed);
			}
			//------------------------------------------------------------------------------------------------------------------------
		};
	}
}
