private static bool InternalAddParameter(TimelineClip clip, string parameterName, ref EditorCurveBinding binding, out SerializedProperty property)
        {
            property = null;
            bool result;

            if (clip.IsParameterAnimated(parameterName))
            {
                result = false;
            }
            else
            {
                SerializedObject serializedObject = AnimatedParameterExtensions.GetSerializedObject(clip);
                if (serializedObject == null)
                {
                    result = false;
                }
                else
                {
                    property = serializedObject.FindProperty(parameterName);
                    if (property == null || !AnimatedParameterExtensions.IsAnimatable(property.get_propertyType()))
                    {
                        result = false;
                    }
                    else
                    {
                        AnimatedParameterExtensions.CreateCurvesIfRequired(clip, null);
                        binding = clip.GetCurveBinding(parameterName);
                        result  = true;
                    }
                }
            }
            return(result);
        }
        internal static bool ProcessPlayableAssetRecording(UndoPropertyModification mod, WindowState state, TimelineClip clip)
        {
            if (mod.currentValue == null)
            {
                return(false);
            }

            if (!clip.IsParameterAnimatable(mod.currentValue.propertyPath))
            {
                return(false);
            }

            // don't use time global to local since it will possibly loop.
            double localTime = clip.ToLocalTimeUnbound(state.editSequence.time);

            if (localTime < 0)
            {
                return(false);
            }

            // grab the value from the current modification
            float fValue = 0;

            if (!float.TryParse(mod.currentValue.value, out fValue))
            {
                // case 916913 -- 'Add Key' menu item will passes 'True' or 'False' (instead of 1, 0)
                // so we need a special case to parse the boolean string
                bool bValue = false;
                if (!bool.TryParse(mod.currentValue.value, out bValue))
                {
                    Debug.Assert(false, "Invalid type in PlayableAsset recording");
                    return(false);
                }

                fValue = bValue ? 1 : 0;
            }

            bool added = (clip.AddAnimatedParameterValueAt(mod.currentValue.propertyPath, fValue, (float)localTime));

            if (added && AnimationMode.InAnimationMode())
            {
                EditorCurveBinding binding = clip.GetCurveBinding(mod.previousValue.propertyPath);
                AnimationMode.AddPropertyModification(binding, mod.previousValue, true);
                clip.parentTrack.SetShowInlineCurves(true);
                if (state.GetWindow() != null && state.GetWindow().treeView != null)
                {
                    state.GetWindow().treeView.CalculateRowRects();
                }
            }
            return(added);
        }
        public static bool SetAnimatedParameter(this TimelineClip clip, string parameterName, AnimationCurve curve)
        {
            bool result;

            if (!clip.IsParameterAnimated(parameterName) && !clip.AddAnimatedParameter(parameterName))
            {
                result = false;
            }
            else
            {
                EditorCurveBinding curveBinding = clip.GetCurveBinding(parameterName);
                AnimationUtility.SetEditorCurve(clip.curves, curveBinding, curve);
                result = true;
            }
            return(result);
        }
        public static bool RemoveAnimatedParameter(this TimelineClip clip, string parameterName)
        {
            bool result;

            if (!clip.IsParameterAnimated(parameterName) || clip.curves == null)
            {
                result = false;
            }
            else
            {
                EditorCurveBinding curveBinding = clip.GetCurveBinding(parameterName);
                AnimationUtility.SetEditorCurve(clip.curves, curveBinding, null);
                result = true;
            }
            return(result);
        }
        public static bool IsParameterAnimated(this TimelineClip clip, string parameterName)
        {
            bool result;

            if (clip == null)
            {
                result = false;
            }
            else if (clip.curves == null)
            {
                result = false;
            }
            else
            {
                EditorCurveBinding   binding  = clip.GetCurveBinding(parameterName);
                EditorCurveBinding[] bindings = AnimationClipCurveCache.Instance.GetCurveInfo(clip.curves).bindings;
                result = bindings.Any((EditorCurveBinding x) => AnimatedParameterExtensions.MatchBinding(x, binding.propertyName));
            }
            return(result);
        }
        public static bool AddAnimatedParameterValueAt(this TimelineClip clip, string parameterName, float value, float time)
        {
            bool result;

            if (!clip.IsParameterAnimatable(parameterName))
            {
                result = false;
            }
            else
            {
                AnimatedParameterExtensions.CreateCurvesIfRequired(clip, null);
                EditorCurveBinding curveBinding       = clip.GetCurveBinding(parameterName);
                AnimationCurve     animationCurve     = AnimationUtility.GetEditorCurve(clip.curves, curveBinding) ?? new AnimationCurve();
                SerializedObject   serializedObject   = AnimatedParameterExtensions.GetSerializedObject(clip);
                SerializedProperty serializedProperty = serializedObject.FindProperty(parameterName);
                bool stepped = serializedProperty.get_propertyType() == 1 || serializedProperty.get_propertyType() == null || serializedProperty.get_propertyType() == 7;
                CurveEditUtility.AddKeyFrameToCurve(animationCurve, time, clip.curves.get_frameRate(), value, stepped);
                AnimationUtility.SetEditorCurve(clip.curves, curveBinding, animationCurve);
                result = true;
            }
            return(result);
        }
        public static AnimationCurve GetAnimatedParameter(this TimelineClip clip, string parameterName)
        {
            AnimationCurve result;

            if (clip == null || clip.curves == null)
            {
                result = null;
            }
            else
            {
                ScriptableObject scriptableObject = clip.asset as ScriptableObject;
                if (scriptableObject == null)
                {
                    result = null;
                }
                else
                {
                    EditorCurveBinding curveBinding = clip.GetCurveBinding(parameterName);
                    result = AnimationUtility.GetEditorCurve(clip.curves, curveBinding);
                }
            }
            return(result);
        }