using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditorInternal;

using RuntimeSRPPreferences = UnityEngine.Rendering.CoreRenderPipelinePreferences;

namespace UnityEditor.Rendering
{
    using CED = CoreEditorDrawer<SerializedProbeAdjustmentVolume>;

    internal class ProbeAdjustmentColorPreferences
    {
        internal static Func<Color> GetColorPrefProbeVolumeGizmoColor;
        internal static Color s_ProbeAdjustmentVolumeGizmoColorDefault = new Color32(222, 132, 144, 45);

        static ProbeAdjustmentColorPreferences()
        {
            GetColorPrefProbeVolumeGizmoColor = RuntimeSRPPreferences.RegisterPreferenceColor("Adaptive Probe Volumes/Probe Adjustment Volume Gizmo", s_ProbeAdjustmentVolumeGizmoColorDefault);
        }

    }

    [CanEditMultipleObjects]
    [CustomEditor(typeof(ProbeAdjustmentVolume))]
    internal class ProbeAdjustmentVolumeEditor : Editor
    {
        internal static class Styles
        {
            internal static readonly GUIContent s_VORotateTool = EditorGUIUtility.TrIconContent("RotateTool", "The virtual offset direction for probes falling in this volume.");
            internal static readonly GUIContent s_SORotateTool = EditorGUIUtility.TrIconContent("RotateTool", "The direction used to sample the ambient probe for probes falling in this volume.");
            internal static readonly GUIContent s_VolumeHeader = EditorGUIUtility.TrTextContent("Influence Volume");
            internal static readonly GUIContent s_AdjustmentHeader = EditorGUIUtility.TrTextContent("Probe Volume Overrides");

            internal static readonly GUIContent s_Mode = new GUIContent("Mode", "Choose which type of adjustment to apply to probes covered by this volume.");
            internal static readonly GUIContent s_DilationThreshold = new GUIContent("Dilation Validity Threshold", "Override the Dilation Validity Threshold for probes covered by this Probe Adjustment Volume. Higher values increase the chance of probes being considered invalid.");
            internal static readonly GUIContent virtualOffsetThreshold = new GUIContent("Validity Threshold", "Override the Virtual Offset Validity Threshold for probes covered by this Probe Adjustment Volume. Higher values increase the chance of probes being considered invalid.");
            internal static readonly GUIContent s_VODirection = new GUIContent("Rotation", "Rotate the axis along which probes will be pushed when applying Virtual Offset.");
            internal static readonly GUIContent s_VODistance = new GUIContent("Distance", "Determines how far probes are pushed in the direction of the Virtual Offset.");
            internal static readonly GUIContent renderingLayerMaskOperation = new GUIContent("Operation", "The operation to combine the Rendering Layer Mask set by this adjustment volume with the Rendering Layer Mask of the probes covered by this volume.");
            internal static readonly GUIContent renderingLayerMask = new GUIContent("Rendering Layer Mask", "Sets the Rendering Layer Mask to be combined with the Rendering Layer Mask of the probes covered by this volume.");
            internal static readonly GUIContent s_PreviewLighting = new GUIContent("Preview Probe Adjustments", "Quickly preview the effect of adjustments on probes covered by this volume.");

            internal static readonly GUIContent skyOcclusionSampleCount = new GUIContent("Sample Count", "Controls the number of samples per probe for sky occlusion baking.");
            internal static readonly GUIContent skyOcclusionMaxBounces = new GUIContent("Max Bounces", "Controls the number of bounces per light path for sky occlusion baking.");

            internal static readonly string s_AdjustmentVolumeChangedMessage = "This Adjustment Volume has never been baked, or has changed since the last bake. Re-bake Probe Volumes to ensure lighting data is valid.";

            internal static readonly EditMode.SceneViewEditMode VirtualOffsetEditMode = (EditMode.SceneViewEditMode)110;
            internal static readonly EditMode.SceneViewEditMode SkyDirectionEditMode = (EditMode.SceneViewEditMode)110;

            internal static readonly Color k_GizmoColorBase = ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault;

