/**********************************************************************************
* Blueprint Reality Inc. CONFIDENTIAL
* 2020 Blueprint Reality Inc.
* All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains, the property of
* Blueprint Reality Inc. and its suppliers, if any.  The intellectual and
* technical concepts contained herein are proprietary to Blueprint Reality Inc.
* and its suppliers and may be covered by Patents, pending patents, and are
* protected by trade secret or copyright law.
*
* Dissemination of this information or reproduction of this material is strictly
* forbidden unless prior written permission is obtained from Blueprint Reality Inc.
***********************************************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_2017_2_OR_NEWER
using UnityEngine.XR;
#else
using XRSettings = UnityEngine.VR.VRSettings;
using XRStats = UnityEngine.VR.VRStats;
#endif
#if MIXCAST_XRMAN
using UnityEngine.XR.Management;
#endif

namespace BlueprintReality.MixCast
{
    public class XrPlatformInfo : MonoBehaviour
    {
        public enum XrPlatform
        {
            None, SteamVR, Oculus
        }

        private const string OPENVR_DEVICE_NAME = "OpenVR";
        private const string OCULUS_DEVICE_NAME = "Oculus";

        public static readonly Vector3 VIVE_HMD_TO_HEAD = new Vector3(0, 0, -0.075f);
        public static readonly Vector3 OCULUS_RIFT_HMD_TO_HEAD = new Vector3(0, 0, -0.075f);


        public static XrPlatform ActivePlatform
        {
            get
            {
                if (destroyed)
                    return XrPlatform.None;
                if (instance == null)
                {
                    GameObject instanceObj = new GameObject("XrInfo") { hideFlags = HideFlags.HideAndDontSave };
                    DontDestroyOnLoad(instanceObj);
                    instance = instanceObj.AddComponent<XrPlatformInfo>();
                }
                return instance.activePlatform;
            }
        }
        public static event System.Action OnPlatformLoaded;

        private static XrPlatformInfo instance;
        private static bool destroyed = false;


        private XrPlatform activePlatform;

        private bool lastXrSettingsEnabled;
#if MIXCAST_XRMAN
        private XRLoader lastXrLoader;
#endif


        private void Awake()
        {
            instance = this;
            RefreshRuntimeInfo();

        }
        private void OnDestroy()
        {
            destroyed = true;
        }

        private void Update()
        {
            RefreshRuntimeInfo();
        }
        void RefreshRuntimeInfo()
        {
            XrPlatform newPlatform = XrPlatform.None;

#if UNITY_2017_1_OR_NEWER
            bool renderedOneFrame = XRSettings.isDeviceActive && (activePlatform != XrPlatform.None || !string.IsNullOrEmpty(XRSettings.loadedDeviceName));
#else
            bool renderedOneFrame = XRStats.gpuTimeLastFrame > 0;
#endif
            bool isReady = XRSettings.enabled && renderedOneFrame;
            bool xrSettingsChanged = lastXrSettingsEnabled != isReady;
            lastXrSettingsEnabled = isReady;

#if MIXCAST_XRMAN
            lastXrLoader = null;
            if (XRGeneralSettings.Instance != null && XRGeneralSettings.Instance.Manager != null)
            {
                lastXrLoader = XRGeneralSettings.Instance.Manager.activeLoader;
                if(lastXrLoader != null)
                {
                    if (XRGeneralSettings.Instance.Manager.isInitializationComplete)
                    {
                        string loaderName = lastXrLoader.name;
                        if (loaderName.IndexOf("Oculus", System.StringComparison.OrdinalIgnoreCase) != -1)
                            newPlatform = XrPlatform.Oculus;
                        else if (loaderName.IndexOf("Open VR", System.StringComparison.OrdinalIgnoreCase) != -1)
                            newPlatform = XrPlatform.SteamVR;
                    }

                    if (activePlatform != newPlatform)
                    {
                        activePlatform = newPlatform;
                        if (OnPlatformLoaded != null)
                            OnPlatformLoaded();
                    }
                    return;
                }
            }
#endif

            if (!lastXrSettingsEnabled)
                newPlatform = XrPlatform.None;
            else
            {
                if (xrSettingsChanged || (lastXrSettingsEnabled && activePlatform == XrPlatform.None))
                {
                    string deviceName = XRSettings.loadedDeviceName;
                    if (deviceName == OPENVR_DEVICE_NAME)
                        newPlatform = XrPlatform.SteamVR;
                    else if (deviceName == OCULUS_DEVICE_NAME)
                        newPlatform = XrPlatform.Oculus;
                }
                else
                    newPlatform = activePlatform;
            }

            if (newPlatform != activePlatform)
            {
                activePlatform = newPlatform;
                if (OnPlatformLoaded != null)
                    OnPlatformLoaded();
            }
        }
    }
}
