public void ClearTrack(int trackIndex)
        {
            if (trackIndex >= tracks.Count)
            {
                return;
            }
            TrackEntry current = tracks.Items[trackIndex];

            if (current == null)
            {
                return;
            }

            current.OnEnd(this, trackIndex);
            if (End != null)
            {
                End(this, trackIndex);
            }

            tracks.Items[trackIndex] = null;
        }
        private void SetCurrent(int index, TrackEntry entry)
        {
            TrackEntry current = ExpandToIndex(index);

            if (current != null)
            {
                TrackEntry previous = current.previous;
                current.previous = null;

                current.OnEnd(this, index);
                if (End != null)
                {
                    End(this, index);
                }

                entry.mixDuration = data.GetMix(current.animation, entry.animation);
                if (entry.mixDuration > 0)
                {
                    entry.mixTime = 0;
                    // If a mix is in progress, mix from the closest animation.
                    if (previous != null && current.mixTime / current.mixDuration < 0.5f)
                    {
                        entry.previous = previous;
                    }
                    else
                    {
                        entry.previous = current;
                    }
                }
            }

            tracks.Items[index] = entry;

            entry.OnStart(this, index);
            if (Start != null)
            {
                Start(this, index);
            }
        }
        override public String ToString()
        {
            StringBuilder buffer = new StringBuilder();

            for (int i = 0, n = tracks.Count; i < n; i++)
            {
                TrackEntry entry = tracks.Items[i];
                if (entry == null)
                {
                    continue;
                }
                if (buffer.Length > 0)
                {
                    buffer.Append(", ");
                }
                buffer.Append(entry.ToString());
            }
            if (buffer.Length == 0)
            {
                return("<none>");
            }
            return(buffer.ToString());
        }
        public void Apply(Skeleton skeleton)
        {
            ExposedList <Event> events = this.events;

            for (int i = 0; i < tracks.Count; i++)
            {
                TrackEntry current = tracks.Items[i];
                if (current == null)
                {
                    continue;
                }

                events.Clear();

                float time = current.time;
                bool  loop = current.loop;
                if (!loop && time > current.endTime)
                {
                    time = current.endTime;
                }

                TrackEntry previous = current.previous;
                if (previous == null)
                {
                    if (current.mix == 1)
                    {
                        current.animation.Apply(skeleton, current.lastTime, time, loop, events);
                    }
                    else
                    {
                        current.animation.Mix(skeleton, current.lastTime, time, loop, events, current.mix);
                    }
                }
                else
                {
                    float previousTime = previous.time;
                    if (!previous.loop && previousTime > previous.endTime)
                    {
                        previousTime = previous.endTime;
                    }
                    previous.animation.Apply(skeleton, previous.lastTime, previousTime, previous.loop, null);
                    // Remove the line above, and uncomment the line below, to allow previous animations to fire events during mixing.
                    //previous.animation.Apply(skeleton, previous.lastTime, previousTime, previous.loop, events);
                    previous.lastTime = previousTime;

                    float alpha = current.mixTime / current.mixDuration * current.mix;
                    if (alpha >= 1)
                    {
                        alpha            = 1;
                        current.previous = null;
                    }
                    current.animation.Mix(skeleton, current.lastTime, time, loop, events, alpha);
                }

                for (int ii = 0, nn = events.Count; ii < nn; ii++)
                {
                    Event e = events.Items[ii];
                    current.OnEvent(this, i, e);
                    if (Event != null)
                    {
                        Event(this, i, e);
                    }
                }

                current.lastTime = current.time;
            }
        }