            internal static readonly Color[] k_BaseHandlesColor = new Color[]
            {
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault,
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault,
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault,
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault,
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault,
                ProbeAdjustmentColorPreferences.s_ProbeAdjustmentVolumeGizmoColorDefault
            };
        }

        static class ProbeAdjustmentVolumeUI
        {
            public static readonly CED.IDrawer Inspector = null;

            enum AdditionalProperties
            {
                Adjustments = 1 << 0,
            }
            enum Expandable
            {
                Volume = 1 << 0,
                Adjustments = 1 << 1,
            }

            readonly static ExpandedState<Expandable, ProbeAdjustmentVolume> k_ExpandedState = new ExpandedState<Expandable, ProbeAdjustmentVolume>(Expandable.Volume | Expandable.Adjustments);
            readonly static AdditionalPropertiesState<AdditionalProperties, ProbeAdjustmentVolume> k_AdditionalPropertiesState = new AdditionalPropertiesState<AdditionalProperties, ProbeAdjustmentVolume>(0);

            public static void DrawVolumeContent(SerializedProbeAdjustmentVolume serialized, Editor owner)
            {
                EditorGUILayout.PropertyField(serialized.shape);
                EditorGUILayout.PropertyField(serialized.shape.intValue == 0 ? serialized.size : serialized.radius);

            }

            static T[] RemoveAt<T>(T[] values, int index)
            {
                var list = new List<T>(values);
                list.RemoveAt(index);
                return list.ToArray();
            }
            static GUIContent[] CastArray(string[] values)
            {
                var result = new GUIContent[values.Length];
                for (int i = 0; i < values.Length; i++)
                    result[i] = new GUIContent(ObjectNames.NicifyVariableName(values[i]));
                return result;
            }

