using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneAccess
{
    private static Dictionary<string, GameObject> m_foundObjects = new Dictionary<string, GameObject>();

    public static void Clear()
    {
        m_foundObjects.Clear();
    }

    public static GameObject FindActive(string name)
    {
        GameObject obj = null;

        if (m_foundObjects.TryGetValue(name, out obj))
            return obj;

        obj = GameObject.Find(name);
        if (obj)
            m_foundObjects.Add(name, obj);

        return obj;
    }

    // also finds inactive objects; but scene must be loaded
    // @NOTE: if called on awake, the scene is not loaded yet
    public static GameObject Find(string name)
    {
        GameObject obj = null;
        if (m_foundObjects.TryGetValue(name, out obj))
            return obj;

        for (int i = 0; i < SceneManager.sceneCount; i++)
        {
            Scene s = SceneManager.GetSceneAt(i);
            if (s.IsValid() && s.isLoaded)
            {
                GameObject[] roots = s.GetRootGameObjects();
                foreach (var o in roots)
                {
                    if (o.name == name)
                    {
                        m_foundObjects.Add(name, o);
                        return o;
                    }

                    Transform[] transforms = o.GetComponentsInChildren<Transform>(true);
                    foreach (var t in transforms)
                    {
                        if (t.name == name)
                        {
                            m_foundObjects.Add(name, t.gameObject);
                            return t.gameObject;
                        }
                    }
                }
            }
        }

        return null;
    }

    public T FindComponent<T>(string name) where T : Component
    {
        GameObject o = Find(name);
        if (o)
            return o.GetComponent<T>();
        else
            return null;
    }

    //@TODO move these out of here
    public void ActivateMainScene()
    {
        Scene main = SceneManager.GetSceneByName("Main");
        if (main.IsValid() && SceneManager.GetActiveScene() != main)
            SceneManager.SetActiveScene(main);
    }

    public string FindLoadedLevelScene()
    {
        for (int i = 0; i < SceneManager.sceneCount; i++)
        {
            Scene s = SceneManager.GetSceneAt(i);
            if (s.IsValid() && s.isLoaded)
            {
                if (s.name.Contains("Level") || 
                    s.name.Contains("Ending") ||
                    s.name.Contains("Hideout") ||
                    s.name.Contains("Party"))
                    return s.name;
            }
        }

        return "";
    }

    /* UNUSED
    public int GetLevelNumberFromSceneName(string sceneName)
    {
        if (sceneName.StartsWith("Level"))
        {
            int id = 1;
            if (int.TryParse(sceneName.Substring(5), out id))
                return id;
        }
        return -1;
    }
    */
}