using UnityEngine;

namespace EngineSdkConverter.Unity.SDK
{
    public class SDKMonoBehaviour : MonoBehaviour
    {
        private Transform _transform;

        public Transform Transform
        {
            get
            {
                if (_transform == null)
                {
                    _transform = base.transform;
                }

                return _transform;
            }
        }

        private GameObject _gameObject;

        protected GameObject GameObject
        {
            get
            {
                if (_gameObject == null)
                {
                    _gameObject = base.gameObject;
                }

                return _gameObject;
            }
        }
    }

    /// <summary>
    /// mono单例的实现
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class MonoSingleton<T> : SDKMonoBehaviour where T : MonoSingleton<T>
    {
        private static T mInstance = null;
        public static Transform BootRoot = null;

        public static T Instance
        {
            get
            {
                if (mInstance is null)
                {
                    mInstance = FindObjectOfType(typeof(T)) as T;
                    if (mInstance is null)
                    {
                        GameObject go = new GameObject(typeof(T).Name);
                        mInstance = go.AddComponent<T>();
                        if (BootRoot is null || BootRoot.gameObject == null)
                        {
                            var bootRootObj = GameObject.Find("Boot");
                            if (bootRootObj is null)
                            {
                                bootRootObj = new GameObject("Boot");
                                BootRoot = bootRootObj.transform;
                                DontDestroyOnLoad(bootRootObj);
                            }
                            else
                            {
                                BootRoot = bootRootObj.transform;
                            }
                        }

                        if (!(BootRoot is null))
                        {
                            go.transform.SetParent(BootRoot);
                        }
                    }
                }

                return mInstance;
            }
        }


        public void Startup()
        {
        }

        private void Awake()
        {
            if (mInstance == null)
            {
                mInstance = this as T;
            }

            DontDestroyOnLoad(GameObject);
            Init();
        }

        protected virtual void Init()
        {
            RegisterMsg();
        }

        protected virtual void RegisterMsg()
        {
        }

        protected virtual void UnRegisterMsg()
        {
        }

        public void DestroySelf()
        {
            UnRegisterMsg();
            Dispose();
            mInstance = null;
            Destroy(GameObject);
        }

        public virtual void Dispose()
        {
        }

        protected virtual void OnDestroy()
        {
            UnRegisterMsg();
            mInstance = null;
        }
    }
}