public static async Task <IEvent> Paste(EventPanelViewmodelBase destination, PasteLocation location)
 {
     return(await Task.Run(() =>
     {
         var dest = destination.Event;
         if (CanPaste(destination, location))
         {
             var operation = _operation;
             using (var enumerator = Clipboard.GetEnumerator())
             {
                 if (!enumerator.MoveNext())
                 {
                     return null;
                 }
                 dest = _paste(enumerator.Current, dest, location, operation);
                 while (enumerator.MoveNext())
                 {
                     dest = _paste(enumerator.Current, dest, PasteLocation.After, operation);
                 }
             }
         }
         if (_operation == ClipboardOperation.Cut)
         {
             Clipboard.Clear();
         }
         return dest;
     }));
 }
        public static bool CanPaste(EventPanelViewmodelBase destEventVm, PasteLocation location)
        {
            if (destEventVm?.Event == null)
            {
                return(false);
            }
            IEventProperties dest = destEventVm.Event;
            var operation         = _operation;
            var destStartType     = dest.StartType;

            if (location != PasteLocation.Under &&
                (destStartType == TStartType.Manual || destStartType == TStartType.OnFixedTime) &&
                Clipboard.Any(e => e.EventType != TEventType.Rundown))
            {
                return(false);
            }
            using (var enumerator = Clipboard.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                {
                    return(false);
                }
                if (!_canPaste(enumerator.Current, dest, location, operation))
                {
                    return(false);
                }
                dest = enumerator.Current;
                while (enumerator.MoveNext())
                {
                    if (!_canPaste(enumerator.Current, dest, PasteLocation.After, operation))
                    {
                        return(false);
                    }
                    dest = enumerator.Current;
                }
            }
            return(true);
        }
        private static bool _canPaste(IEventProperties source, IEventProperties dest, PasteLocation location, ClipboardOperation operation)
        {
            var sourceEvent = source as IEvent;
            var destEvent   = dest as IEvent;

            if (source == null ||
                (operation == ClipboardOperation.Cut && (destEvent == null || sourceEvent?.Engine != destEvent.Engine)) ||
                (destEvent != null && !destEvent.HaveRight(EventRight.Create)))
            {
                return(false);
            }
            if (location == PasteLocation.Under)
            {
                if (dest.EventType == TEventType.StillImage)
                {
                    return(false);
                }
                if ((dest.EventType == TEventType.Movie || dest.EventType == TEventType.Live) && source.EventType != TEventType.StillImage)
                {
                    return(false);
                }
                if (dest.EventType == TEventType.Rundown && (source.EventType == TEventType.StillImage || destEvent?.SubEventsCount > 0))
                {
                    return(false);
                }
                if (dest.EventType == TEventType.Container && source.EventType != TEventType.Rundown)
                {
                    return(false);
                }
            }
            if (location == PasteLocation.After || location == PasteLocation.Before)
            {
                if (!(source.EventType == TEventType.Rundown ||
                      source.EventType == TEventType.Movie ||
                      source.EventType == TEventType.Live)
                    ||
                    !(dest.EventType == TEventType.Rundown ||
                      dest.EventType == TEventType.Movie ||
                      dest.EventType == TEventType.Live)
                    )
                {
                    return(false);
                }
            }
            if (operation == ClipboardOperation.Cut && destEvent.IsContainedIn(sourceEvent))
            {
                return(false);
            }
            return(true);
        }
        static IEvent _paste(IEventProperties source, IEvent dest, PasteLocation location, ClipboardOperation operation)
        {
            if (operation == ClipboardOperation.Cut)
            {
                if (source is IEvent sourceEvent)
                {
                    if (sourceEvent.Engine == dest.Engine)
                    {
                        sourceEvent.Remove();
                        switch (location)
                        {
                        case PasteLocation.After:
                            dest.InsertAfter(sourceEvent);
                            break;

                        case PasteLocation.Before:
                            dest.InsertBefore(sourceEvent);
                            break;

                        case PasteLocation.Under:
                            dest.InsertUnder(sourceEvent, false);
                            break;
                        }
                        return(sourceEvent);
                    }
                    else
                    {
                        //TODO: paste from another engine
                        throw new NotImplementedException("Event engines are different");
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Cannot paste from type: {source?.GetType().Name}");
                }
            }
            else //(operation == ClipboardOperation.Copy)
            {
                if (source is EventProxy sourceProxy)
                {
                    var mediaFiles     = (dest.Engine.MediaManager.MediaDirectoryPRI ?? dest.Engine.MediaManager.MediaDirectorySEC)?.GetAllFiles();
                    var animationFiles = (dest.Engine.MediaManager.AnimationDirectoryPRI ?? dest.Engine.MediaManager.AnimationDirectorySEC)?.GetAllFiles();
                    switch (location)
                    {
                    case PasteLocation.After:
                        return(sourceProxy.InsertAfter(dest, mediaFiles, animationFiles));

                    case PasteLocation.Before:
                        return(sourceProxy.InsertBefore(dest, mediaFiles, animationFiles));

                    case PasteLocation.Under:
                        var newEvent = sourceProxy.InsertUnder(dest, false, mediaFiles, animationFiles);
                        if (dest.EventType == TEventType.Container)
                        {
                            newEvent.ScheduledTime = EventExtensions.DefaultScheduledTime;
                        }
                        return(newEvent);
                    }
                    throw new InvalidOperationException("Invalid paste location");
                }
                else
                {
                    throw new InvalidOperationException($"Cannot paste from type: {source?.GetType().Name}");
                }
            }
        }