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

enum AIState {

    moveing,
    jumping,
    attacking,
    flying,
    successful,

    
}


public class CatBasicAIBehaviour : MonoBehaviour {

    delegate void AIBehaviour();
    public float gravityScale = 1.0f;

    // Global Gravity doesn't appear in the inspector. Modify it here in the code
    // (or via scripting) to define a different default gravity for all objects.

    static float globalGravity = -9.81f;

    public float speed;
    public float preJumpTime;
    public float preAttakTime;
    public float attackRange;
    // consider depreciate with numeric spring

    public float scaleAmt;

    public bool landed = false;
    public bool Dead = false;

    float stateTimer;

    Rigidbody rb;

    AIState currentState;

    List<AIBehaviour> AIBehaviourList;

    // target
    GameObject activeTarget;

    public GameObject player;
    public GameObject nearestLimb;

    Vector3 origin;

    Animator m_Animator;

    Vector3 distVect ;

    GameObject scoreTracker;

	public AudioSource Cat_Audio;

	public AudioClip[] Cat_Spawn_AudioList;

	public AudioClip[] Cat_Jump_AudioList;


    private void Awake()
    {
        player = GameObject.Find("Main");
        scoreTracker = GameObject.Find("ScoreTracker");


        AIBehaviourList = new List<AIBehaviour>();


        AIBehaviourList.Add(moveingBehaviour);
        AIBehaviourList.Add(jumpingBehaviour);
        AIBehaviourList.Add(attackingBehaviour);
        AIBehaviourList.Add(flyingingBehaviour);
        AIBehaviourList.Add(successfulBehavior);


        currentState = AIState.moveing;
        rb = GetComponent<Rigidbody>();


        m_Animator = gameObject.GetComponentInChildren<Animator>();


    }

    // Use this for initialization
    void Start () {
        distVect = player.transform.position - transform.position;
        distVect.z = 0;
        distVect.y = 0;
        distVect.Normalize();

if ( Cat_Spawn_AudioList != null && Cat_Spawn_AudioList.Length > 0 ) {
		int CheckIndex = Random.Range (0,Cat_Spawn_AudioList.Length - 1);


		Cat_Audio.PlayOneShot(Cat_Spawn_AudioList [CheckIndex]);
}

        
        //Debug.Log("CatBasicAIBehavior");
        //Debug.Log(FindObjectsOfType(typeof(LimbBehaviour)).Length);
        origin = transform.position;
        CalcSetNearestLimb(origin);
    }

    // Update is called once per frame
    void Update () {

        AIBehaviourList[(int)currentState]();


    }

    void CalcSetNearestLimb(Vector3 origin) {
        bool findAliveLimb = true;
        
        var found = FindObjectsOfType(typeof(LimbBehaviour));
        //Debug.Log("Object.FindObjectsOfType(typeof(LimbBehaviour))");
        //Debug.Log(found.Length);
        var sqnear = float.PositiveInfinity;

        foreach (var f in found) {
            var ff = f as LimbBehaviour;
            Debug.DrawLine(origin, ff.transform.position,Color.green,3);
            if (findAliveLimb && ff.currentHealth == 0) continue;
            var sqdist = (ff.transform.position - origin).sqrMagnitude;
            //Debug.Log(ff.gameObject.name);
            //Debug.Log(sqdist);
            if ( sqnear > sqdist) {
                //Debug.Log("new");
                //Debug.Log(ff.gameObject.name);
                nearestLimb = ff.gameObject;
                sqnear = sqdist;
            }
        }
    }
    
    void moveingBehaviour()
    {


        // play move animation

        // move towards activetarget / bed


        transform.position  += (distVect * speed * Time.deltaTime);



    }

    void jumpingBehaviour()
    {
        //stateTimer += Time.deltaTime;
        m_Animator.SetTrigger("Climb");



        //if (stateTimer >= preJumpTime)
        //{
        //    Vector3 distVect = player.transform.position - transform.position ;
        //    distVect.Normalize();
        //    //distVect *= 2.5f;
        //    distVect += new Vector3(0.0f, 5.0f, 0.0f);
        //    rb.AddForce(distVect,ForceMode.Impulse);
        //
        //    transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y + scaleAmt, transform.localScale.z);
        //    currentState = AIState.attacking;
        //
        //}
        //else {
        //    // play prejump squash animation
        //    transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y - scaleAmt * Time.deltaTime, transform.localScale.z );
        //}





    }
    void attackingBehaviour()
    {
        if (landed) {
            // play attack animation
            // end of animation kill self and target -1 hp
            currentState = AIState.successful;

            CalcSetNearestLimb(origin);
            if (nearestLimb) {
                Debug.Log("attackingBehavior");
                var limb = nearestLimb.GetComponent<LimbBehaviour>();
                if (limb) limb.OnAttacked();
            }
        }
    }

    void successfulBehavior() {
        Destroy(gameObject);

    }

    void flyingingBehaviour()
    {
        m_Animator.SetBool("RightButton", false);
    }

    public void OnTriggered(Collider other)
    {
        if(Dead)
        {
            return;
        }
        if (other.tag == "bedTop") {
            currentState = AIState.attacking;
            landed = true;
        }
    }

    public void OnBed()
    {

    }

    void OnTriggerEnter(Collider other) {
        if (other.tag == "bedEdge") {
            currentState = AIState.jumping;
            stateTimer = 0.0f;

        }
    }

    void FixedUpdate()
    {
        Vector3 gravity = globalGravity * gravityScale * Vector3.up;
        //rb.AddForce(gravity, ForceMode.Acceleration);
    }

}



