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 OnOrientationChange = new UnityEvent();
        public ScreenOrientation ScreenOrientation;
        private Vector2 resolution; // Current Resolution
        private 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);

            var scaler = canvas.AddComponent<UnityEngine.UI.CanvasScaler>();
            scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
            scaler.referenceResolution = new Vector2(1024, 1024);
            scaler.screenMatchMode = UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
            scaler.matchWidthOrHeight = .5f;

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

            instance.ScreenOrientation = instance.resolution.x < instance.resolution.y
                    ? ScreenOrientation.Portrait
                    : ScreenOrientation.Landscape;
        }

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

        private void OnRectTransformDimensionsChange()
        {
            if (orientation != Screen.orientation || !(resolution.x == Screen.width && resolution.y == Screen.height))
            {
                orientation = Screen.orientation;
                resolution = new Vector2(Screen.width, Screen.height);
                ScreenOrientation = resolution.x < resolution.y 
                    ? ScreenOrientation.Portrait 
                    : ScreenOrientation.Landscape;

                OnOrientationChange.Invoke();
            }
        }

        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.
                OnOrientationChange.RemoveAllListeners();
                instance = null;
            }
        }
    }
}