public void UpdateMove(IEnumerable <ItemsPerTrack> itemsGroups)
        {
            if (m_Detached)
            {
                return;
            }

            m_TrackLocked = true;

            var overlap = 0.0;

            foreach (var itemsGroup in itemsGroups)
            {
                var track = itemsGroup.targetTrack;
                if (track == null)
                {
                    continue;
                }

                var prevItemInfo = m_PreviousItem[track];
                if (prevItemInfo.item != null)
                {
                    var prevItem = prevItemInfo.item;

                    var firstItem = itemsGroup.items.OrderBy(c => c.start).First();

                    if (prevItemInfo.blending)
                    {
                        prevItemInfo.blending = prevItem.end > firstItem.start;
                    }

                    if (prevItemInfo.blending)
                    {
                        var b = EditModeUtils.BlendDuration(firstItem, TrimEdge.End);
                        overlap = Math.Max(overlap, Math.Max(prevItem.start, prevItem.end - firstItem.end + firstItem.start + b) - firstItem.start);
                    }
                    else
                    {
                        overlap = Math.Max(overlap, prevItem.end - firstItem.start);
                    }
                }
            }

            if (overlap > 0)
            {
                foreach (var itemsGroup in itemsGroups)
                {
                    foreach (var item in itemsGroup.items)
                    {
                        item.start += overlap;
                    }
                }
            }

            var newEnd = itemsGroups.Max(m => m.items.Max(c => c.end));

            var offset = newEnd - m_PreviousEnd;

            m_PreviousEnd = newEnd;

            foreach (var itemsGroup in itemsGroups)
            {
                foreach (var item in m_NextItems[itemsGroup.targetTrack])
                {
                    item.start += offset;
                }
            }
        }
        public void OnBeforeTrim(ITrimmable item, TrimEdge trimDirection)
        {
            m_Item = item;

            var sortedItems = ItemsUtils.GetItemsExcept(item.parentTrack, new[] { item })
                              .OfType <ITrimmable>()
                              .OrderBy(c => c.start);

            var itemStart = (DiscreteTime)item.start;
            var itemEnd   = (DiscreteTime)item.end;

            var overlapped = sortedItems.LastOrDefault(c => (DiscreteTime)c.start == itemStart && (DiscreteTime)c.end == itemEnd);

            ITrimmable nextItem;
            ITrimmable prevItem;

            m_Min = 0.0;
            m_Max = double.PositiveInfinity;

            var blendableItem = item as IBlendable;

            if (blendableItem != null && blendableItem.supportsBlending)
            {
                if (trimDirection == TrimEdge.Start)
                {
                    nextItem = sortedItems.FirstOrDefault(c => (DiscreteTime)c.start >= itemStart && (DiscreteTime)c.end > itemEnd);
                    prevItem = sortedItems.LastOrDefault(c => (DiscreteTime)c.start <= itemStart && (DiscreteTime)c.end < itemEnd);

                    if (prevItem != null)
                    {
                        m_Min = prevItem.start + EditModeUtils.BlendDuration(prevItem, TrimEdge.Start);
                    }

                    if (nextItem != null)
                    {
                        m_Max = nextItem.start;
                    }
                }
                else
                {
                    nextItem = sortedItems.FirstOrDefault(c => c != overlapped && (DiscreteTime)c.start >= itemStart && (DiscreteTime)c.end >= itemEnd);
                    prevItem = sortedItems.LastOrDefault(c => c != overlapped && (DiscreteTime)c.start <= itemStart && (DiscreteTime)c.end <= itemEnd);

                    if (prevItem != null)
                    {
                        m_Min = prevItem.end;
                    }

                    if (nextItem != null)
                    {
                        m_Max = nextItem.end - EditModeUtils.BlendDuration(nextItem, TrimEdge.End);
                    }
                }
            }
            else
            {
                nextItem = sortedItems.FirstOrDefault(c => (DiscreteTime)c.start > itemStart);
                prevItem = sortedItems.LastOrDefault(c => (DiscreteTime)c.start < itemStart);

                if (prevItem != null)
                {
                    m_Min = prevItem.end;
                }

                if (nextItem != null)
                {
                    m_Max = nextItem.start;
                }
            }
        }
        public void OnBeforeTrim(ITrimmable item, TrimEdge trimDirection)
        {
            m_Item = item;

            var sortedClips = ItemsUtils.GetItemsExcept(item.parentTrack, new[] { item })
                              .OfType <ITrimmable>()
                              .OrderBy(c => c.start);

            var clipStart = (DiscreteTime)item.start;
            var clipEnd   = (DiscreteTime)item.end;

            var overlapped = sortedClips.LastOrDefault(c => (DiscreteTime)c.start == clipStart && (DiscreteTime)c.end == clipEnd);

            ITrimmable nextItem;
            ITrimmable prevItem;

            m_Min = 0.0;
            m_Max = double.PositiveInfinity;

            if (trimDirection == TrimEdge.Start)
            {
                nextItem = sortedClips.FirstOrDefault(c => (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end > clipEnd);
                prevItem = sortedClips.LastOrDefault(c => (DiscreteTime)c.start <= clipStart && (DiscreteTime)c.end < clipEnd);

                if (prevItem != null)
                {
                    m_Min = prevItem.start + EditModeUtils.BlendDuration(prevItem, TrimEdge.Start) + TimelineClip.kMinDuration;
                }

                if (nextItem != null)
                {
                    m_Max = nextItem.start;
                }

                m_ItemToBeReplaced = prevItem;

                if (m_ItemToBeReplaced != null)
                {
                    m_ClipOriginalEdgeValue = m_ItemToBeReplaced.end;
                }
            }
            else
            {
                nextItem = sortedClips.FirstOrDefault(c => c != overlapped && (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end >= clipEnd);
                prevItem = sortedClips.LastOrDefault(c => c != overlapped && (DiscreteTime)c.start <= clipStart && (DiscreteTime)c.end <= clipEnd);

                if (prevItem != null)
                {
                    m_Min = prevItem.end;
                }

                if (nextItem != null)
                {
                    m_Max = nextItem.end - EditModeUtils.BlendDuration(nextItem, TrimEdge.End) - TimelineClip.kMinDuration;
                }

                m_ItemToBeReplaced = nextItem;

                if (m_ItemToBeReplaced != null)
                {
                    m_ClipOriginalEdgeValue = m_ItemToBeReplaced.start;
                }
            }

            m_TrimReplace = false;
        }