#pragma strict

enum EAIState
{
	Patrol,
	Attack,
};

var Waypoints : GameObject[];
var TargetWaypoint : int = 0;
var BeginStopTime : float = 3;
var EndStopTime : float = 3;
var PatrolDirection : boolean = true;
var State : EAIState = EAIState.Patrol;

private var PlayerCmpt : Player;

private var PatrolTimeout : float = 0;
private var VisTime : float = 0;
private var MoveDirTimeout : float = 0;
private var ShootActTimeout : float = 0;
private var ShootWaitTimeout : float = 0;
private var AlertTimeout : float = 0;
private var PlayerPos : Vector3;
private var OtherPlayerCmpt : Player;

function Start()
{
	PlayerCmpt = GetComponent(Player);
}

function UpdatePlayerVisibility()
{
	for( var obj : GameObject in GameObject.FindGameObjectsWithTag( "Player" ) )
	{
		var pos : Vector3 = obj.transform.position;
		var mtx : Matrix4x4 = Matrix4x4.TRS( transform.position, transform.rotation, Vector3(1,1,1) ).inverse;
		var localPos : Vector3 = mtx.MultiplyPoint( pos );
		localPos.x /= localPos.z * 2;
		localPos.y /= localPos.z * 2;
		var q : float = 0.5;
		var see : boolean =
			localPos.x > -q && localPos.x < q &&
			localPos.y > -q && localPos.y < q &&
			localPos.z > 0.01 && localPos.z < 5
		;
		
		if( see )
		{
			var rcd = pos - transform.position;
			see = !Physics.Raycast( transform.position, rcd.normalized, rcd.magnitude );
			if( see )
			{
				PlayerPos = pos;
				OtherPlayerCmpt = obj.GetComponent(Player);
				if( State == EAIState.Attack )
				{
					AlertTimeout = 5.0;
					obj.SendMessage( "AlertTrigger" );
				}
			}
		}
		VisTime = Mathf.MoveTowards( VisTime, see ? 1 : 0, Time.deltaTime * 0.8 );
		if( VisTime == 1 && State != EAIState.Attack )
		{
			State = EAIState.Attack;
			ShootWaitTimeout = 0.5;
			AlertTimeout = 5.0;
			obj.SendMessage( "AlertTrigger" );
		}
	}
}

function Update()
{
	if( PlayerCmpt.State == EPlayerState.Dead )
		return;
	
	UpdatePlayerVisibility();
	
	if( State == EAIState.Patrol )
	{
		PlayerCmpt.I_Walk = true;
		PlayerCmpt.I_Fire = false;
		
		if( PatrolTimeout > 0 )
		{
			PatrolTimeout -= Time.deltaTime;
			PlayerCmpt.I_MoveDir = Vector2(0,0);
		}
		else
		{
			if( TargetWaypoint < 0 ) TargetWaypoint = 0;
			if( TargetWaypoint > Waypoints.Length ) TargetWaypoint = Waypoints.Length;
			
			var wpt : Transform = Waypoints[ TargetWaypoint ].transform;
			var mypos : Vector3 = transform.position;
			var target : Vector3 = wpt.position;
			PlayerCmpt.I_MoveDir = Vector2( target.x - mypos.x, target.z - mypos.z );
			if( Mathf.Abs( PlayerCmpt.I_MoveDir.x / wpt.localScale.x ) < 1 && Mathf.Abs( PlayerCmpt.I_MoveDir.y / wpt.localScale.z ) < 1 )
			{
				if( PatrolDirection )
				{
					if( TargetWaypoint == Waypoints.Length - 1 )
					{
						PatrolDirection = !PatrolDirection;
						PatrolTimeout = EndStopTime;
					}
					else
						TargetWaypoint++;
				}
				else
				{
					if( TargetWaypoint == 0 )
					{
						PatrolDirection = !PatrolDirection;
						PatrolTimeout = BeginStopTime;
					}
					else
						TargetWaypoint--;
				}
			}
		}
	}
	else if( State == EAIState.Attack )
	{
		AlertTimeout -= Time.deltaTime;
		PlayerCmpt.I_Walk = false;
		if( AlertTimeout <= 0 )
		{
			State = EAIState.Patrol;
		}
		if( ShootActTimeout > 0 )
		{
			ShootActTimeout -= Time.deltaTime;
			OtherPlayerCmpt.BulletHit();
			if( ShootActTimeout <= 0 )
				ShootWaitTimeout = 0.5;
			PlayerCmpt.I_Fire = VisTime == 1;
		}
		if( ShootWaitTimeout > 0 )
		{
			PlayerCmpt.I_Fire = false;
			ShootWaitTimeout -= Time.deltaTime;
			if( ShootWaitTimeout <= 0 )
				ShootActTimeout = 0.9;
		}
		if( MoveDirTimeout > 0 )
		{
			MoveDirTimeout -= Time.deltaTime;
			PlayerCmpt.I_MoveDir = Vector2(0,0);
		}
		else
		{
			MoveDirTimeout = 0.05;
			PlayerCmpt.I_MoveDir = Vector2( PlayerPos.x - transform.position.x, PlayerPos.z - transform.position.z );
		}
	}
}

