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

public class SceneTransitionManager : MonoBehaviour {

    static Image image = null;
    public static bool alreadyCalled = false;

    public static Image getOverlayImage() {
        GameObject sceneTransitionGO = GameObject.Find("~SceneTransition");
        if (sceneTransitionGO == null) {
            //Build transition GOs on demand
            sceneTransitionGO = new GameObject("~SceneTransition");
            GameObject newCanvas = new GameObject("Canvas");
            Canvas canvas = newCanvas.AddComponent<Canvas>();
            canvas.renderMode = RenderMode.ScreenSpaceOverlay;
            canvas.sortingOrder = 99;
            newCanvas.AddComponent<CanvasScaler>();
            newCanvas.AddComponent<GraphicRaycaster>();
            GameObject panel = new GameObject("Panel");
            panel.AddComponent<CanvasRenderer>();
            image = panel.AddComponent<Image>();
            image.raycastTarget = false;
            image.color = new Color(1, 1, 1, 0);
            image.rectTransform.sizeDelta = new Vector2(1080, 1920);
            panel.transform.SetParent(newCanvas.transform, false);
            newCanvas.transform.SetParent(sceneTransitionGO.transform);
        }
        return image;
    }

    public static IEnumerator fadeInAndLoad(string nextScene, float duration = 0.25f, float activationDelay = 0.25f) {
        yield return fadeInColorAndLoad(nextScene, Color.white, duration, activationDelay);
    }

    public static IEnumerator fadeInColorAndLoad(string nextScene, Color opaque, float duration = 0.25f, float activationDelay = 0.25f) {
        if (alreadyCalled) {
            Debug.LogWarning("fadeInColorAndLoad already called on this scene, don't do that!");
            yield break;
        }
        alreadyCalled = true;
        Image overlayImage = getOverlayImage();
        Color transparent = new Color(opaque.r, opaque.g, opaque.b, 0f);
        float start = 0;
        AsyncOperation async = SceneManager.LoadSceneAsync(nextScene);
        async.allowSceneActivation = false;
        while(start < duration) {
            overlayImage.color = Color.Lerp(transparent, opaque, start / duration);
            start += Time.deltaTime;
            yield return null;
        }
        overlayImage.color = opaque;
        yield return new WaitForSeconds(activationDelay);
        async.allowSceneActivation = true;
    }

    public static IEnumerator fadeOut(float duration = 0.25f) {
        yield return fadeOutColor(Color.white, duration);
    }

    public static IEnumerator fadeOutColor(Color opaque, float duration = 0.25f) {
        float start = 0;
        Image overlayImage = getOverlayImage();
        Color transparent = new Color(opaque.r, opaque.g, opaque.b, 0f);
        while (start < duration) {
            overlayImage.color = Color.Lerp(opaque, transparent, start / duration);
            start += Time.deltaTime;
            yield return null;
        }
        alreadyCalled = false;
        GameObject sceneTransitionGO = GameObject.Find("~SceneTransition");
        if(sceneTransitionGO) Destroy(sceneTransitionGO);
    }
}