            public static void DrawAdjustmentContent(SerializedProbeAdjustmentVolume serialized, Editor owner)
            {
                ProbeAdjustmentVolume ptv = (owner.target as ProbeAdjustmentVolume);

                var bakingSet = ProbeVolumeBakingSet.GetBakingSetForScene(ptv.gameObject.scene);
                bool useVirtualOffset = bakingSet != null ? bakingSet.settings.virtualOffsetSettings.useVirtualOffset : false;
                bool useSkyOcclusion = bakingSet != null ? bakingSet.skyOcclusion : false;

                var hiddenMode = (int)ProbeAdjustmentVolume.Mode.IntensityScale;
                var availableValues = (int[])Enum.GetValues(typeof(ProbeAdjustmentVolume.Mode));
                var availableModes = CastArray(Enum.GetNames(typeof(ProbeAdjustmentVolume.Mode)));
                if (!k_AdditionalPropertiesState[AdditionalProperties.Adjustments] && serialized.mode.intValue != hiddenMode)
                {
                    int idx = Array.IndexOf(availableValues, hiddenMode);
                    availableValues = RemoveAt(availableValues, idx);
                    availableModes = RemoveAt(availableModes, idx);
                }

                EditorGUI.BeginChangeCheck();
                int newValue = EditorGUILayout.IntPopup(Styles.s_Mode, serialized.mode.intValue, availableModes, availableValues);
                if (EditorGUI.EndChangeCheck())
                    serialized.mode.intValue = newValue;

                if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.OverrideValidityThreshold)
                {
                    EditorGUILayout.PropertyField(serialized.overriddenDilationThreshold, Styles.s_DilationThreshold);
                }
                else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.ApplyVirtualOffset)
                {
                    EditorGUI.BeginDisabledGroup(!useVirtualOffset);
                    EditorGUILayout.BeginHorizontal();

                    EditorGUILayout.PropertyField(serialized.virtualOffsetRotation, Styles.s_VODirection);

                    var editMode = Styles.VirtualOffsetEditMode;
                    EditorGUI.BeginChangeCheck();
                    GUILayout.Toggle(editMode == EditMode.editMode, Styles.s_VORotateTool, EditorStyles.miniButton, GUILayout.Width(28f));
                    if (EditorGUI.EndChangeCheck())
                    {
                        EditMode.SceneViewEditMode targetMode = EditMode.editMode == editMode ? EditMode.SceneViewEditMode.None : editMode;
                        EditMode.ChangeEditMode(targetMode, GetBounds(serialized, owner), owner);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.PropertyField(serialized.virtualOffsetDistance, Styles.s_VODistance);
                    EditorGUI.EndDisabledGroup();

                    if (!useVirtualOffset)
                    {
                        CoreEditorUtils.DrawFixMeBox("Apply Virtual Offset can be used only if Virtual Offset is enabled for the Baking Set.", MessageType.Warning, "Open", () =>
                        {
                            ProbeVolumeLightingTab.OpenBakingSet(bakingSet);
                        });
                    }
                }
                else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.OverrideVirtualOffsetSettings)
                {
                    EditorGUI.BeginDisabledGroup(!useVirtualOffset);
                    EditorGUILayout.PropertyField(serialized.virtualOffsetThreshold, Styles.virtualOffsetThreshold);
                    EditorGUILayout.PropertyField(serialized.geometryBias);
                    EditorGUILayout.PropertyField(serialized.rayOriginBias);
                    EditorGUI.EndDisabledGroup();

                    if (!useVirtualOffset)
                    {
                        CoreEditorUtils.DrawFixMeBox("Override Virtual Offset can be used only if Virtual Offset is enabled for the Baking Set.", MessageType.Warning, "Open", () =>
                        {
                            ProbeVolumeLightingTab.OpenBakingSet(bakingSet);
                        });
                    }
                }
                else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.OverrideSampleCount)
                {
                    EditorGUILayout.LabelField("Probes", EditorStyles.miniBoldLabel);
                    using (new EditorGUI.IndentLevelScope())
                    {
                        EditorGUILayout.PropertyField(serialized.directSampleCount);
                        EditorGUILayout.PropertyField(serialized.indirectSampleCount);
                        EditorGUILayout.PropertyField(serialized.sampleCountMultiplier);
                        EditorGUILayout.PropertyField(serialized.maxBounces);
                    }

                    EditorGUILayout.Space();
                    EditorGUILayout.LabelField("Sky Occlusion", EditorStyles.miniBoldLabel);
                    using (new EditorGUI.DisabledGroupScope(bakingSet != null && !bakingSet.skyOcclusion))
                    using (new EditorGUI.IndentLevelScope())
                    {
                        EditorGUILayout.PropertyField(serialized.skyOcclusionSampleCount, Styles.skyOcclusionSampleCount);
                        EditorGUILayout.PropertyField(serialized.skyOcclusionMaxBounces, Styles.skyOcclusionMaxBounces);
                    }
                }
                else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.IntensityScale)
                {
                    EditorGUILayout.PropertyField(serialized.intensityScale);
                    EditorGUILayout.HelpBox("Overriding the intensity of probes can break the physical plausibility of lighting. This may result in unwanted visual inconsistencies.", MessageType.Info, wide: true);
                }
				else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.OverrideSkyDirection)
                {
                    if (!SupportedRenderingFeatures.active.skyOcclusion)
                    {
                        EditorGUILayout.HelpBox("Sky Occlusion is not supported by this Render Pipeline.", MessageType.Warning);
                        return;
                    }

                    var editMode = Styles.SkyDirectionEditMode;

                    EditorGUILayout.BeginHorizontal();
                    using (new EditorGUI.DisabledScope(!SupportedRenderingFeatures.active.skyOcclusion))
                    {
                        using (new EditorGUI.DisabledScope(editMode == EditMode.editMode))
                            EditorGUILayout.PropertyField(serialized.skyDirection);

                        EditorGUI.BeginChangeCheck();
                        GUILayout.Toggle(editMode == EditMode.editMode, Styles.s_SORotateTool, EditorStyles.miniButton, GUILayout.Width(28f));
                        if (EditorGUI.EndChangeCheck())
                        {
                            EditMode.SceneViewEditMode targetMode = EditMode.editMode == editMode ? EditMode.SceneViewEditMode.None : editMode;
                            EditMode.ChangeEditMode(targetMode, GetBounds(serialized, owner), owner);
                        }
                    }
                    EditorGUILayout.EndHorizontal();

                    if (!useSkyOcclusion)
                    {
                        CoreEditorUtils.DrawFixMeBox("Overriding Sky Direction can be used only if Sky Occlusion is enabled for the Baking Set.", MessageType.Warning, "Open", () =>
                        {
                            ProbeVolumeLightingTab.OpenBakingSet(bakingSet);
                        });
                    }
                }
                else if (serialized.mode.intValue == (int)ProbeAdjustmentVolume.Mode.OverrideRenderingLayerMask)
                {
                    if (bakingSet != null && !bakingSet.useRenderingLayers)
                    {
                        CoreEditorUtils.DrawFixMeBox("Override Rendering Layer can be used only if Rendering Layers are enabled for the Baking Set.", MessageType.Warning, "Open", () =>
                        {
                            ProbeVolumeLightingTab.OpenBakingSet(bakingSet);
                        });
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(serialized.renderingLayerMaskOperation, Styles.renderingLayerMaskOperation);

                        string[] options;
                        if (bakingSet != null)
                        {
                            options = new string[bakingSet.renderingLayerMasks.Length];
                            for (int i = 0; i < bakingSet.renderingLayerMasks.Length; i++)
                                options[i] = bakingSet.renderingLayerMasks[i].name;
                        }
                        else
                        {
                            options = new string[APVDefinitions.probeMaxRegionCount];
                            for (int i = 0; i < APVDefinitions.probeMaxRegionCount; i++)
                                options[i] = "Mask " + (i + 1);
                        }

                        if (options.Length == 0)
                        {
                            using (new EditorGUI.DisabledScope(true))
                                EditorGUILayout.MaskField(Styles.renderingLayerMask, 0, new[] { "Nothing" });
                        }
                        else
                        {
                            EditorGUI.BeginChangeCheck();
                            int newMask = EditorGUILayout.MaskField(Styles.renderingLayerMask, serialized.renderingLayerMask.intValue, options);
                            if (EditorGUI.EndChangeCheck())
                                serialized.renderingLayerMask.uintValue = (uint)newMask;
                        }
                    }
                }
            }

            static void DrawBakingHelpers(SerializedProbeAdjustmentVolume p, Editor owner)
            {
                ProbeAdjustmentVolume ptv = owner.target as ProbeAdjustmentVolume;
                var bakingSet = ProbeVolumeBakingSet.GetBakingSetForScene(ptv.gameObject.scene);

                if (owner.targets.Length == 1)
                {
                    EditorGUILayout.Space();
                    using (new EditorGUI.DisabledScope(Lightmapping.isRunning || bakingSet == null))
                    {
                        using (new EditorGUI.DisabledScope(AdaptiveProbeVolumes.isRunning))
                            if (GUILayout.Button(Styles.s_PreviewLighting))
                                AdaptiveProbeVolumes.BakeAdjustmentVolume(bakingSet, ptv);

                        ProbeVolumeLightingTab.BakeAPVButton();
                    }
                }

                if (ptv.cachedHashCode != ptv.GetHashCode())
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.HelpBox(Styles.s_AdjustmentVolumeChangedMessage, MessageType.Warning);
                }
            }

            internal static Bounds GetBounds(SerializedProbeAdjustmentVolume serialized, Editor owner)
            {
                var position = ((Component)owner.target).transform.position;
                if (serialized.shape.intValue == (int)ProbeAdjustmentVolume.Shape.Box)
                    return new Bounds(position, serialized.size.vector3Value);
                if (serialized.shape.intValue == (int)ProbeAdjustmentVolume.Shape.Box)
                    return new Bounds(position, serialized.radius.floatValue * Vector3.up);
                return default;
            }

            public static void DrawAdditionalContent(SerializedProbeAdjustmentVolume serialized, Editor owner)
            {
            }

            static ProbeAdjustmentVolumeUI()
            {
                Inspector = CED.Group(
                    CED.FoldoutGroup(Styles.s_VolumeHeader, Expandable.Volume, k_ExpandedState,
                        (serialized, owner) => DrawVolumeContent(serialized, owner)),
                    CED.AdditionalPropertiesFoldoutGroup(Styles.s_AdjustmentHeader, Expandable.Adjustments, k_ExpandedState, AdditionalProperties.Adjustments, k_AdditionalPropertiesState,
                        CED.Group((serialized, owner) => DrawAdjustmentContent(serialized, owner)), DrawAdditionalContent),
                    CED.Group(null, GroupOption.None, DrawBakingHelpers)
                );
            }
        }


        SerializedProbeAdjustmentVolume m_SerializedAdjustmentVolume;
        internal const EditMode.SceneViewEditMode k_EditShape = EditMode.SceneViewEditMode.ReflectionProbeBox;

        static HierarchicalBox _ShapeBox;
        static HierarchicalBox s_ShapeBox
        {
            get
            {
                if (_ShapeBox == null)
                    _ShapeBox = new HierarchicalBox(Styles.k_GizmoColorBase, Styles.k_BaseHandlesColor);
                return _ShapeBox;
            }
        }

        static HierarchicalSphere _ShapeSphere;
        static HierarchicalSphere s_ShapeSphere
        {
            get
            {
                if (_ShapeSphere == null)
                    _ShapeSphere = new HierarchicalSphere(Styles.k_GizmoColorBase);
                return _ShapeSphere;
            }
        }

        protected void OnEnable()
        {
            m_SerializedAdjustmentVolume = new SerializedProbeAdjustmentVolume(serializedObject);
            ProbeVolumeDebug.s_ActiveAdjustmentVolumes++;
        }

        protected void OnDisable()
        {
            ProbeVolumeDebug.s_ActiveAdjustmentVolumes--;
        }

        public override void OnInspectorGUI()
        {
            if (!ProbeReferenceVolume.instance.isInitialized || !ProbeReferenceVolume.instance.enabledBySRP)
            {
                ProbeVolumeEditor.APVDisabledHelpBox();
                return;
            }

            ProbeVolumeEditor.FrameSettingDisabledHelpBox();

            serializedObject.Update();
            ProbeAdjustmentVolumeUI.Inspector.Draw(m_SerializedAdjustmentVolume, this);
            serializedObject.ApplyModifiedProperties();
        }

        [DrawGizmo(GizmoType.InSelectionHierarchy)]
        static void DrawGizmosSelected(ProbeAdjustmentVolume adjustmentVolume, GizmoType gizmoType)
        {
            using (new Handles.DrawingScope(Matrix4x4.TRS(adjustmentVolume.transform.position, adjustmentVolume.transform.rotation, Vector3.one)))
            {
                if (adjustmentVolume.shape == ProbeAdjustmentVolume.Shape.Box)
                {
                    s_ShapeBox.center = Vector3.zero;
                    s_ShapeBox.size = adjustmentVolume.size;
                    s_ShapeBox.SetBaseColor(ProbeAdjustmentColorPreferences.GetColorPrefProbeVolumeGizmoColor());
                    s_ShapeBox.DrawHull(true);
                }
                else if (adjustmentVolume.shape == ProbeAdjustmentVolume.Shape.Sphere)
                {
                    s_ShapeSphere.center = Vector3.zero;
                    s_ShapeSphere.radius = adjustmentVolume.radius;
                    s_ShapeSphere.DrawHull(true);
                }

                if (adjustmentVolume.mode == ProbeAdjustmentVolume.Mode.ApplyVirtualOffset)
                {
                    ArrowHandle(0, Quaternion.Euler(adjustmentVolume.virtualOffsetRotation), adjustmentVolume.virtualOffsetDistance);
                }

            }
            using (new Handles.DrawingScope(Matrix4x4.TRS(adjustmentVolume.transform.position, Quaternion.identity, Vector3.one)))
            {
                if (adjustmentVolume.mode == ProbeAdjustmentVolume.Mode.OverrideSkyDirection)
                {
                    var editMode = Styles.SkyDirectionEditMode;
                    if (editMode != EditMode.editMode)
                    {
                        var quat = Quaternion.FromToRotation(Vector3.forward, adjustmentVolume.skyDirection);
                        adjustmentVolume.skyShadingDirectionRotation = quat.eulerAngles;
                    }

                    ArrowHandle(0, Quaternion.Euler(adjustmentVolume.skyShadingDirectionRotation), 1.0f);
                }
            }
        }

        static void ArrowHandle(int controlID, Quaternion rotation, float distance)
        {
            Handles.matrix *= Matrix4x4.Rotate(rotation);

            float thickness = Handles.lineThickness;
            float coneSize = .05f;

            var linePos = (distance - coneSize) * Vector3.forward;
            var conePos = (distance - coneSize * 0.5f) * Vector3.forward;

            if (distance < coneSize)
            {
                conePos = coneSize * 0.5f * Vector3.forward;
                Handles.matrix *= Matrix4x4.Scale(new Vector3(1, 1, distance / coneSize));
            }

            Handles.DrawLine(Vector3.zero, linePos, thickness);
            Handles.ConeHandleCap(controlID, conePos, Quaternion.identity, coneSize, EventType.Repaint);
        }

        protected void OnSceneGUI()
        {
            ProbeAdjustmentVolume adjustmentVolume = target as ProbeAdjustmentVolume;

            var position = Quaternion.Inverse(adjustmentVolume.transform.rotation) * adjustmentVolume.transform.position;

            //important: if the origin of the handle's space move along the handle,
            //handles displacement will appears as moving two time faster.
            using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, adjustmentVolume.transform.rotation, Vector3.one)))
            {
                if (adjustmentVolume.shape == ProbeAdjustmentVolume.Shape.Box)
                {
                    //contained must be initialized in all case
                    s_ShapeBox.center = position;
                    s_ShapeBox.size = adjustmentVolume.size;

                    s_ShapeBox.monoHandle = false;
                    EditorGUI.BeginChangeCheck();
                    s_ShapeBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObjects(new UnityEngine.Object[] { adjustmentVolume, adjustmentVolume.transform }, "Change Adjustment Volume Bounding Box");

                        adjustmentVolume.size = s_ShapeBox.size;
                        Vector3 delta = adjustmentVolume.transform.rotation * s_ShapeBox.center - adjustmentVolume.transform.position;
                        adjustmentVolume.transform.position += delta; ;
                    }
                }
                else if (adjustmentVolume.shape == ProbeAdjustmentVolume.Shape.Sphere)
                {
                    s_ShapeSphere.center = position;
                    s_ShapeSphere.radius = adjustmentVolume.radius;

                    EditorGUI.BeginChangeCheck();
                    s_ShapeSphere.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(adjustmentVolume, "Change Adjustment Volume Radius");
                        adjustmentVolume.radius = s_ShapeSphere.radius;
                    }
                }

                if (adjustmentVolume.mode == ProbeAdjustmentVolume.Mode.ApplyVirtualOffset && EditMode.editMode == Styles.VirtualOffsetEditMode)
                {
                    EditorGUI.BeginChangeCheck();
                    Quaternion rotation = Handles.RotationHandle(Quaternion.Euler(adjustmentVolume.virtualOffsetRotation), position);
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(adjustmentVolume, "Change Virtual Offset Direction");
                        adjustmentVolume.virtualOffsetRotation = rotation.eulerAngles;
                    }
                }
            }
            if (adjustmentVolume.mode == ProbeAdjustmentVolume.Mode.OverrideSkyDirection && EditMode.editMode == Styles.SkyDirectionEditMode)
            {
                EditorGUI.BeginChangeCheck();

                Quaternion rotation = Handles.RotationHandle(Quaternion.Euler(adjustmentVolume.skyShadingDirectionRotation), adjustmentVolume.transform.position);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(adjustmentVolume, "Change Sky Shading Direction");
                    adjustmentVolume.skyShadingDirectionRotation = rotation.eulerAngles;
                    adjustmentVolume.skyDirection = rotation * Vector3.forward;
                    adjustmentVolume.skyDirection.Normalize();
                }
            }
        }

        [MenuItem("CONTEXT/ProbeAdjustmentVolume/Rendering Debugger...")]
        internal static void AddAdjustmentVolumeContextMenu()
        {
            ProbeVolumeLightingTab.OpenProbeVolumeDebugPanel(null, null, 0);
        }
    }
}