using UnityEditor;
using UnityEngine;

namespace Utility
{
    /// <summary>
    /// Ein Singleton das von <see cref="MonoBehaviour"/> erbt. Ermöglicht es aus einem normalen GameObject ein Singleton zu machen.
    /// Stellt sicher, dass es nur ein Exemplar von sich selbst gibt.
    /// </summary>
    /// <typeparam name="T">Der Typ des Singletons.</typeparam>
    public abstract class MonoBehaviourSingleton<T> : MonoBehaviour, ISerializationCallbackReceiver where T : MonoBehaviourSingleton<T>
    {
        private static T _instance;

        public static T Instance
        {
            get => _instance;
            private set
            {
                if (_instance == null)
                {
                    _instance = value;
                }
                else if (_instance != value)
                {
                    Debug.LogError("Instance already exists. Deleting duplicate.");
                    
                    if (Application.isEditor)
                    {
                        DestroyImmediate(value.gameObject);
                    }
                    else
                    {
                        Destroy(value.gameObject);    
                    }
                }
            }
        }

        /// <remarks>Wenn du diese methode überlädst, rufe auf jeden Fall base.Awake() auf!</remarks>
        protected virtual void Awake()
        {
            Instance = (T)this;
        }

        public void OnBeforeSerialize()
        {
            // Nothing to do here.
        }

        public void OnAfterDeserialize()
        {
            if (!Application.isEditor)
            {
                // The value of Instance is lost after deserialization, so we need to set it again.
                Instance = (T)this;   
            }
        }
    }
}