/// <inheritdoc/>
        public virtual SegmentViewModelBase CreateSplitSegmentModelViewModel(SegmentViewModelBase segmentViewModelToSplit, int frameNumberToSplitAt)
        {
            KeyFrameViewModelCollection splitKeyFrameViewModels = new KeyFrameViewModelCollection();

            if (segmentViewModelToSplit.ActiveKeyFrame?.FrameNumber >= frameNumberToSplitAt)
            {
                segmentViewModelToSplit.ActiveKeyFrame = null;
            }

            int keyFrameIndex = segmentViewModelToSplit.KeyFrameViewModels.LowerBoundIndex(frameNumberToSplitAt);

            if (keyFrameIndex < segmentViewModelToSplit.KeyFrameViewModels.Count)
            {
                KeyFrameViewModelBase keyFrameViewModel = segmentViewModelToSplit.KeyFrameViewModels[keyFrameIndex];
                if (keyFrameViewModel.FrameNumber > frameNumberToSplitAt)
                {
                    // Lerp new KeyFrameViewModel and add to splitKeyFrameViewModels
                    Debug.Assert(keyFrameIndex > 0);

                    keyFrameViewModel = segmentViewModelToSplit.KeyFrameViewModels[keyFrameIndex - 1].Lerp(frameNumberToSplitAt, keyFrameViewModel);

                    splitKeyFrameViewModels.Add(keyFrameViewModel);
                }

                // Loop from keyFrameIndex and move (via remove & add) KeyFrameViewModel(s) to splitKeyFrameViewModels
                do
                {
                    keyFrameViewModel = segmentViewModelToSplit.KeyFrameViewModels[keyFrameIndex];

                    segmentViewModelToSplit.KeyFrameViewModels.RemoveAt(keyFrameIndex);
                    segmentViewModelToSplit.Model.KeyFrames.RemoveAt(keyFrameIndex);

                    splitKeyFrameViewModels.Add(keyFrameViewModel);
                } while (keyFrameIndex < segmentViewModelToSplit.KeyFrameViewModels.Count);
            }
            else
            {
                // Lerp new KeyFrameViewModel and add to splitKeyFrameViewModels
                KeyFrameModelBase keyFrameModel = segmentViewModelToSplit.Model.KeyFrames.Last(kfm => kfm.FrameNumber < frameNumberToSplitAt).DeepCopy();
                keyFrameModel.FrameNumber = frameNumberToSplitAt;

                splitKeyFrameViewModels.Add(segmentViewModelToSplit.CreateKeyFrameViewModel(keyFrameModel));
            }

            int splitViewModelEndFrame = segmentViewModelToSplit.EndFrame;

            segmentViewModelToSplit.EndFrame = frameNumberToSplitAt - 1;

            return(CreateSegmentModelViewModel(segmentViewModelToSplit, segmentViewModelToSplit.TrackNumber,
                                               frameNumberToSplitAt, splitViewModelEndFrame, segmentViewModelToSplit.Name,
                                               splitKeyFrameViewModels));
        }
        /// <summary>
        /// Gets a <see cref="KeyFrameModelCollection"/> containing the data models of key frame view models in a <see cref="KeyFrameViewModelCollection"/>,
        /// optionally creating deep copies of the data models and offsetting the key frame numbers.
        /// </summary>
        /// <param name="keyFrameViewModels">The source <see cref="KeyFrameViewModelCollection"/>.</param>
        /// <param name="createCopies">Whether to create deep copies of the data models. Defaults to false.</param>
        /// <param name="frameOffset">The number of frames to offset the frame numbers of the data models by. Defaults to zero.</param>
        /// <returns>
        /// A <see cref="KeyFrameModelCollection"/> containing the data models of key frame view models in the <see cref="KeyFrameViewModelCollection"/>
        /// which have been deep copied and/or frame offset if so specified.
        /// </returns>
        protected KeyFrameModelCollection GetKeyFrameModels(KeyFrameViewModelCollection keyFrameViewModels, bool createCopies = false, int frameOffset = 0)
        {
            KeyFrameModelCollection keyFrameModels = new KeyFrameModelCollection();

            for (int i = 0; i < keyFrameViewModels.Count; i++)
            {
                KeyFrameModelBase keyFrameModel = createCopies ? keyFrameViewModels[i].Model.DeepCopy() : keyFrameViewModels[i].Model;
                if (frameOffset != 0)
                {
                    keyFrameModel.FrameNumber += frameOffset;
                }

                keyFrameModels.Add(keyFrameModel);
            }

            return(keyFrameModels);
        }
        /// <inheritdoc/>
        public override SegmentViewModelBase CreateSegmentModelViewModel(SegmentViewModelBase sourceViewModel, int?trackNumber = null, int?startFrame = null, int?endFrame = null, string name = null, KeyFrameViewModelCollection keyFrameViewModels = null)
        {
            int    newTrackNumber = trackNumber.GetValueOrDefault(sourceViewModel.TrackNumber);
            int    newStartFrame  = startFrame.GetValueOrDefault(sourceViewModel.StartFrame);
            int    newEndFrame    = endFrame.GetValueOrDefault(sourceViewModel.EndFrame);
            string newName        = name ?? sourceViewModel.Name;

            KeyFrameModelCollection keyFrameModels = keyFrameViewModels != null
                                                     ? GetKeyFrameModels(keyFrameViewModels)
                                                     : GetKeyFrameModels(sourceViewModel.KeyFrameViewModels, true, newStartFrame - sourceViewModel.StartFrame);

            return(new MockSegmentViewModel(
                       new MockSegmentModel(newStartFrame, newEndFrame, newTrackNumber, keyFrameModels, newName),
                       _scriptVideoContext, _rootUndoObject, _undoService, _undoChangeFactory, _clipboardService, keyFrameViewModels
                       ));
        }
 /// <inheritdoc/>
 public abstract SegmentViewModelBase CreateSegmentModelViewModel(SegmentViewModelBase sourceViewModel, int?trackNumber = null, int?startFrame = null, int?endFrame = null, string name = null, KeyFrameViewModelCollection keyFrameViewModels = null);
 /// <summary>
 /// Base constructor for masking shape segment view models derived from the <see cref="MaskShapeViewModelBase"/> class.
 /// </summary>
 /// <inheritdoc cref="SegmentViewModelBase(SegmentModelBase, IScriptVideoContext, object, IUndoService, IChangeFactory, IClipboardService, KeyFrameViewModelCollection)"/>
 protected MaskShapeViewModelBase(SegmentModelBase model, IScriptVideoContext scriptVideoContext, object rootUndoObject, IUndoService undoService, IChangeFactory undoChangeFactory, IClipboardService clipboardService, KeyFrameViewModelCollection keyFrameViewModels = null) : base(model, scriptVideoContext, rootUndoObject, undoService, undoChangeFactory, clipboardService, keyFrameViewModels)
 {
 }