using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class FadeManager : MonoBehaviour {

    [SerializeField] private GameObject currentDayGUI;
    [SerializeField] private float waitingBeforeFadeInDuration = 1.5f;
    [SerializeField] private float fadeDuration = 2f;
    [SerializeField] private float fps = 30f;

    public static FadeManager instance;

    public static int currentDay = 0;

    public static bool isFading = false;

    public static float fpsStatic;
    public static float fadeDurationStatic;

    private static Image img = null;
    private static float alpha = 0f;

    private static float waitingBeforeFadeInDurationStatic;

    private Text currentDayGUIText = null;

    void Awake() {
        if (instance != null) {
            Debug.LogError("Error : Only one Fade instance at a time !");
        }
        instance = this;
        if (currentDayGUI != null) {
            currentDayGUIText = currentDayGUI.GetComponent<Text>();
            currentDayGUI.SetActive(false);
        }
        if (Application.loadedLevelName.Contains("MainScene")) {
            currentDay = Application.loadedLevelName[Application.loadedLevelName.Length - 1] - '0';
        }
    }

	void Start() {
        img = GetComponent<Image>();
        fpsStatic = fps;
        fadeDurationStatic = fadeDuration;
        waitingBeforeFadeInDurationStatic = waitingBeforeFadeInDuration;
        if (Application.loadedLevelName == "Tests") {
            alpha = 1f;
            DoFadeIn();
        }
    }

    public static void NextDay() {
        DoFadeOut(true);
    }

    public static void DoFadeIn(bool passDay = true) {
        Physics.gravity = Vector3.down * 19.62f;
        if (isFading) {
            instance.CancelInvoke("FadeIn");
            instance.CancelInvoke("FadeOut");
        }
        isFading = true;
        if (instance.currentDayGUI != null) {
            instance.currentDayGUI.SetActive(true);
            instance.currentDayGUIText.text = "Jour " + (Application.loadedLevelName[Application.loadedLevelName.Length-1]-'0'+1).ToString();
        }
        if (passDay) {
            instance.InvokeRepeating("FadeIn", waitingBeforeFadeInDurationStatic, 1 / fpsStatic);
            instance.Invoke("PassDay", fadeDurationStatic);
        } else {
            instance.InvokeRepeating("FadeIn", 0, 1 / fpsStatic);
        }
    }

    public static void DoFadeOut(bool mustWrite = false) {
        if (isFading) {
            instance.CancelInvoke("FadeIn");
            instance.CancelInvoke("FadeOut");
        }
        isFading = true;
        instance.InvokeRepeating("FadeOut", 0, 1 / fpsStatic);
        if (mustWrite) {
            instance.Invoke("Write", fadeDurationStatic);
        }
    }

    public static void DoFadeOut(string levelName) {
        if (isFading) {
            instance.CancelInvoke("FadeIn");
            instance.CancelInvoke("FadeOut");
        }
        isFading = true;
        instance.InvokeRepeating("FadeOut", 0, 1 / fpsStatic);
        StaticCoroutine.DoCoroutine(Load(levelName));
    }

    void FadeIn() {
        alpha -= 1 / (fps * fadeDuration);
        img.color = new Color(0, 0, 0, alpha);
        if (currentDayGUIText != null) {
            currentDayGUIText.color = new Color(1, 1, 1, alpha);
        }
        if (alpha < 0) {
            alpha = 0;
            img.color = new Color(0, 0, 0, alpha);
            CancelInvoke("FadeIn");
            isFading = false;
            EndFade();
        }
    }

    void PassDay() {
        currentDay++;
    }

    void Write() {
        Application.LoadLevel("Typewriter");
    }

    static IEnumerator Load(string levelName) {
        yield return new WaitForSeconds(fadeDurationStatic);
        MenuManager.cursorLocked = false;
        Application.LoadLevel(levelName);
        yield return null;
    }

    void FadeOut() {
        alpha += 1 / (fps * fadeDuration);
        img.color = new Color(0, 0, 0, alpha);
        if (alpha > 0.99f) {
            alpha = 1;
            img.color = new Color(0, 0, 0, alpha);
            isFading = false;
            CancelInvoke("FadeOut");
        }
    }

    void EndFade() {
        isFading = false;
    }
}