using System;
using Unity.Collections;
using UnityEngine.Scripting;
using UnityEngine.XR.ARSubsystems;
#if UNITY_XR_MAGICLEAP_PROVIDER
using UnityEngine.XR.MagicLeap.Internal;
#endif
using UnityEngine.XR.Management;
namespace UnityEngine.XR.MagicLeap
{
    [Preserve]
    public sealed class SessionSubsystem : XRSessionSubsystem
    {
#if !UNITY_2020_2_OR_NEWER
        protected override Provider CreateProvider() => new MagicLeapProvider();
#endif
        class MagicLeapProvider : Provider
        {
            public override Promise<SessionAvailability> GetAvailabilityAsync()
            {
                var availability = SessionAvailability.Installed | SessionAvailability.Supported;
                return Promise<SessionAvailability>.CreateResolvedPromise(availability);
            }
            public override TrackingState trackingState
            {
                get
                {
                    var device = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye);
                    if (device.TryGetFeatureValue(CommonUsages.trackingState, out InputTrackingState inputTrackingState))
                    {
                        if (inputTrackingState == InputTrackingState.None)
                            return TrackingState.None;
                        else if (inputTrackingState == (InputTrackingState.Position | InputTrackingState.Rotation))
                            return TrackingState.Tracking;
                        else
                            return TrackingState.Limited;
                    }
                    else
                    {
                        return TrackingState.None;
                    }
                }
            }
            public override Feature requestedFeatures => SubsystemFeatures.requestedFeatures;
            public override NativeArray<ConfigurationDescriptor> GetConfigurationDescriptors(Allocator allocator)
                => SubsystemFeatures.AcquireConfigurationDescriptors(allocator);
            public override Feature requestedTrackingMode
            {
                get => SubsystemFeatures.requestedFeatures.Intersection(Feature.AnyTrackingMode);
                set
                {
                    SubsystemFeatures.SetFeatureRequested(Feature.AnyTrackingMode, false);
                    SubsystemFeatures.SetFeatureRequested(value, true);
                }
            }
            public override Feature currentTrackingMode
            {
                get
                {
                    switch (trackingState)
                    {
                        case TrackingState.Tracking:
                            return Feature.PositionAndRotation;
                        case TrackingState.Limited:
                            return Feature.RotationOnly;
                        default:
                            return Feature.None;
                    }
                }
            }
            private Feature previousConfigurationFeatures = Feature.None;
            public override void Update(XRSessionUpdateParams updateParams, Configuration configuration)
            {
                
                if (configuration.features.HasFlag(Feature.Meshing | Feature.PointCloud))
                {
                    
                    
                    
#if UNITY_XR_MAGICLEAP_PROVIDER
                    var loader = (MagicLeapLoader)XRGeneralSettings.Instance.Manager.activeLoader;
                    if (loader.meshSubsystem != null && !loader.meshSubsystem.running)
                    {
                        loader.StartMeshSubsystem();
                    }
#endif
                }
                else if (previousConfigurationFeatures.HasFlag(Feature.Meshing | Feature.PointCloud))
                {
#if UNITY_XR_MAGICLEAP_PROVIDER
                    var loader = (MagicLeapLoader)XRGeneralSettings.Instance.Manager.activeLoader;
                    if (loader.meshSubsystem != null && loader.meshSubsystem.running)
                    {
                        loader.StopMeshSubsystem();
                    }
#endif
                }
                
                
                
                SubsystemFeatures.SetCurrentFeatureEnabled(previousConfigurationFeatures, false);
                SubsystemFeatures.SetCurrentFeatureEnabled(configuration.features, true);
                previousConfigurationFeatures = configuration.features;
            }
        }
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
        static void RegisterDescriptor()
        {
            XRSessionSubsystemDescriptor.RegisterDescriptor(new XRSessionSubsystemDescriptor.Cinfo
            {
                id = MagicLeapXrProvider.SessionSubsystemId,
#if UNITY_2020_2_OR_NEWER
                providerType = typeof(SessionSubsystem.MagicLeapProvider),
                subsystemTypeOverride = typeof(SessionSubsystem),
#else
                subsystemImplementationType = typeof(SessionSubsystem),
#endif
                supportsInstall = false
            });
        }
    }
}