using UnityEngine;
using System.Collections;
using XInputDotNetPure;

public class GamePadManager : MonoBehaviour {

    public bool useVibration;
    public static bool useVibrationStatic;

    public static GamePadState state;
	public static GamePadState prevState;

	private const float defaultDuration = 0.25f;
	private const float defaultPower = 1.0f;

	private static bool isVibrating = false;

	// Variables for XInput
	private static bool playerIndexSet = false;
	private static PlayerIndex playerIndex;

	private static bool canShake = true;

	void Update()
    {
        useVibrationStatic = useVibration;
        UpdateGamePadState ();
	}

    public void SwitchVibrationMode()
    {
        useVibration = !useVibration;
    }

	void OnApplicationQuit() {
		for(int i = 0; i < 4; i++)
        {
            GamePad.SetVibration((PlayerIndex) i, 0.0f, 0.0f);
        }			
	}

	/// <summary>
	/// Updates the state of the game pad. Necessary at the beginning of each update !
	/// </summary>
	void UpdateGamePadState() {
		// Find a PlayerIndex, for a single player game
		// Will find the first controller that is connected and use it
		if (!playerIndexSet || !prevState.IsConnected) {
			for (int i = 0; i < 4; ++i) {
				PlayerIndex testPlayerIndex = (PlayerIndex)i;
				GamePadState testState = GamePad.GetState(testPlayerIndex);
				if (testState.IsConnected) {
					Debug.Log(string.Format("GamePad found {0}", testPlayerIndex));
					playerIndex = testPlayerIndex;
				}
			}
            playerIndexSet = true;
        }
		prevState = state;
		state = GamePad.GetState(playerIndex);
	}

	public static void Vibrate(PlayerIndex playerIdx = 0, float duration=defaultDuration, float power=defaultPower) {
		if (playerIndexSet) {
			if (!isVibrating && canShake && useVibrationStatic) {
				StaticCoroutine.DoCoroutine (DoVibration (playerIdx, duration, power));
			} else {
				GamePad.SetVibration (playerIdx, 0.0f, 0.0f);
			}
		}
	}

	public static void ChangeCanShake() {
		canShake = !canShake;
		if (!canShake) {
			GamePad.SetVibration (playerIndex, 0.0f, 0.0f);
		}
	}

	/// <summary>
	/// Vibrates controller the specified duration and power.
	/// </summary>
	static IEnumerator DoVibration(PlayerIndex playerIdx = 0, float duration=defaultDuration, float power=defaultPower) {
		if (power < 0 || power > 1) {
			Debug.LogError ("Error : power not set to a proper value in IEnum. Vibrate");
		} else {
			isVibrating = true;
			float counter = 0.0f;
			float coroutineDelay = 0.1f; // 10fps
			while (counter < duration) {
				counter += coroutineDelay;
				GamePad.SetVibration (playerIdx, power, power);
				yield return new WaitForSeconds (coroutineDelay);
			}
			GamePad.SetVibration (playerIdx, 0.0f, 0.0f);
			isVibrating = false;
		}
		yield return null;
	}
}