using UnityEngine;

public class MonsterAI : MonoBehaviour 
{
    public float WakeUpTime;
    public float SearchDoneAtDistance = -1;

    public Transform SpotFlash;
    public Transform LostFlash;

    private Transform target;
    private Vector2 searchLocation;

    private enum AIState
    {
        Lurking,
        FindingTarget,
        Chasing,
        Searching,
        Eating
    }
    private AIState state;

    private AggroTrigger aggro;

    void Start()
    {
        aggro = GetComponent<AggroTrigger>();
        state = AIState.Lurking;
	}

    public void Eat(Transform t)
    {
        transform.position = t.position;        
        EnterState(AIState.Eating);
    }

    public void FinishEating()
    {
        EnterState(AIState.FindingTarget);
    }
	
	void Update ()
    {
        if (Exit.ExitClosed)
        {
            transform.SendMessage("Stop");
            return;
        }

        switch (state)
        {
            case AIState.Lurking:
                if (aggro.Triggered && (Time.time - aggro.TriggeredTime) > WakeUpTime)
                    EnterState(AIState.FindingTarget);
                break;

            case AIState.FindingTarget:
                target = AIUtil.NearestVisibleHuman(transform.position);
                if (target != null)
                    EnterState(AIState.Chasing);
                break;

            case AIState.Chasing:
                if (LostLineOfSight())
                    target = null;

                if (target == null)
                {
                    EnterState(AIState.Searching);
                }
                else
                {
                    searchLocation = target.position;
                    transform.SendMessage("Attack", target);
                }
                break;

            case AIState.Searching:
                if (DoneWithSearch())
                {
                    transform.SendMessage("Stop");
                    EnterState(AIState.FindingTarget);
                }
                else
                {
                    transform.SendMessage("Search", searchLocation);
                }
                break;
        }
    }

    private bool DoneWithSearch()
    {
        if (SearchDoneAtDistance == -1)
            return true;

        return (searchLocation - (Vector2)transform.position).magnitude < SearchDoneAtDistance;
    }

    private bool LostLineOfSight()
    {
        return !AIUtil.HasLoS(transform.position, target.position);
    }

    private void EnterState(AIState newstate)
    {
        Debug.Log(name + " AI state transition from " + state + " to " + newstate);
        AIState oldstate = state;
        state = newstate;

        if (state == AIState.Chasing && SpotFlash != null)
            Instantiate(SpotFlash, transform.position + Vector3.up, transform.rotation);
        else if (state == AIState.FindingTarget && oldstate == AIState.Searching && LostFlash != null)
            Instantiate(LostFlash, transform.position + Vector3.up, transform.rotation);
        else if(state == AIState.Eating)
            transform.SendMessage("Stop");
    }
}
