public TourTL copy()
 {
     TourParallelTL tl = new TourParallelTL();
     tl.type = type;
     tl.displayName = displayName;
     tl.file = file;
     tl.inkCanvas = inkCanvas;
     return tl;
 }
        public void LoadDictFromXML(String xmlFileName)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlFileName);

            if (doc.HasChildNodes)
            {
                foreach (XmlNode tourNode in doc.ChildNodes)
                {
                    if (tourNode.Name == "TourStoryboard")
                    {
                        tourStoryboard = new TourStoryboard();
                        tourStoryboard.displayName = tourNode.Attributes.GetNamedItem("displayName").InnerText;
                        tourStoryboard.description = tourNode.Attributes.GetNamedItem("description").InnerText;
                        //// Time experiment
                        tourStoryboard.totalDuration = double.Parse(tourNode.Attributes.GetNamedItem("duration").InnerText);

                        dockableItemsLoaded = new List<DockableItem>();
                        msiItemsLoaded = new List<MultiScaleImage>();
                        tourBiDictionary = new BiDictionary<Timeline, BiDictionary<double, TourEvent>>();
                        undoStack = new Stack<BiDictionary<Timeline, BiDictionary<double, TourEvent>>>();
                        redoStack = new Stack<BiDictionary<Timeline, BiDictionary<double, TourEvent>>>();
                        itemToTLDict = new Dictionary<DockableItem, Timeline>();
                        msiToTLDict = new Dictionary<MultiScaleImage, Timeline>();

                        foreach (XmlNode TLNode in tourNode.ChildNodes)
                        {
                            if (TLNode.Name == "TourParallelTL")
                            {
                                if (TLNode.Attributes.GetNamedItem("type").InnerText == "artwork")
                                {
                                    String msi_file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    String msi_tour_path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Data\\Images\\DeepZoom\\" + msi_file + "\\dz.xml";
                                    artModeWin.msi_tour.SetImageSource(msi_tour_path);
                                    artModeWin.msi_tour_thumb.SetImageSource(msi_tour_path);

                                    msiItemsLoaded.Add(artModeWin.msi_tour);
                                    artModeWin.msi_tour.PreviewTouchDown += new EventHandler<TouchEventArgs>(msiTouchDown);
                                    artModeWin.msi_tour.PreviewMouseDown += new MouseButtonEventHandler(msiTouchDown);
                                    artModeWin.msi_tour.PreviewTouchMove += new EventHandler<TouchEventArgs>(msiTouchMoved);
                                    artModeWin.msi_tour.PreviewMouseMove += new MouseEventHandler(msiTouchMoved);
                                    artModeWin.msi_tour.PreviewTouchUp += new EventHandler<TouchEventArgs>(msiTouchUp);
                                    artModeWin.msi_tour.PreviewMouseUp += new MouseButtonEventHandler(msiTouchUp);
                                    artModeWin.msi_tour.PreviewMouseWheel += new MouseWheelEventHandler(msiMouseWheel);
                                    artModeWin.msi_tour.disableInertia();
                                    TourParallelTL msi_tour_TL = new TourParallelTL();

                                    msiToTLDict.Add(artModeWin.msi_tour, msi_tour_TL);

                                    msi_tour_TL.type = TourTLType.artwork;
                                    msi_tour_TL.displayName = TLNode.Attributes.GetNamedItem("displayName").InnerText;
                                    msi_tour_TL.file = TLNode.Attributes.GetNamedItem("file").InnerText;

                                    BiDictionary<double, TourEvent> msi_tour_TL_dict = new BiDictionary<double, TourEvent>();
                                    tourBiDictionary.Add(msi_tour_TL, msi_tour_TL_dict);

                                    foreach (XmlNode TourEventNode in TLNode.ChildNodes)
                                    {
                                        if (TourEventNode.Name == "TourEvent")
                                        {
                                            if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "ZoomMSIEvent")
                                            {
                                                double scale = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("scale").InnerText);
                                                double toMSIPointX = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toMSIPointX").InnerText);
                                                double toMSIPointY = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toMSIPointY").InnerText);
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);
                                                TourEvent zoomMSIEvent = new ZoomMSIEvent(artModeWin.msi_tour, scale, toMSIPointX, toMSIPointY, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                msi_tour_TL_dict.Add(beginTime, zoomMSIEvent);
                                            }
                                        }
                                    }
                                }

                                else if (TLNode.Attributes.GetNamedItem("type").InnerText == "media")
                                {
                                    String media_file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    DockableItem dockItem = new DockableItem(artModeWin.MSIScatterView, artModeWin, artModeWin.Bar, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Data\\Images\\Metadata\\" + media_file);

                                    dockItem.PreviewMouseMove += new MouseEventHandler(mediaTouchDown);
                                    dockItem.PreviewTouchDown += new EventHandler<TouchEventArgs>(mediaTouchDown);
                                    dockItem.PreviewMouseDown += new MouseButtonEventHandler(mediaTouchDown);
                                    dockItem.PreviewTouchMove += new EventHandler<TouchEventArgs>(mediaTouchMoved);
                                    dockItem.PreviewMouseMove += new MouseEventHandler(mediaTouchMoved);
                                    dockItem.PreviewTouchUp += new EventHandler<TouchEventArgs>(mediaTouchUp);
                                    dockItem.PreviewMouseUp += new MouseButtonEventHandler(mediaTouchUp);

                                    dockableItemsLoaded.Add(dockItem);
                                    dockItem.Visibility = Visibility.Hidden;

                                    TourParallelTL dockItem_TL = new TourParallelTL();
                                    dockItem_TL.type = TourTLType.media;

                                    dockItem_TL.displayName = TLNode.Attributes.GetNamedItem("displayName").InnerText;
                                    dockItem_TL.file = TLNode.Attributes.GetNamedItem("file").InnerText;

                                    itemToTLDict.Add(dockItem, dockItem_TL);

                                    BiDictionary<double, TourEvent> dockItem_TL_dict = new BiDictionary<double, TourEvent>();
                                    tourBiDictionary.Add(dockItem_TL, dockItem_TL_dict);

                                    foreach (XmlNode TourEventNode in TLNode.ChildNodes)
                                    {
                                        if (TourEventNode.Name == "TourEvent")
                                        {
                                            if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeInMediaEvent")
                                            {
                                                double toScreenPointX = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toScreenPointX").InnerText);
                                                double toScreenPointY = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toScreenPointY").InnerText);
                                                double scale = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("scale").InnerText);
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeInMediaEvent = new FadeInMediaEvent(dockItem, toScreenPointX, toScreenPointY, scale, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                dockItem_TL_dict.Add(beginTime, fadeInMediaEvent);
                                            }

                                            else if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "ZoomMediaEvent")
                                            {
                                                double scale = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("scale").InnerText);
                                                double toScreenPointX = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toScreenPointX").InnerText);
                                                double toScreenPointY = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("toScreenPointY").InnerText);
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent zoomMediaEvent = new ZoomMediaEvent(dockItem, scale, toScreenPointX, toScreenPointY, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                dockItem_TL_dict.Add(beginTime, zoomMediaEvent);
                                            }

                                            else if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeOutMediaEvent")
                                            {
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeOutMediaEvent = new FadeOutMediaEvent(dockItem, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                dockItem_TL_dict.Add(beginTime, fadeOutMediaEvent);
                                            }
                                        }
                                    }
                                }

                                else if (TLNode.Attributes.GetNamedItem("type").InnerText == "highlight")
                                {
                                    String media_file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    SurfaceInkCanvas sic = new SurfaceInkCanvas();
                                    inkCanvases.Add(sic);
                                    sic.Width = 1920;
                                    sic.Height = 1080;
                                    sic.DefaultDrawingAttributes.Width = 50;
                                    sic.DefaultDrawingAttributes.Height = 50;
                                    sic.UsesTouchShape = false;
                                    sic.Background = Brushes.Transparent;
                                    sic.Opacity = 0.7;
                                    sic.Visibility = Visibility.Visible;
                                    Canvas.SetZIndex(sic, 50);
                                    loadInkCanvas(sic, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "/" + media_file);
                                    artModeWin.ImageArea.Children.Add(sic);

                                    TourParallelTL tourtl = new TourParallelTL();
                                    tourtl.type = TourTLType.highlight;
                                    tourtl.inkCanvas = sic;
                                    tourtl.displayName = TLNode.Attributes.GetNamedItem("displayName").InnerText;
                                    tourtl.file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    BiDictionary<double, TourEvent> tldict = new BiDictionary<double, TourEvent>();
                                    tourBiDictionary.Add(tourtl, tldict);

                                    foreach (XmlNode TourEventNode in TLNode.ChildNodes)
                                    {
                                        if (TourEventNode.Name == "TourEvent")
                                        {
                                            if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeInHighlightEvent")
                                            {
                                                double opacity = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("opacity").InnerText);
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeInHighlightEvent = new FadeInHighlightEvent(sic, duration, opacity);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                tldict.Add(beginTime, fadeInHighlightEvent);
                                            }

                                            else if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeOutHighlightEvent")
                                            {
                                                double opacity = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("opacity").InnerText);
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeOutHighlightEvent = new FadeOutHighlightEvent(sic, duration, opacity);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                tldict.Add(beginTime, fadeOutHighlightEvent);
                                            }
                                        }
                                    }
                                }

                                else if (TLNode.Attributes.GetNamedItem("type").InnerText == "path")
                                {
                                    String media_file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    SurfaceInkCanvas sic = new SurfaceInkCanvas();
                                    inkCanvases.Add(sic);
                                    sic.Width = 1920;
                                    sic.Height = 1080;
                                    sic.UsesTouchShape = true;
                                    sic.DefaultDrawingAttributes.FitToCurve = true;
                                    sic.Background = Brushes.Transparent;
                                    sic.Opacity = 0;
                                    sic.Visibility = Visibility.Visible;
                                    Canvas.SetZIndex(sic, 50);
                                    loadInkCanvas(sic, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "/" + media_file);
                                    artModeWin.ImageArea.Children.Add(sic);

                                    TourParallelTL tourtl = new TourParallelTL();
                                    tourtl.type = TourTLType.path;
                                    tourtl.inkCanvas = sic;
                                    tourtl.displayName = TLNode.Attributes.GetNamedItem("displayName").InnerText;
                                    tourtl.file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                    BiDictionary<double, TourEvent> tldict = new BiDictionary<double, TourEvent>();
                                    tourBiDictionary.Add(tourtl, tldict);

                                    foreach (XmlNode TourEventNode in TLNode.ChildNodes)
                                    {
                                        if (TourEventNode.Name == "TourEvent")
                                        {
                                            if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeInPathEvent")
                                            {
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeInPathEvent = new FadeInPathEvent(sic, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                tldict.Add(beginTime, fadeInPathEvent);
                                            }

                                            else if (TourEventNode.Attributes.GetNamedItem("type").InnerText == "FadeOutPathEvent")
                                            {
                                                double duration = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("duration").InnerText);

                                                TourEvent fadeOutPathEvent = new FadeOutPathEvent(sic, duration);

                                                double beginTime = Convert.ToDouble(TourEventNode.Attributes.GetNamedItem("beginTime").InnerText);
                                                tldict.Add(beginTime, fadeOutPathEvent);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (TLNode.Name == "TourMediaTL")
                            {
                                String audio_file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                TourMediaTL tourAudio_TL = new TourMediaTL(new Uri(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Data\\Tour\\Audio\\" + audio_file, UriKind.Absolute));
                                tourAudio_TL.type = TourTLType.audio;
                                tourAudio_TL.displayName = TLNode.Attributes.GetNamedItem("displayName").InnerText;
                                tourAudio_TL.file = TLNode.Attributes.GetNamedItem("file").InnerText;
                                if (TLNode.Attributes.GetNamedItem("beginTime") != null)
                                    tourAudio_TL.BeginTime = TimeSpan.FromSeconds(Convert.ToDouble(TLNode.Attributes.GetNamedItem("beginTime").InnerText));

                                if (TLNode.Attributes.GetNamedItem("duration") != null)
                                    tourAudio_TL.Duration = TimeSpan.FromSeconds(Convert.ToDouble(TLNode.Attributes.GetNamedItem("duration").InnerText));
                                else
                                {
                                    TagLib.File audio_file_tags = TagLib.File.Create(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Data\\Tour\\Audio\\" + audio_file);
                                    tourAudio_TL.Duration = audio_file_tags.Properties.Duration;
                                }

                                BiDictionary<double, TourEvent> tourAudio_TL_dict = new BiDictionary<double, TourEvent>(); // dummy TL_dict -- tourAudio_timeline obviously doesn't store any TourEvents
                                tourBiDictionary.Add(tourAudio_TL, tourAudio_TL_dict);

                                tourAudio_element = new MediaElement();
                                tourAudio_element.Volume = 0.99;

                                tourAudio_element.LoadedBehavior = MediaState.Manual;
                                tourAudio_element.UnloadedBehavior = MediaState.Manual;

                                Storyboard.SetTarget(tourAudio_TL, tourAudio_element);
                                tourStoryboard.SlipBehavior = SlipBehavior.Slip;

                                // took me quite a while to figure out that WPF really can't determine the duration of an MP3 until it's actually loaded (i.e. playing), and then it took me a little longer to finally find and accept this open-source library...argh

                            }
                        }
                    }
                }
            }
        }
        public void MakeNewPathCanvas()
        {
            currentPathCanvas = new SurfaceInkCanvas();
            currentPathCanvas.DefaultDrawingAttributes.FitToCurve = true;
            inkCanvases.Add(currentPathCanvas);
            currentPathCanvas.Width = 1920;
            currentPathCanvas.Height = 1080;
            currentPathCanvas.UsesTouchShape = true;
            currentPathCanvas.Background = Brushes.Transparent;
            Canvas.SetZIndex(currentPathCanvas, 50);
            artModeWin.ImageArea.Children.Add(currentPathCanvas);
            TourEvent fadeIn = new FadeInPathEvent(currentPathCanvas, 1);
            fadeIn.type = TourEvent.Type.fadeInPath;
            TourEvent fadeOut = new FadeOutPathEvent(currentPathCanvas, 1);
            fadeOut.type = TourEvent.Type.fadeOutPath;

            TourParallelTL tourtl = new TourParallelTL();
            tourtl.type = TourTLType.path;
            tourtl.inkCanvas = currentPathCanvas;
            tourtl.displayName = "Drawing";
            tourtl.file = getNextFile("Path");
            currentPathCanvasFile = tourtl.file;
            BiDictionary<double, TourEvent> tlbidict = new BiDictionary<double, TourEvent>();
            double start = authorTimerCountSpan.TotalSeconds;
            if (start < 1) start = 1;
            authorTimerCountSpan = TimeSpan.FromSeconds(start);
            tlbidict.Add(start - 1, fadeIn);
            tlbidict.Add(start + 1, fadeOut);
            tourBiDictionary.Add(tourtl, tlbidict);
            if (!tourAuthoringOn)
                currentPathCanvas.IsHitTestVisible = false;
            tourAuthoringUI.refreshUI();
        }
        public void AddNewMetaDataTimeline(String imageFilePath, String fileName)
        {
            DockableItem dockItem = new DockableItem(artModeWin.MSIScatterView, artModeWin, artModeWin.Bar, imageFilePath);

            dockItem.PreviewMouseWheel += new MouseWheelEventHandler(mediaMouseWheel);
            dockItem.removeDockability();
            dockItem.PreviewMouseMove += new MouseEventHandler(mediaTouchDown);
            dockItem.PreviewTouchDown += new EventHandler<TouchEventArgs>(mediaTouchDown);
            dockItem.PreviewMouseDown += new MouseButtonEventHandler(mediaTouchDown);
            dockItem.PreviewTouchMove += new EventHandler<TouchEventArgs>(mediaTouchMoved);
            dockItem.PreviewMouseMove += new MouseEventHandler(mediaTouchMoved);
            dockItem.PreviewTouchUp += new EventHandler<TouchEventArgs>(mediaTouchUp);
            dockItem.PreviewMouseUp += new MouseButtonEventHandler(mediaTouchUp);

            dockableItemsLoaded.Add(dockItem);
            dockItem.Visibility = Visibility.Hidden;

            TourParallelTL dockItem_TL = new TourParallelTL();
            dockItem_TL.type = TourTLType.media;

            dockItem_TL.displayName = fileName;
            dockItem_TL.file = System.IO.Path.GetFileName(imageFilePath);

            itemToTLDict.Add(dockItem, dockItem_TL);

            BiDictionary<double, TourEvent> dockItem_TL_dict = new BiDictionary<double, TourEvent>();

            tourBiDictionary.Add(dockItem_TL, dockItem_TL_dict);

            // Add fade in
            double toScreenPointX = 500;
            double toScreenPointY = 500;
            double scale = 1.0;
            double FadeInduration = 1.0;

            TourEvent fadeInMediaEvent = new FadeInMediaEvent(dockItem, toScreenPointX, toScreenPointY, scale, FadeInduration);

            double FadeInbeginTime = authorTimerCountSpan.TotalSeconds - 1;
            if (FadeInbeginTime < 0) FadeInbeginTime = 0;
            if (authorTimerCountSpan.TotalSeconds == 0) FadeInbeginTime += 1;
            authorTimerCountSpan = TimeSpan.FromSeconds(FadeInbeginTime+1);
            dockItem_TL_dict.Add(FadeInbeginTime, fadeInMediaEvent);

            // Add fade out
            double FadeOutduration = 1.0;

            TourEvent fadeOutMediaEvent = new FadeOutMediaEvent(dockItem, FadeOutduration);

            double FadeOutbeginTime = FadeInbeginTime + 2;
            dockItem_TL_dict.Add(FadeOutbeginTime, fadeOutMediaEvent);

            TourAuthoringUI.timelineInfo tli = tourAuthoringUI.addTimeline(dockItem_TL, dockItem_TL_dict, fileName, tourAuthoringUI.getNextPos());
            tourAuthoringUI.addTourEvent(tli, fadeInMediaEvent, tli.lengthSV, FadeInbeginTime, FadeInduration);
            tourAuthoringUI.addTourEvent(tli, fadeOutMediaEvent, tli.lengthSV, FadeOutbeginTime, FadeOutduration);
            tourAuthoringUI.timelineCount += 1;
            tourAuthoringUI.updateTLSize();

            StopAndReloadTourAuthoringUIFromDict(authorTimerCountSpan.TotalSeconds);

            tourAuthoringUI.refreshUI();
        }
        /// <summary>
        /// Adding of animations for each TourEvent during loading of tourDict --> tourStoryboard
        /// </summary>
        /// <param name="tourParallelTL"></param>
        /// <param name="tourEvent"></param>
        /// <param name="timerCount"></param>
        public void addAnim(TourParallelTL tourParallelTL, TourEvent tourEvent, double timerCount)
        {
            switch (tourEvent.type)
            {
                case TourEvent.Type.fadeInMedia:
                    FadeInMediaEvent fadeInMediaEvent = (FadeInMediaEvent)tourEvent;

                    // used to use MSI points, but now using screen points -- see artwork mode documentation in Google Doc
                    Point mediaPoint = new Point();
                    mediaPoint.X = fadeInMediaEvent.fadeInMediaToScreenPointX;
                    mediaPoint.Y = fadeInMediaEvent.fadeInMediaToScreenPointY;

                    double initialScale = fadeInMediaEvent.absoluteScale;

                    DockableItem fadeInMediaItem = fadeInMediaEvent.media;
                    fadeInMediaItem.ApplyAnimationClock(DockableItem.CenterProperty, null);
                    fadeInMediaItem.Center = mediaPoint;
                    fadeInMediaItem.Width = fadeInMediaItem.image.Source.Width * initialScale;
                    fadeInMediaItem.Height = fadeInMediaItem.image.Source.Height * initialScale;
                    fadeInMediaItem.Orientation = 0;

                    DoubleAnimation fadeInMediaWidth = new DoubleAnimation(fadeInMediaItem.Width, fadeInMediaItem.Width, new Duration(TimeSpan.FromSeconds(0.0)));
                    Storyboard.SetTarget(fadeInMediaWidth, fadeInMediaItem);
                    Storyboard.SetTargetProperty(fadeInMediaWidth, new PropertyPath(DockableItem.WidthProperty));
                    fadeInMediaWidth.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInMediaWidth);

                    DoubleAnimation fadeInMediaHeight = new DoubleAnimation(fadeInMediaItem.Height, fadeInMediaItem.Height, new Duration(TimeSpan.FromSeconds(0.0)));
                    Storyboard.SetTarget(fadeInMediaHeight, fadeInMediaItem);
                    Storyboard.SetTargetProperty(fadeInMediaHeight, new PropertyPath(DockableItem.HeightProperty));
                    fadeInMediaHeight.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInMediaHeight);

                    PointAnimation fadeInMediaCenter = new PointAnimation(fadeInMediaItem.Center, fadeInMediaItem.Center, new Duration(TimeSpan.FromSeconds(0.0)));
                    Storyboard.SetTarget(fadeInMediaCenter, fadeInMediaItem);
                    Storyboard.SetTargetProperty(fadeInMediaCenter, new PropertyPath(DockableItem.CenterProperty));
                    fadeInMediaCenter.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInMediaCenter);

                    ObjectAnimationUsingKeyFrames fadeInMediaAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeInMediaAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeInMediaAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Visible, new TimeSpan(0, 0, 0));
                    fadeInMediaAnim_vis.KeyFrames.Add(fadeInMediaAnim_vis_kf1);
                    Storyboard.SetTarget(fadeInMediaAnim_vis, fadeInMediaItem);
                    Storyboard.SetTargetProperty(fadeInMediaAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeInMediaAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInMediaAnim_vis);

                    DoubleAnimation fadeInMediaAnim = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(fadeInMediaEvent.duration)));
                    Storyboard.SetTarget(fadeInMediaAnim, fadeInMediaItem);
                    Storyboard.SetTargetProperty(fadeInMediaAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeInMediaAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInMediaAnim);

                    break;

                case TourEvent.Type.fadeOutMedia:
                    FadeOutMediaEvent fadeOutMediaEvent = (FadeOutMediaEvent)tourEvent;

                    DockableItem fadeOutMediaItem = fadeOutMediaEvent.media;
                    fadeOutMediaItem.ApplyAnimationClock(DockableItem.CenterProperty, null);
                    DoubleAnimation fadeOutMediaAnim = new DoubleAnimation(1.0, 0.0, new Duration(TimeSpan.FromSeconds(fadeOutMediaEvent.duration)));
                    Storyboard.SetTarget(fadeOutMediaAnim, fadeOutMediaItem);
                    Storyboard.SetTargetProperty(fadeOutMediaAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeOutMediaAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeOutMediaAnim);

                    ObjectAnimationUsingKeyFrames fadeOutMediaAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeOutMediaAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeOutMediaAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Hidden, new TimeSpan(0, 0, 0));
                    fadeOutMediaAnim_vis.KeyFrames.Add(fadeOutMediaAnim_vis_kf1);
                    Storyboard.SetTarget(fadeOutMediaAnim_vis, fadeOutMediaItem);
                    Storyboard.SetTargetProperty(fadeOutMediaAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeOutMediaAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount + fadeOutMediaEvent.duration);
                    tourParallelTL.Children.Add(fadeOutMediaAnim_vis);

                    break;
                case TourEvent.Type.zoomMedia:
                    ZoomMediaEvent zoomMediaEvent = (ZoomMediaEvent)tourEvent;

                    DockableItem zoomMediaItem = zoomMediaEvent.media;
                    zoomMediaItem.ApplyAnimationClock(DockableItem.CenterProperty, null);
                    double targetMediaScale = zoomMediaEvent.absoluteScale;

                    DoubleAnimation zoomWidth = new DoubleAnimation(zoomMediaItem.image.Source.Width * targetMediaScale, new Duration(TimeSpan.FromSeconds(zoomMediaEvent.duration)));
                    Storyboard.SetTarget(zoomWidth, zoomMediaItem);
                    Storyboard.SetTargetProperty(zoomWidth, new PropertyPath(DockableItem.WidthProperty));
                    zoomWidth.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(zoomWidth);

                    DoubleAnimation zoomHeight = new DoubleAnimation(zoomMediaItem.image.Source.Height * targetMediaScale, new Duration(TimeSpan.FromSeconds(zoomMediaEvent.duration)));
                    Storyboard.SetTarget(zoomHeight, zoomMediaItem);
                    Storyboard.SetTargetProperty(zoomHeight, new PropertyPath(DockableItem.HeightProperty));
                    zoomHeight.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(zoomHeight);

                    // used to use MSI points, but now using screen points -- see artwork mode documentation in Google Doc
                    Point zoomEndPoint = new Point();
                    zoomEndPoint.X = zoomMediaEvent.zoomMediaToScreenPointX;
                    zoomEndPoint.Y = zoomMediaEvent.zoomMediaToScreenPointY;

                    PointAnimation zoomMediaPan = new PointAnimation(zoomEndPoint, new Duration(TimeSpan.FromSeconds(zoomMediaEvent.duration)), FillBehavior.HoldEnd);
                    Storyboard.SetTarget(zoomMediaPan, zoomMediaItem);
                    Storyboard.SetTargetProperty(zoomMediaPan, new PropertyPath(DockableItem.CenterProperty));
                    zoomMediaPan.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(zoomMediaPan);

                    break;
                case TourEvent.Type.zoomMSI:
                    ZoomMSIEvent zoomMSIEvent = (ZoomMSIEvent)tourEvent;

                    double targetMSIScale = zoomMSIEvent.absoluteScale;

                    Point zoomToMSIPoint = new Point(zoomMSIEvent.zoomToMSIPointX, zoomMSIEvent.zoomToMSIPointY);

                    // new
                    ZoomableCanvas zoomMSI_canvas = zoomMSIEvent.msi.GetZoomableCanvas;
                    targetMSIScale = zoomMSIEvent.msi.ClampTargetScale(targetMSIScale);

                    Point targetOffset = new Point(zoomToMSIPoint.X, zoomToMSIPoint.Y);

                    PointAnimation zoomMSI_pan = new PointAnimation(targetOffset, new Duration(TimeSpan.FromSeconds(zoomMSIEvent.duration)));
                    Storyboard.SetTarget(zoomMSI_pan, zoomMSI_canvas);
                    Storyboard.SetTargetProperty(zoomMSI_pan, new PropertyPath(ZoomableCanvas.OffsetProperty));
                    zoomMSI_pan.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(zoomMSI_pan);

                    DoubleAnimation zoomMSI_scale = new DoubleAnimation(targetMSIScale, new Duration(TimeSpan.FromSeconds(zoomMSIEvent.duration)));
                    zoomMSI_scale.CurrentStateInvalidated += new EventHandler(ZoomMSI_scale_CurrentStateInvalidated);
                    Storyboard.SetTarget(zoomMSI_scale, zoomMSI_canvas);
                    Storyboard.SetTargetProperty(zoomMSI_scale, new PropertyPath(ZoomableCanvas.ScaleProperty));
                    zoomMSI_scale.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(zoomMSI_scale);

                    break;
                case TourEvent.Type.fadeInPath:
                    FadeInPathEvent fadeInPathEvent = (FadeInPathEvent)tourEvent;

                    // used to use MSI points, but now using screen points -- see artwork mode documentation in Google Doc

                    SurfaceInkCanvas fadeInPathItem = fadeInPathEvent.inkCanvas;
                    fadeInPathItem.Opacity = 0.0;

                    ObjectAnimationUsingKeyFrames fadeInPathAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeInPathAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeInPathAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Visible, new TimeSpan(0, 0, 0));
                    fadeInPathAnim_vis.KeyFrames.Add(fadeInPathAnim_vis_kf1);
                    Storyboard.SetTarget(fadeInPathAnim_vis, fadeInPathItem);
                    Storyboard.SetTargetProperty(fadeInPathAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeInPathAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInPathAnim_vis);
                    fadeInPathAnim_vis.FillBehavior = FillBehavior.Stop;

                    DoubleAnimation fadeInPathAnim = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(fadeInPathEvent.duration)));
                    Storyboard.SetTarget(fadeInPathAnim, fadeInPathItem);
                    Storyboard.SetTargetProperty(fadeInPathAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeInPathAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInPathAnim);
                    //fadeInPathAnim.FillBehavior = FillBehavior.Stop;

                    break;
                case TourEvent.Type.fadeOutPath:
                    FadeOutPathEvent fadeOutPathEvent = (FadeOutPathEvent)tourEvent;

                    SurfaceInkCanvas fadeOutPathItem = fadeOutPathEvent.inkCanvas;
                    DoubleAnimation fadeOutPathAnim = new DoubleAnimation(1.0, 0.0, new Duration(TimeSpan.FromSeconds(fadeOutPathEvent.duration)));
                    Storyboard.SetTarget(fadeOutPathAnim, fadeOutPathItem);
                    Storyboard.SetTargetProperty(fadeOutPathAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeOutPathAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeOutPathAnim);

                    ObjectAnimationUsingKeyFrames fadeOutPathAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeOutPathAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeOutPathAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Hidden, new TimeSpan(0, 0, 0));
                    fadeOutPathAnim_vis.KeyFrames.Add(fadeOutPathAnim_vis_kf1);
                    Storyboard.SetTarget(fadeOutPathAnim_vis, fadeOutPathItem);
                    Storyboard.SetTargetProperty(fadeOutPathAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeOutPathAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount + fadeOutPathEvent.duration);
                    tourParallelTL.Children.Add(fadeOutPathAnim_vis);

                    break;

                case TourEvent.Type.fadeInHighlight:

                    FadeInHighlightEvent fadeInHighlightEvent = (FadeInHighlightEvent)tourEvent;

                    // used to use MSI points, but now using screen points -- see artwork mode documentation in Google Doc

                    SurfaceInkCanvas fadeInHighlightItem = fadeInHighlightEvent.inkCanvas;
                    fadeInHighlightItem.Opacity = 0.0;

                    ObjectAnimationUsingKeyFrames fadeInHighlightAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeInHighlightAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeInHighlightAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Visible, new TimeSpan(0, 0, 0));
                    fadeInHighlightAnim_vis.KeyFrames.Add(fadeInHighlightAnim_vis_kf1);
                    Storyboard.SetTarget(fadeInHighlightAnim_vis, fadeInHighlightItem);
                    Storyboard.SetTargetProperty(fadeInHighlightAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeInHighlightAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInHighlightAnim_vis);
                    fadeInHighlightAnim_vis.FillBehavior = FillBehavior.Stop;

                    DoubleAnimation fadeInHighlightAnim = new DoubleAnimation(0.0, fadeInHighlightEvent.opacity, new Duration(TimeSpan.FromSeconds(fadeInHighlightEvent.duration)));
                    Storyboard.SetTarget(fadeInHighlightAnim, fadeInHighlightItem);
                    Storyboard.SetTargetProperty(fadeInHighlightAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeInHighlightAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeInHighlightAnim);

                    break;
                case TourEvent.Type.fadeOutHighlight:
                    FadeOutHighlightEvent fadeOutHighlightEvent = (FadeOutHighlightEvent)tourEvent;

                    SurfaceInkCanvas fadeOutHighlightItem = fadeOutHighlightEvent.inkCanvas;
                    DoubleAnimation fadeOutHighlightAnim = new DoubleAnimation(fadeOutHighlightEvent.opacity, 0.0, new Duration(TimeSpan.FromSeconds(fadeOutHighlightEvent.duration)));
                    Storyboard.SetTarget(fadeOutHighlightAnim, fadeOutHighlightItem);
                    Storyboard.SetTargetProperty(fadeOutHighlightAnim, new PropertyPath(DockableItem.OpacityProperty));
                    fadeOutHighlightAnim.BeginTime = TimeSpan.FromSeconds(timerCount);
                    tourParallelTL.Children.Add(fadeOutHighlightAnim);

                    ObjectAnimationUsingKeyFrames fadeOutHighlightAnim_vis = new ObjectAnimationUsingKeyFrames();
                    fadeOutHighlightAnim_vis.Duration = new TimeSpan(0, 0, 0);
                    DiscreteObjectKeyFrame fadeOutHighlightAnim_vis_kf1 = new DiscreteObjectKeyFrame(Visibility.Hidden, new TimeSpan(0, 0, 0));
                    fadeOutHighlightAnim_vis.KeyFrames.Add(fadeOutHighlightAnim_vis_kf1);
                    Storyboard.SetTarget(fadeOutHighlightAnim_vis, fadeOutHighlightItem);
                    Storyboard.SetTargetProperty(fadeOutHighlightAnim_vis, new PropertyPath(DockableItem.VisibilityProperty));
                    fadeOutHighlightAnim_vis.BeginTime = TimeSpan.FromSeconds(timerCount + fadeOutHighlightEvent.duration);
                    tourParallelTL.Children.Add(fadeOutHighlightAnim_vis);

                    break;
                default:
                    break;
            }
        }