using UnityEngine;
using UnityEngine.Events;

namespace RothenburgAR.UI
{
    [RequireComponent(typeof(RectTransform))]
    public class DisplayManager : MonoBehaviour
    {
        static DisplayManager instance = null;
        public static DisplayManager Instance
        {
            get
            {
                Init();
                return instance;
            }
        }

        public readonly UnityEvent OnResolutionChange = new UnityEvent();
        public readonly UnityEvent OnOrientationChange = new UnityEvent();
        Vector2 resolution; // Current Resolution
        ScreenOrientation orientation; // Current Screen Orientation

        static void Init()
        {
            if (instance != null) return;
            GameObject canvas = new GameObject("DisplayManager");
            canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
            instance = canvas.AddComponent<DisplayManager>();
            DontDestroyOnLoad(canvas);

            instance.resolution = new Vector2(Screen.width, Screen.height);
            instance.orientation = Screen.orientation;
        }

        private void Start()
        {
            if (instance != this)
            {
                Destroy(this);
            }
        }

        private void OnRectTransformDimensionsChange()
        {
            // Check for an orientation change.
            ScreenOrientation curOri = Screen.orientation;
            switch (curOri)
            {
                case ScreenOrientation.Unknown: // Ignore
                    {
                        break;
                    }
                default:
                    {
                        if (orientation != curOri)
                        {
                            orientation = curOri;
                            OnOrientationChange.Invoke();
                        }
                        break;
                    }
            }

            // Check for a resolution change.
            if ((resolution.x != Screen.width && resolution.x != Screen.height) || (resolution.y != Screen.height && resolution.y != Screen.width))
            {
                resolution = new Vector2(Screen.width, Screen.height);
                OnResolutionChange.Invoke();
            }
        }

        public void AddResolutionChangeListener(UnityAction callback)
        {
            OnResolutionChange.AddListener(callback);
        }

        public void RemoveResolutionChangeListener(UnityAction callback)
        {
            OnResolutionChange.RemoveListener(callback);
        }

        public void AddOrientationChangeListener(UnityAction callback)
        {
            OnOrientationChange.AddListener(callback);
        }

        public void RemoveOrientationChangeListener(UnityAction callback)
        {
            OnOrientationChange.RemoveListener(callback);
        }

        private void OnDestroy()
        {
            if (instance == this)
            {
                // Clean up memory.
                OnResolutionChange.RemoveAllListeners();
                OnOrientationChange.RemoveAllListeners();
                instance = null;
            }
        }
    }
}