// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using UnityEngine;
using UnityEditor;

namespace Microsoft.MixedReality.WebRTC.Unity.Editor
{
    /// <summary>
    /// Property drawer for <see cref="CaptureCameraAttribute"/>, to report an error to the user if
    /// the associated <see xref="UnityEngine.Camera"/> property instance cannot be used for framebuffer
    /// capture by <see cref="SceneVideoSource"/>.
    /// </summary>
    [CustomPropertyDrawer(typeof(CaptureCameraAttribute))]
    public class CaptureCameraDrawer : PropertyDrawer
    {
        private const int c_errorMessageHeight = 42;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            try
            {
                Validate(property.objectReferenceValue as Camera);
            }
            catch (Exception ex)
            {
                // Display error message below the property
                var totalHeight = position.height;
                position.yMin = position.yMax - c_errorMessageHeight;
                EditorGUI.HelpBox(position, ex.Message, MessageType.Warning);

                // Adjust rect for the property itself
                position.yMin = position.yMax - totalHeight;
                position.yMax -= c_errorMessageHeight;
            }

            EditorGUI.PropertyField(position, property, label);
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            float height = base.GetPropertyHeight(property, label);
            try
            {
                Validate(property.objectReferenceValue as Camera);
            }
            catch (Exception)
            {
                // Add extra space for the error message
                height += c_errorMessageHeight;
            }
            return height;
        }

        /// <summary>
        /// Validate that a given <see xref="UnityEngine.Camera"/> instance can be used for framebuffer
        /// capture by <see cref="SceneVideoSource"/> based on the current settings of the Unity Player
        /// for the current build platform.
        /// </summary>
        /// <param name="camera">The camera instance to test the settings of.</param>
        /// <exception xref="System.NotSupportedException">
        /// The camera has settings not compatible with its use with <see cref="SceneVideoSource"/>.
        /// </exception>
        /// <seealso cref="CaptureCameraAttribute.Validate(Camera)"/>
        public static void Validate(Camera camera)
        {
            if (PlayerSettings.virtualRealitySupported && (camera != null))
            {
                if (PlayerSettings.stereoRenderingPath == StereoRenderingPath.MultiPass)
                {
                    // Ensure camera is not rendering to both eyes in multi-pass stereo, otherwise the command buffer
                    // is executed twice (once per eye) and will produce twice as many frames, which leads to stuttering
                    // when playing back the video stream resulting from combining those frames.
                    if (camera.stereoTargetEye == StereoTargetEyeMask.Both)
                    {
                        throw new NotSupportedException("Capture camera renders both eyes in multi-pass stereoscopic rendering. This is not" +
                            " supported by the capture mechanism which cannot discriminate them. Set Camera.stereoTargetEye to either Left or" +
                            " Right, or use a different rendering mode (Player Settings > XR Settings > Stereo Rendering Mode).");
                    }
                }
#if !UNITY_2019_1_OR_NEWER
                else if (PlayerSettings.stereoRenderingPath == StereoRenderingPath.Instancing)
                {
                    throw new NotSupportedException("Capture camera does not support single-pass instanced stereoscopic rendering before Unity 2019.1." +
                        " Use a different stereoscopic rendering mode (Player Settings > XR Settings > Stereo Rendering Mode) or upgrade to Unity 2019.1+.");
                }
#endif
            }
        }
    }
}