private void PositionField(string name, BGCurvePointI point, BGCurve.Mode2DEnum mode2D, int index)
        {
            var math = mathProvider();

            Vector3          pos;
            Action <Vector3> newValueAction;
            string           tooltipDetails;
            string           details;

            switch ((BGCurveSettingsForEditor.CoordinateSpaceEnum)BGCurveSettingsForEditor.I.Get <int>(BGCurveSettingsForEditor.InspectorPointsCoordinatesKey))
            {
            case BGCurveSettingsForEditor.CoordinateSpaceEnum.World:
                pos            = math == null ? point.PositionWorld : math.GetPosition(index);
                newValueAction = vector3 => point.PositionWorld = vector3;
                tooltipDetails = "world";
                details        = "W";
                break;

            case BGCurveSettingsForEditor.CoordinateSpaceEnum.LocalTransformed:
                pos            = point.PositionLocalTransformed;
                newValueAction = vector3 => point.PositionLocalTransformed = vector3;
                tooltipDetails = "local transformed";
                details        = "LT";
                break;

            case BGCurveSettingsForEditor.CoordinateSpaceEnum.Local:
                pos            = point.PositionLocal;
                newValueAction = vector3 => point.PositionLocal = vector3;
                tooltipDetails = "local";
                details        = "L";
                break;

            default:
                throw new ArgumentOutOfRangeException("BGCurveSettingsForEditor.InspectorPointCoordinates");
            }

            BGEditorUtility.SwapLabelWidth(80, () =>
            {
                var label   = name + "(" + details + ")";
                var tooltip = "Point's position in " + tooltipDetails + " space. You can change points space in BGCurve Editor settings (gear icon)";

                if (mode2D == BGCurve.Mode2DEnum.Off)
                {
                    BGEditorUtility.Vector3Field(label, tooltip, pos, newValueAction);
                }
                else
                {
                    Vector2Field(label, tooltip, pos, mode2D, newValueAction);
                }
            });
        }
        private void Vector2Field(string label, string tooltip, Vector3 value, BGCurve.Mode2DEnum mode2D, Action <Vector3> newValueAction)
        {
            Vector2 val;

            switch (mode2D)
            {
            case BGCurve.Mode2DEnum.XY:
                val = value;
                break;

            case BGCurve.Mode2DEnum.XZ:
                val = new Vector2(value.x, value.z);
                break;

            case BGCurve.Mode2DEnum.YZ:
                val = new Vector2(value.y, value.z);
                break;

            default:
                throw new ArgumentOutOfRangeException("mode2D", mode2D, null);
            }

            BGEditorUtility.Vector2Field(label, tooltip, val, vector2 =>
            {
                Vector3 newValue;
                switch (mode2D)
                {
                case BGCurve.Mode2DEnum.XY:
                    newValue = vector2;
                    break;

                case BGCurve.Mode2DEnum.XZ:
                    newValue = new Vector3(vector2.x, 0, vector2.y);
                    break;

                case BGCurve.Mode2DEnum.YZ:
                    newValue = new Vector3(0, vector2.x, vector2.y);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("mode2D", mode2D, null);
                }
                newValueAction(newValue);
            });
        }
        public static void SwapVector2Labels(BGCurve.Mode2DEnum mode2D, Action action)
        {
            var needToSwap = mode2D != BGCurve.Mode2DEnum.Off && mode2D != BGCurve.Mode2DEnum.XY;

            GUIContent[] oldLabels = null;
            if (needToSwap)
            {
                oldLabels = BGPrivateField.Get <GUIContent[]>(typeof(EditorGUI), "s_XYLabels");
                GUIContent[] newLabels;
                switch (mode2D)
                {
                case BGCurve.Mode2DEnum.XZ:
                    newLabels = XZLabels;
                    break;

                case BGCurve.Mode2DEnum.YZ:
                    newLabels = YZLabels;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("mode2D", mode2D, null);
                }
                BGPrivateField.Set(typeof(EditorGUI), "s_XYLabels", newLabels);
            }

            try
            {
                action();
            }
            finally
            {
                if (needToSwap)
                {
                    BGPrivateField.Set(typeof(EditorGUI), "s_XYLabels", oldLabels);
                }
            }
        }
        private void ControlField(BGCurvePointI point, BGCurve.Mode2DEnum mode2D, int index)
        {
            Vector3          pos;
            string           tooltipDetails, details;
            Action <Vector3> newValueAction;

            switch ((BGCurveSettingsForEditor.CoordinateSpaceEnum)BGCurveSettingsForEditor.I.Get <int>(BGCurveSettingsForEditor.InspectorControlsCoordinatesKey))
            {
            case BGCurveSettingsForEditor.CoordinateSpaceEnum.Local:
                tooltipDetails = "local";
                details        = "L";
                if (index == 1)
                {
                    pos            = point.ControlFirstLocal;
                    newValueAction = vector3 => point.ControlFirstLocal = vector3;
                }
                else
                {
                    pos            = point.ControlSecondLocal;
                    newValueAction = vector3 => point.ControlSecondLocal = vector3;
                }
                break;

            case BGCurveSettingsForEditor.CoordinateSpaceEnum.LocalTransformed:
                tooltipDetails = "local transformed";
                details        = "LT";

                if (index == 1)
                {
                    pos            = point.ControlFirstLocalTransformed;
                    newValueAction = vector3 => point.ControlFirstLocalTransformed = vector3;
                }
                else
                {
                    pos            = point.ControlSecondLocalTransformed;
                    newValueAction = vector3 => point.ControlSecondLocalTransformed = vector3;
                }
                break;

            case BGCurveSettingsForEditor.CoordinateSpaceEnum.World:
                tooltipDetails = "world";
                details        = "W";

                if (index == 1)
                {
                    pos            = point.ControlFirstWorld;
                    newValueAction = vector3 => point.ControlFirstWorld = vector3;
                }
                else
                {
                    pos            = point.ControlSecondWorld;
                    newValueAction = vector3 => point.ControlSecondWorld = vector3;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("BGCurveSettingsForEditor.InspectorPointControlsCoordinates");
            }

            var label   = "Control " + index + " (" + details + ")";
            var tooltip = "Point " + (index == 0 ? "1st" : "2nd") + " control position in " + tooltipDetails + " space. You can change points space in BGCurve Editor settings (gear icon)";



            if (mode2D == BGCurve.Mode2DEnum.Off)
            {
                BGEditorUtility.Vector3Field(label, tooltip, pos, newValueAction);
            }
            else
            {
                Vector2Field(label, tooltip, pos, mode2D, newValueAction);
            }
        }