using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting.Activation;
using UnityEngine.UI;

public enum InputTypes
{
    up = 0,
    right,
    down,
    left,
    x,
    y,
    b,
    a,
    NO_INPUT,
    MAX,
};

public class InputManager : MonoBehaviour
{
    public class InputCommandRecord
    {
        public float fTimeSinceInput;
        public InputTypes inputType;
    }
    
    //y, a, b ,x ???
    private bool[] commandsDown;
    private bool[] oldCommandsDown;
    private bool[] pressedThisFrameCommands;

    private float joystickY;
    private float joystickX;

    public int iMaxQueuedCommands = 5;

    private InputCommandRecord[] commandQueue;

	// Use this for initialization
	void Start ()
	{
        commandsDown = new bool[(int)InputTypes.MAX];
        oldCommandsDown = new bool[(int)InputTypes.MAX];
        pressedThisFrameCommands = new bool[(int)InputTypes.MAX];
        commandQueue = new InputCommandRecord[iMaxQueuedCommands];
	}

    void OnGUI()
    {

    }

	// Update is called once per frame
    private void Update()
    {
        //Tick Queued Commands
        for (int t = 0; t < iMaxQueuedCommands; t++)
        {
            InputCommandRecord icr = commandQueue[t];
            if (icr == null)
                continue;

            icr.fTimeSinceInput += Time.deltaTime;
        }

        CollectInputThisFrame();

        //Check for double taps

    }

    public bool IsThisInputDoubleTapped(InputTypes keypress)
    {
        //first, was it pressed this turn?
        if (!commandsDown[(int) keypress])
            return false;

        if (commandQueue[0] == null || commandQueue[1] == null)
            return false;

        if (commandQueue[0].inputType == keypress &&
            commandQueue[0].inputType == commandQueue[1].inputType &&
            commandQueue[1].fTimeSinceInput < 0.5f)
            return true;

        return false;


    }

    public bool InputHeldThisTurn(InputTypes keypress)
    {
        return commandsDown[(int) keypress];
    }

    public bool InputJustPressedThisFrame(InputTypes keypress)
    {
        return pressedThisFrameCommands[(int)keypress];
    }


    private void CollectInputThisFrame()
    {

        if( Input.GetKey(KeyCode.Escape))
            Application.Quit();
            

        joystickX = Input.GetAxis("Horizontal");
        joystickY = Input.GetAxis("Vertical");

        for (int t = 0; t < (int) InputTypes.MAX; t++)
        {
            commandsDown[t] = false;
            pressedThisFrameCommands[t] = false;
        }

        //up, down, right, left
        commandsDown[(int) InputTypes.up] = joystickY > 0.5f || Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W);
        commandsDown[(int)InputTypes.down] = joystickY < -0.5f || Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S);

        commandsDown[(int)InputTypes.left] = joystickX < -0.5f || Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A);
        commandsDown[(int)InputTypes.right] = joystickX > 0.5f || Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D);

        //y, a, b ,x ???
        //private bool[] commandsDown;

        commandsDown[(int)InputTypes.y] = Input.GetButton("Jump");
        commandsDown[(int) InputTypes.a] = Input.GetButton("Fire1") || Input.GetKey(KeyCode.X) ||
                                           Input.GetKey(KeyCode.RightShift)|| Input.GetKey(KeyCode.Space);
        commandsDown[(int)InputTypes.b] = Input.GetButton("Fire2");
        commandsDown[(int) InputTypes.x] = Input.GetButton("Fire3") || Input.GetKey(KeyCode.Z) ||
                                           Input.GetKey(KeyCode.RightAlt);

        //if no stick input was entered this turn, enter in a NoInput command
        bool bNoMovement = true;
        for(int t= (int)InputTypes.up; t <= (int)InputTypes.left; t++)
            if (commandsDown[t])
                bNoMovement = false;

        commandsDown[(int) InputTypes.NO_INPUT] = bNoMovement;

        //evaluate all inputs compared to old.
        for (int t = 0; t < (int)InputTypes.MAX; t++)
        {
            if (commandsDown[t] && oldCommandsDown[t] == false)
            {
                pressedThisFrameCommands[t] = true;
                InputCommandRecord icr = new InputCommandRecord();
                icr.inputType = (InputTypes)t;
                icr.fTimeSinceInput = 0.0f;

                QueueInputCommand(icr);
            }

            oldCommandsDown[t] = commandsDown[t];
        }
    }

    private void QueueInputCommand(InputCommandRecord icr)
    {
        //don't push everything back if we're overwriting a no-movement call
        if (commandQueue[0] != null &&
            commandQueue[0].inputType == InputTypes.NO_INPUT)
        {
            commandQueue[0] = icr;
            return;
        }

        for (int t = iMaxQueuedCommands -1; t > 0; t--)
        {
            commandQueue[t] = commandQueue[t-1];
        }
        commandQueue[0] = icr;
    }
}
