using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class BaseCharacterController : MonoBehaviour {

    public Transform spawnPoint;
    public BaseCharacterController friend; 
    WaveGenerator IntervalScript;
    public AudioSource musicSource;
    public Animator playerAnimator;

    [Space]
    public enum STATE { IDLE = 0, MOVINGLEFT, MOVINGRIGHT, INAIR, DEAD, PAUSED }
    public STATE state = 0;

    private Rigidbody2D rb;

    [Space]
    public AnimationCurve accelerationRate;
    public AnimationCurve jumpRate;
    public AnimationCurve deathLerp;

    [Space]
    [SerializeField]
    private float maxMovementSpeed;
    [SerializeField]
    private float maxJumpHeight;
    [SerializeField]
    private float jumpSpeed;
    [SerializeField]
    private float RaycastLength;
    public LayerMask layerMask;

    private float horizontal;
    private float vertical;

    private float currentJumpVelocity;

    private float acceletationPercent;
    private float jumpPercent;

    public bool Jump;
    private bool canJump = true;

    // Use this for initialization
    void Awake ()
    {
        IntervalScript = GameObject.Find("Wave Generator").GetComponent<WaveGenerator>();
        playerAnimator = GetComponent<Animator>();

        rb = GetComponent<Rigidbody2D>();

        horizontal = 0;
        vertical = 0;
	}

    // Update is called once per frame
    void FixedUpdate()
    {
        if (state != STATE.DEAD)
        {
            if (Jump && jumpPercent < 2.0f)
            {
                jumpPercent += (Time.fixedDeltaTime * jumpSpeed);
            }

            rb.velocity = new Vector2(horizontal * maxMovementSpeed, jumpRate.Evaluate(jumpPercent) * maxJumpHeight);

            RaycastHit2D hit = Physics2D.Raycast(new Vector3(transform.position.x, transform.position.y - (transform.localScale.y / 2), transform.position.z), -Vector2.up, RaycastLength, layerMask);

            if (hit && jumpPercent > 1)
            {
                Jump = false;
                canJump = true;
                jumpPercent = 0;
                state = STATE.IDLE;
            }

            Debug.DrawRay(new Vector3(transform.position.x, transform.position.y - (transform.localScale.y / 2), transform.position.z), -Vector2.up, new Color(1, 0, 0), 0.1f);

            //Player Animation

            //Idle/Booping
            if (state == STATE.IDLE && IntervalScript.hitInterval == true)
            {
                playerAnimator.SetTrigger("SwapOnBeat");
            }

            //Left and Right Walking
            if (state == STATE.MOVINGLEFT || state == STATE.MOVINGRIGHT)
            {
                playerAnimator.SetBool("Walking", true);

                if (state == STATE.MOVINGLEFT)
                {
                    GetComponent<SpriteRenderer>().flipX = true;
                }
                else if (state == STATE.MOVINGRIGHT)
                {
                    GetComponent<SpriteRenderer>().flipX = false;
                }
            }
            else
            {
                playerAnimator.SetBool("Walking", false);
            }

            if (state == STATE.INAIR)
            {
                playerAnimator.SetBool("Jumping", true);
            }
            else
            {
                playerAnimator.SetBool("Jumping", false);
            }

            if(transform.position.y < -200.0f)
            {
                Kill();
            }
        }
    }

    public void Move(float _horizontal, float _vertical)
    {
        if (state != STATE.DEAD)
        {
            horizontal = _horizontal;
            vertical = _vertical;

            if (horizontal > 0)
            {
                if (state < (STATE)3)
                    state = STATE.MOVINGRIGHT;
            }
            else if (horizontal < 0)
            {
                if (state < (STATE)3)
                    state = STATE.MOVINGLEFT;
            }
            else if (state != STATE.INAIR)
            {
                state = STATE.IDLE;
            }
            if (vertical > 0 && canJump)
            {
                Jump = true;
                state = STATE.INAIR;
            }
        }
    }

    void CalculateRayLocations()
    {

    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.gameObject.tag == "Deadly")
        {
            Kill();
        }
    }

    void OnCollisionExit2D(Collision2D other)
    {
        canJump = false;
        if (!Jump)
        {
            Jump = true;
            jumpPercent = 1.55f;

            if (state != STATE.DEAD)
                state = STATE.INAIR;
        }
    }

    public void Kill()
    {
        state = STATE.DEAD;

        GetComponent<Collider2D>().enabled =      false;
        GetComponent<SpriteRenderer>().enabled =  false;
        GetComponent<Rigidbody2D>().isKinematic = true;

        StartCoroutine(Respawn());
    }

    IEnumerator Respawn()
    {
        transform.position = new Vector3(spawnPoint.position.x + 2.0f, spawnPoint.position.y);

        yield return new WaitForSeconds(1.0f);

        friend.transform.position = new Vector3(spawnPoint.position.x - 2.0f, spawnPoint.position.y);

        state = STATE.IDLE;
        GetComponent<Collider2D>().enabled = true;
        GetComponent<SpriteRenderer>().enabled = true;
        GetComponent<Rigidbody2D>().isKinematic = false;
    }
}
