using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {
    public Animator anim;

    public AudioClip chompSFX;
    public AudioClip hurtSFX;

    public Chomper chomp;

    private CharacterController cc;

    private float turnSpeed = 8.0f;

    private Transform m_Cam;                  // A reference to the main camera in the scenes transform
    private Vector3 m_CamForward;

    private float velY = 0.0f;
    private float gravity = 18.0f;
    private float jumpForce = 10.0f;

    private bool grounded = true;

    private float moveSpeed = 10.0f;

    private Vector3 velocity = Vector3.zero;

    public bool canMove = true;

    public bool startSleeping = true;

    private float sleepTimer = 0.0f;

    private float dashing = 0.0f;

    private float dashCooldown = 0.6f;

    private Vector3 dashDir = Vector3.zero;

    private float barkCooldown = 1.5f;
    private float barking = 0.0f;

    private AudioSource audio;

    private float invul = 0.0f;

    private bool ending = false;

    private PlayerStats stats; 

    public void hurt(float amount) {
        if (invul > 0) {
            return;
        }

        audio.PlayOneShot(hurtSFX);
        stats.hurt(amount);
        invul = 1.0f;
        anim.SetTrigger("hurt");
        canMove = false;
    }
    
	// Use this for initialization
	void Start () {
        cc = GetComponent<CharacterController>();
        audio = GetComponent<AudioSource>();
        stats = GetComponent<PlayerStats>();
        
	}

    void Awake() {
        if (startSleeping) {
            sleep();
        }
    }

    void sleep() {
        canMove = false;
        CameraFollow cf = FindObjectOfType<CameraFollow>();
        cf.startZoom();
        anim.SetTrigger("sleep");
        sleepTimer = 5.0f;
    }

    void wakeup() {
        if (startSleeping) {
            anim.SetTrigger("wakeup");
            sleepTimer = 7.0f;
            startSleeping = false;
        } else {
            canMove = true;
            CameraFollow cf = FindObjectOfType<CameraFollow>();
            cf.zoomOut();

        }
    }


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


        if (stats.health <= 10 && stats.health > 0) {

            if (!ending) {
                ending = true;
                anim.SetTrigger("scare");
                anim.SetFloat("speed", 0);
            }

            canMove = false;
            return;
        }


        if (invul > 0) {
            invul -= Time.deltaTime;
            if (invul <= 0.4) {
                canMove = true;
            }
        }

        if (sleepTimer > 0) {
            sleepTimer -= Time.deltaTime;
            if (sleepTimer <= 0) {
                wakeup();
            }
        }

        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");


        Vector3 input;
        if (canMove)
            input = Vector3.ClampMagnitude(new Vector3(horizontal, 0, vertical), 1.0F);
        else
            input = Vector3.zero;

        if (dashing > dashCooldown - 0.3f) {
            input = dashDir;
        }


        attacks();




        if (grounded) {
            velocity = input;
        } else {
            if (input != Vector3.zero) {
                velocity = Vector3.Lerp(velocity, input, 0.02f);
                
            }
        }

        Vector3 lookDir = Vector3.RotateTowards(transform.forward, velocity, turnSpeed * Time.deltaTime, 0.5F);
        transform.rotation = Quaternion.LookRotation(lookDir);

        Vector3 fallAmount = new Vector3(0, velY, 0);


        Vector3 down = transform.TransformDirection(-Vector3.up);
        if (velY < 0 && Physics.Raycast(transform.position, down, 0.5f)) {
            grounded = true;
            anim.SetBool("jumping", false);
        }

        

        if (Input.GetButtonDown("Jump") && grounded && canMove) {
            velY = jumpForce;
            anim.SetBool("jumping", true);
            anim.SetTrigger("jump");
            grounded = false;
        }



        if (velY > -10.0f) {
            velY -= Time.deltaTime * gravity;
        }

        cc.Move((velocity * moveSpeed + fallAmount) * Time.deltaTime);

        if (horizontal == 0 && vertical == 0) {
            anim.SetFloat("speed", 0);
        } else {
            anim.SetFloat("speed", 1.0f);
        }


	}

    void attacks() {

        if (canMove) {

            if (dashing > 0) {
                chomp.chomping = false;
                if (dashing < dashCooldown - 0.1f && dashing > dashCooldown - 0.4f) {
                    chomp.chomping = true;
                }
                dashing -= Time.deltaTime;
            }

            if (Input.GetButtonDown("Fire1") && dashing <= 0) {
                anim.SetTrigger("dash");
                dashing = dashCooldown;
                if (grounded) {
                    velY = jumpForce * 0.7f;
                } else {
                    velY = jumpForce * 0.3f;
                }
                grounded = false;

                dashDir = transform.forward * 1.5f;
                velocity = dashDir;
                audio.PlayOneShot(chompSFX);
            }
        }

        if (barking > 0) {

            if (barking < barkCooldown - 0.8f) {
                canMove = true;
            }

            barking -= Time.deltaTime;
        }

        if (grounded && canMove && Input.GetButtonDown("Fire2") && barking <= 0) {
            canMove = false;
            velocity = Vector3.zero;
            barking = barkCooldown;
            anim.SetTrigger("bark");
            audio.Play();

            Bear[] bears = FindObjectsOfType<Bear>();

            foreach (Bear b in bears) {
                b.scare();
            }


        }
    }
}
