using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasicEnemy : MonoBehaviour {

	//public vars
	public GameObject[] pathNodes;
	public GlobalEnums.WaveTypes waveType;
	public GlobalEnums.ActivityState currentActivityState;
	public float moveSpeed = 2.5f;
	public GlobalEnums.NodeMovementType nodeMovementType;

	//protected vars
	protected int currentPathNode; //used to track current node in array
	protected Vector2 minChangeNodeDistance = new Vector3(0.5f,0.5f);
	protected bool isAsleep = false;
	protected bool isPaused = false; //used so level "stops"
	//private vars

	#region StartUpdates
	protected void Start ()
	{
		
	}

	protected void FixedUpdate () 
	{
		if (!isPaused) 
		{
			GlobalEnums.WaveTypes pWave = GameObject.FindGameObjectWithTag ("Player").GetComponent<PlayerScript> ().GetCurrentWaveType();

			if (pWave == waveType)
			{
				isAsleep = true;
			} 
			else 
			{
				isAsleep = false;
			}

			Movement ();
		}
	}
	#endregion

	#region Activity
	public void UnPause()
	{
		isPaused = false;
	}


	public void Pause()
	{
		isPaused = true;
		this.GetComponent<Rigidbody2D> ().velocity = Vector2.zero;
	}

	protected void Movement()
	{
		if (isAsleep)
		{
			
		} 
		else if(currentActivityState == GlobalEnums.ActivityState.Alerted || (currentActivityState == GlobalEnums.ActivityState.Cautious && pathNodes.Length <= 0))
		{
			Vector2 playerPos = GameObject.FindGameObjectWithTag ("Player").transform.position;

			this.transform.position = Vector2.MoveTowards (this.transform.position, playerPos, moveSpeed * Time.fixedDeltaTime);

			this.transform.right = new Vector3(playerPos.x, playerPos.y, 0) - this.transform.position;
		}
		else if(currentActivityState == GlobalEnums.ActivityState.Cautious && pathNodes.Length > 0 && nodeMovementType == GlobalEnums.NodeMovementType.Loop) 
		{
			Vector2 nodePos = pathNodes [currentPathNode].transform.position;

			this.transform.position = Vector2.MoveTowards (this.transform.position, nodePos, moveSpeed * Time.fixedDeltaTime);

			this.transform.right = new Vector3(nodePos.x, nodePos.y, 0) - this.transform.position;

			Vector2 distanceFromNode = nodePos - new Vector2(this.transform.position.x, this.transform.position.y);

			if (Mathf.Abs(distanceFromNode.x) < minChangeNodeDistance.x && Mathf.Abs(distanceFromNode.y) < minChangeNodeDistance.y) 
			{
				currentPathNode++;
				if (currentPathNode >= pathNodes.Length)
				{
					currentPathNode = 0;
				}
			}
		}
		else if(currentActivityState == GlobalEnums.ActivityState.Cautious && pathNodes.Length > 0 && nodeMovementType != GlobalEnums.NodeMovementType.Loop) 
		{
			Vector2 nodePos = pathNodes [currentPathNode].transform.position;

			this.transform.position = Vector2.MoveTowards (this.transform.position, nodePos, moveSpeed * Time.fixedDeltaTime);

			this.transform.right = new Vector3(nodePos.x, nodePos.y, 0) - this.transform.position;

			Vector2 distanceFromNode = nodePos - new Vector2(this.transform.position.x, this.transform.position.y);

			if (Mathf.Abs(distanceFromNode.x) < minChangeNodeDistance.x && Mathf.Abs(distanceFromNode.y) < minChangeNodeDistance.y) 
			{
				if (nodeMovementType == GlobalEnums.NodeMovementType.BacktrackF) 
				{
					currentPathNode++;
					if (currentPathNode >= pathNodes.Length)
					{
						currentPathNode--;
						nodeMovementType = GlobalEnums.NodeMovementType.BacktrackB;
					}
				}
				if (nodeMovementType == GlobalEnums.NodeMovementType.BacktrackB) 
				{
					currentPathNode--;
					if (currentPathNode < 0)
					{
						currentPathNode++;
						nodeMovementType = GlobalEnums.NodeMovementType.BacktrackF;
					}
				}
			}
		}
	}
	#endregion

	#region Getters
	//getters
	#endregion

	#region Setters
	void SetNearestNode()
	{
		Vector3 closestDistance = new Vector3(99999,99999,99999);
		int closestNode = -1;
		for (int i = 0; i < pathNodes.Length; i++)
		{
			Vector3 currentDistance = pathNodes [i].transform.position - this.transform.position;

			if (Mathf.Abs(currentDistance.x) + Mathf.Abs(currentDistance.y) < Mathf.Abs(closestDistance.x) + Mathf.Abs(closestDistance.y))
			{
				closestDistance = currentDistance;
				closestNode = i;
			}
		}
		if(closestNode > -1)
			currentPathNode = closestNode;
	}
	#endregion

	#region Collision
	protected void OnCollisionEnter2D(Collision2D col) 
	{
		if(col.gameObject.tag == "Enemy")
		{
			Physics2D.IgnoreCollision (col.gameObject.GetComponent<Collider2D>(), this.GetComponent<Collider2D>());
		}
		if(col.gameObject.tag == "Wall")
		{
			Physics2D.IgnoreCollision (col.gameObject.GetComponent<Collider2D>(), this.GetComponent<Collider2D>());
		}
		if(col.gameObject.tag == "Player") 
		{
			Physics2D.IgnoreCollision (col.gameObject.GetComponent<Collider2D>(), this.GetComponent<Collider2D>());
		}
	}

	protected void OnTriggerEnter2D(Collider2D col)
	{
		if(col.gameObject.tag == "Player") 
		{
			currentActivityState = GlobalEnums.ActivityState.Alerted;
		}
	}

	protected void OnTriggerExit2D(Collider2D col)
	{
		if(col.gameObject.tag == "Player") 
		{
			SetNearestNode ();
			currentActivityState = GlobalEnums.ActivityState.Cautious;
		}
	}
	#endregion

	#region Misc
	void OnDrawGizmosSelected()
	{
		if (waveType == GlobalEnums.WaveTypes.Sin) {
			Gizmos.color = Color.red;
		}
		else if (waveType == GlobalEnums.WaveTypes.Square) {
			Gizmos.color = Color.yellow;
		}
		else if (waveType == GlobalEnums.WaveTypes.Triangle) {
			Gizmos.color = Color.blue;
		}

		if (nodeMovementType == GlobalEnums.NodeMovementType.Loop) 
		{
			for (int i = 0; i < pathNodes.Length; i++)
			{
				if (i < pathNodes.Length - 1) 
				{
					Gizmos.DrawLine (pathNodes [i].transform.position, pathNodes [i + 1].transform.position);
				} else if (i >= pathNodes.Length - 1)
				{
					Gizmos.DrawLine (pathNodes [i].transform.position, pathNodes [0].transform.position);
				}
			}
		}
		else if (nodeMovementType != GlobalEnums.NodeMovementType.Loop) 
		{
			for (int i = 0; i < pathNodes.Length - 1; i++)
			{
				if (i <= pathNodes.Length - 2) 
				{
					Gizmos.DrawLine (pathNodes [i].transform.position, pathNodes [i + 1].transform.position);
				}
			}
			for (int i = pathNodes.Length - 1; i >= 1; i--)
			{
				if (i >= 1) 
				{
					Gizmos.DrawLine (pathNodes [i].transform.position, pathNodes [i - 1].transform.position);
				}
			}
		}
	}
	#endregion

}
