using UnityEngine;
using System.Collections;

public enum Direction { right, left };
public class FPSWalker : MonoBehaviour {
   
    public float speed= 3.5f;
    public float jumpSpeed= 8.0f;
    public float gravity= 20.0f;

    public static Direction movementDirection = Direction.right;


    private Vector3 moveDirection= Vector3.zero;
    private bool  grounded = false;

    private Transform transCache;
    private Transform graphicsTransform; 
    CharacterController controller;

    private bool hardMovementLock = false;
    public void SetMovementLock(bool value)
    {
        hardMovementLock = value;
    }

    Vector3 spawnPos;

    void Awake()
    {
        transCache = transform;
        spawnPos = transCache.position;
        controller = GetComponent<CharacterController>();
        graphicsTransform = transCache.FindChild("Graphics");
    }

    private float horInput = 0;
    private float verInput = 0;
    private float lastJump = 0;



    void  LateUpdate (){
        if (hardMovementLock) return;
        if (grounded)
        {

            if (GameManager.AllowInput())
            {
                horInput = 0;// Input.GetAxisRaw("Vertical");
                verInput = Input.GetAxisRaw("Horizontal");
                if (Input.GetKey(KeyCode.RightShift) || Input.GetKey(KeyCode.LeftShift))
                    verInput *= 3;
            }
            else
                horInput = verInput = 0;

            if (verInput > 0)
            {
                movementDirection = Direction.right;
                graphicsTransform.localEulerAngles = new Vector3(0, 0,0);

            }
            else if (verInput < 0)
            {
                movementDirection = Direction.left;
                graphicsTransform.localEulerAngles = new Vector3(0, 180, 0);
            }
            else
            {
                graphicsTransform.localEulerAngles = new Vector3(0, 90, 0);
            }
                     

            // We are grounded, so recalculate movedirection directly from axes
            moveDirection.y = 0;

            Vector3 desiredMoveDirection = new Vector3(horInput, 0, verInput);
            desiredMoveDirection *= speed;// Mathf.Clamp(speed, 0, 3.5f);          
            desiredMoveDirection = transform.TransformDirection(desiredMoveDirection);
            
            if(desiredMoveDirection.magnitude > moveDirection.magnitude)
                //Speed up..slower
                moveDirection = Vector3.Lerp(moveDirection, desiredMoveDirection, Time.deltaTime*10);
            else
                moveDirection = Vector3.Lerp(moveDirection, desiredMoveDirection, Time.deltaTime * 40);
             
             //Debug.Log(  Vector3.Magnitude(moveDirection) +" - "+(speed * Time.deltaTime *60) );       
            //TODO: sometimes the movement speed is way too high because of lagspikes..CAP the movedirection SPEED

            if (lastJump < Time.realtimeSinceStartup - 0.5f && (Input.GetButton("Jump") || Input.GetKeyDown(KeyCode.UpArrow)) && GameManager.AllowInput())
            {
                lastJump = Time.realtimeSinceStartup;
                moveDirection.y = jumpSpeed;
            }
            //lastHorInput = horInput;
            //lastVerInput = verInput;
        }
        else
        {
            //Mid air
            if (GameManager.AllowInput())
            {
                horInput = 0; // Input.GetAxisRaw("Vertical");
                verInput = Input.GetAxisRaw("Horizontal");
                if (horInput == 0 && verInput == 0)
                {
                    Vector3 desiredMoveDirection = new Vector3(0, moveDirection.y, 0);
                    moveDirection = Vector3.Lerp(moveDirection, desiredMoveDirection, Time.deltaTime * 2);
                }
            }
        }

	    // Apply gravity
        moveDirection.y -= gravity * Time.deltaTime; // Mathf.Clamp(moveDirection.y - gravity * Time.deltaTime, -20, 20);

        // Move the controller
	    CollisionFlags flags= controller.Move(moveDirection * Time.deltaTime);
	    grounded = (flags & CollisionFlags.CollidedBelow) != 0;

        transCache.position = new Vector3(transCache.position.x, transCache.position.y, spawnPos.z);

    }
    
    void Update()
    {
        if (transCache.position.y < -10)
        {
            Died();                  
        }
        
    }

    public void Died()
    {
        Reset(); 
    }

    public void Reset(){
        moveDirection = Vector3.zero;
        transCache.position = spawnPos;
    }



}