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

/// <summary>
/// When extending from this class remember to call the base.Awake()
/// </summary>
/// <typeparam name="T"></typeparam>
abstract public class SingletonMonoBehavior<T> : MonoBehaviour where T : MonoBehaviour
{

	private static T _instance;

    public static T instance
    {
        get
        {
            if ( null == _instance )
            {
                // try to find
                _instance = FindObjectOfType<T>();

                if ( null == _instance )
                {
                    throw new System.Exception("Singleton Monobehavior not found for " + typeof(T));
                }
                
                
            }

            return _instance;
        }
    }

    protected virtual void Awake()
    {
        InitializeSingleton();
    }

    protected virtual void OnDestroy()
    {
        Debug.Log("Singleton being destroyed : " + this);
        if (this == _instance)
        {
            _instance = null;
        }
    }

    protected virtual void OnEnable()
    {
        if ( null == _instance )
        {
            InitializeSingleton();
        }
    }

    private void InitializeSingleton()
    {
        if ( null != _instance )
        {
            if ( _instance.GetInstanceID() != GetInstanceID() )
            {
                throw new System.Exception("Class has already been instantiated. There can only be one instance running");
            }

            return;   
        }

        _instance = GetComponent<T>();
        // Debug.Log("[SINGLETON] "+_instance);
        // With unity >= 5.3 it is recommended to use the SceneManager to handle global/persistent objects
        // See https://docs.unity3d.com/Manual/MultiSceneEditing.html
        // TODO: Figure out how to handle global variables with the SceneManager properly
        DontDestroyOnLoad(gameObject);
    }

    public static bool HasInstance()
    {
        return (null != _instance);
    }

}
