﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;

public class LoadingScreenController : MonoBehaviour {

    public float minimumLoadTime = 0.5f;
    public BlackScreen blackScreen;

    public static LoadingScreenController controller;

    void Start() {
        if (controller == null) {
            controller = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (controller != this) {
            Destroy(gameObject);
        }
    }

    void Update() {
 
    }

    public void StartLoadingScene(string sceneName, bool multiplayerMatchmaking = false) {
        StartCoroutine(LoadScene(sceneName, multiplayerMatchmaking));
    }

    public IEnumerator LoadScene(string sceneName, bool multiplayerMatchmaking = false) {

        yield return null;

        // Fade to black
        yield return StartCoroutine(blackScreen.FadeInAsync());

        // Load loading screen
        yield return SceneManager.LoadSceneAsync("Loading Screen");        

        // Fade to loading screen
        yield return StartCoroutine(blackScreen.FadeOutAsync());

        float endTime = Time.unscaledTime + minimumLoadTime;

        // Load level async
        yield return SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);

        // set active scene first to prevent any weird instantiation issues
        // (additive sceen loads the scene but doesn't switch the active scene so instantiated objects fall into the last loaded scene)
        SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName));

        GameObject[] rootObjects = SceneManager.GetActiveScene().GetRootGameObjects();

        foreach (GameObject obj in rootObjects) {
            obj.SetActive(false);
        }

        if (Time.unscaledTime < endTime) {
            yield return new WaitForSecondsRealtime(endTime - Time.unscaledTime);
        }

        //// Fade to black
        yield return StartCoroutine(blackScreen.FadeInAsync());

        bool unloadLoadingScreen = false;
        for(int i = 0; i < SceneManager.sceneCount; i++) {
            unloadLoadingScreen = SceneManager.GetSceneAt(i).name == "Loading Screen";
            if (unloadLoadingScreen)
                break;
        }

        // !!! unload loading screen
        if(unloadLoadingScreen)
            yield return SceneManager.UnloadSceneAsync("Loading Screen");

        // for some reason the main camera doesn't always get activated properly
        // the object will be set to active but the actual camera won't work
        GameObject cam = null;

        foreach (GameObject obj in rootObjects) {
            if (!obj)
                continue;

            if(obj.tag == "MainCamera") {
                cam = obj;
            }

            obj.SetActive(true);
        }

        if (cam) {
            cam.SetActive(false);
            yield return null;
        }

        if (cam)
            cam.SetActive(true);
            

        // Fade to new screen
        yield return StartCoroutine(blackScreen.FadeOutAsync());
    }

    // use this for loading any scenes that need a little bit of time to load
    public static void LoadUsingLoadingScreen(string sceneName) {

        // if there's no controller just load the dang thing anyway
        if (!controller) {
            SceneManager.LoadScene(sceneName);
            return;
        }

        controller.StartLoadingScene(sceneName);
    }

    public static void LoadUsingLoadingScreenWithText(string sceneName) {
        // if there's no controller just load the dang thing anyway
        if (!controller) {
            SceneManager.LoadScene(sceneName);
            return;
        }

        controller.StartLoadingScene(sceneName, true);
    }

    IEnumerator PhotonLoadScene(string sceneName) {
        // fade out
        // load loading screen
        // wait for syn ack

        // fade into loading screen

        // load level async
        // wait for syn ack
        // handle any weird things
        // fade out
        // unload loading screen
        // reactivate everything in the scene
        // fade into real scene
        yield return null;
    }

    public static void LoadLevelAcrossPhotonRoom(string sceneName) {
        if (!controller) {
            if (PhotonNetwork.IsConnected) {
                PhotonNetwork.AutomaticallySyncScene = true;
                PhotonNetwork.LoadLevel(sceneName);
            }
            else {
                SceneManager.LoadScene(sceneName);
                return;
            }
            return;
        }

        if (PhotonNetwork.IsConnected) {
            if (PhotonNetwork.IsMasterClient) {
                PhotonNetwork.AutomaticallySyncScene = true;
            }

            controller.PhotonLoadScene(sceneName);
        }
        else {
            controller.StartLoadingScene(sceneName);
        }
    }
}
