/// <summary>
        /// Remove a keyframe of component.
        /// </summary>
        public void RemoveKeyframe(SpriteAnimationKeyFrame kf)
        {
            List<SpriteAnimationKeyFrame> tmp = new List<SpriteAnimationKeyFrame>(keyFrames);
            tmp.Remove(kf);
            tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer);
            keyFrames = tmp.ToArray();

            CalcCurve(null);
        }
        /// <summary>
        /// Calculate the curves of component.
        /// </summary>
        public void CalcCurve(SpriteAnimationKeyFrame newKf)
        {
            _maxIndex = GetMaxIndex();

            List<SpriteAnimationKeyFrame> tmp = new List<SpriteAnimationKeyFrame>(keyFrames);
            tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer);
            keyFrames = tmp.ToArray();

            ApplyCurveChangeToKeyframe();

            List<SpriteAnimationCurve> tmpCurves = new List<SpriteAnimationCurve>();
            for (int i = (int)SpriteAnimationCurveType.KeyframeIndex, e = (int)SpriteAnimationCurveType.ShearY; i <= e; i++)
            {
                SpriteAnimationCurve curve = new SpriteAnimationCurve();

                curve.type = (SpriteAnimationCurveType)i;
                curve.curve = new AnimationCurve();

                foreach (SpriteAnimationCurve _curve in curves)
                {
                    if (_curve.type == curve.type)
                        curve.interpolation = _curve.interpolation;
                }

                tmpCurves.Add(curve);
            }

            float tick = 1f / clip.frameRate;
            int idx = 0;

            tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve = new AnimationCurve();
            tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].interpolation = true;

            foreach (SpriteAnimationKeyFrame kf in keyFrames)
            {
                float time = kf.frameIndex * tick; ;
                kf.isSpriteValid = kf.sprite != null;

                bool needSmooth = kf == newKf;

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex], time, idx + 0.005f, false, 0, false);

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.PositionX], time, kf.position.x, true, 1, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.PositionY], time, kf.position.y, true, 0, needSmooth);

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.Rotate], time, kf.rotation, true, 0, needSmooth);

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ScaleX], time, kf.scale.x, true, 0, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ScaleY], time, kf.scale.y, true, 0, needSmooth);

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ShearX], time, kf.shear.x, true, 0, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ShearY], time, kf.shear.y, true, 0, needSmooth);

                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorR], time, kf.color.r, true, 0, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorG], time, kf.color.g, true, 0, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorB], time, kf.color.b, true, 0, needSmooth);
                AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorA], time, kf.color.a, true, 0, needSmooth);

                idx++;
            }


            //for (int i = 0, e = tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve.keys.Length; i < e; i++)
            //    tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve.SmoothTangents(i, 1f);


            //remove curves if values never change
            tmpCurves.RemoveAll(delegate(SpriteAnimationCurve curve)
            {
                if (curve.type == SpriteAnimationCurveType.KeyframeIndex)
                    return false;

                bool ret = true;

                Keyframe fkf = curve.curve.keys[0];
                curve.defaultValue = fkf.value;

                bool isFkDef = fkf.value == GetDefaultValue(curve.type);

                foreach (Keyframe kf in curve.curve.keys)
                {
                    if (fkf.value != kf.value)
                        return false;
                }


                if (!isFkDef)
                {
                    curve.length = 0;
                    return false;
                }

                return ret;
            });


            foreach (SpriteAnimationCurve curve in tmpCurves)
            {
                if (curve.type == SpriteAnimationCurveType.KeyframeIndex)
                    continue;

                if (!curve.interpolation)
                {
                    Keyframe[] kfs = curve.curve.keys;
                    curve.curve = new AnimationCurve();

                    for (int i = 0, e = kfs.Length; i < e; i++)
                    {
                        Keyframe kf = kfs[i];
                        kf.inTangent = float.PositiveInfinity;
                        kf.outTangent = float.NegativeInfinity;

                        curve.curve.AddKey(kf);
                    }
                }
            }

            curves = tmpCurves.ToArray();
        }
        /// <summary>
        /// Add a keyframe of component.
        /// </summary>
        public void AddKeyframe(SpriteAnimationKeyFrame kf)
        {
            float tick = 1f / clip.frameRate;
            kf.time = kf.frameIndex * tick;

            List<SpriteAnimationKeyFrame> tmp = new List<SpriteAnimationKeyFrame>(keyFrames);
            tmp.Add(kf);
            tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer);
            keyFrames = tmp.ToArray();

            CalcCurve(kf);
        }