void Redisplay()
        {
            //reset
            SelectorMode       = KeySelectorMode.Start;
            selectedStartFrame = selectedEndFrame = 0;
            cursorShown        = false;
            endCursor          = startCursor = cursor = null;
            space = null;
            KeySelector.Children.Clear();

            //display sequences
            foreach (var seq in _sequences)
            {
                if (seq.IsRootSeq)
                {
                    continue;
                }
                SolidColorBrush randomColor     = new SolidColorBrush(AppResources.BatchRandomColor(1)[0]);
                Brush           semiTransparent = new SolidColorBrush(randomColor.Color);
                semiTransparent.Opacity = .5;
                Border border = null;
                KeySelector.Children.Add(
                    border = new Border
                {
                    Child = new TextBlock()
                    {
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment   = VerticalAlignment.Center,
                        Text          = (string.IsNullOrWhiteSpace(seq.Name) ? seq.ID.ToString() : seq.Name + $" ({seq.ID})") + $": {seq.FrameLength} frames",
                        Padding       = new Thickness(5, 3, 5, 3),
                        TextWrapping  = TextWrapping.Wrap,
                        Background    = randomColor,
                        TextAlignment = TextAlignment.Center
                    },
                    Padding         = new Thickness(10),
                    BorderBrush     = randomColor,
                    BorderThickness = new Thickness(2, 0, 2, 0),
                    Background      = semiTransparent,
                    Width           = (seq.FrameLength / (double)blitz3DAnimation.Frames) * KeySelector.ActualWidth,
                    Height          = KeySelector.ActualHeight
                });

                if (border.Width < 60)
                {
                    ((TextBlock)border.Child).Text = seq.ID.ToString();
                    border.Padding = new Thickness(0);
                }
                Canvas.SetLeft(border, (seq.First / (double)blitz3DAnimation.Frames) * KeySelector.ActualWidth);
            }
            DescBlock.Text = $"Sequences: {_sequences.Count()}, Frames: {preview.numPositionKeys()}";
            DataChart.DisplayAnimation(preview);
        }
        private void RefreshOpenedFile(string ManifestPath, string DataPath)
        {
            PathViewer.Children.Clear();
            Parser.ManifestPath        = ManifestPath;
            Parser.DataPath            = DataPath;
            DestinationBox.BorderBrush = Brushes.Gray;
            ManifestBox.BorderBrush    = Brushes.Gray;
            DataBox.BorderBrush        = Brushes.Gray;
            Parser.Refresh();
            bool error = false;

            if (string.IsNullOrWhiteSpace(DestinationBox.Text))
            {
                DestinationBox.BorderBrush = Brushes.Red;
                error = true;
            }
            if (Parser.ManifestPathException != null)
            {
                PathViewer.Children.Add(
                    new Button()
                {
                    Content = new TextBlock()
                    {
                        Text         = "Manifest Path Error: " + Parser.ManifestPathException.Message,
                        TextWrapping = TextWrapping.Wrap
                    },
                    Padding    = new Thickness(10, 5, 10, 5),
                    Background = Brushes.Red,
                    Margin     = new Thickness(10)
                });
                ManifestBox.BorderBrush = Brushes.Red;
                error = true;
            }
            if (Parser.DataPathException != null)
            {
                DataBox.BorderBrush = Brushes.Red;
                PathViewer.Children.Add(
                    new Button()
                {
                    Content = new TextBlock()
                    {
                        Text         = "Data Path Error: " + Parser.ManifestPathException.Message,
                        TextWrapping = TextWrapping.Wrap
                    },
                    Padding    = new Thickness(10, 5, 10, 5),
                    Background = Brushes.Red,
                    Margin     = new Thickness(10)
                });
                return;
            }
            if (error)
            {
                return;
            }
            ManifestSource = Parser.ManifestSource;
            DataSource     = Parser.DataSource;
            Properties.Settings.Default.ManifestPath   = ManifestPath;
            Properties.Settings.Default.DataPath       = DataPath;
            Properties.Settings.Default.DestinationDir = DestinationBox.Text;
            Properties.Settings.Default.Save();
            Destination = DestinationBox.Text;
            FileMap.Children.Clear();
            FileMap.ColumnDefinitions.Clear();
            FileMapBorders.Clear();
            FileMapColors = AppResources.BatchRandomColor(Parser.Chunks.Count);
            foreach (var chunk in Parser.Chunks)
            {
                AddToFileMap(chunk);
                var button = new Button()
                {
                    Content = chunk.Name,
                    Margin  = new Thickness(10),
                    Height  = 25,
                    Tag     = chunk
                };
                button.Click += delegate
                {
                    DisplayInformation(button.Tag as ManifestChunk);
                };
                PathViewer.Children.Add(button);
            }
            Title = $"MV - Viewing {Parser.Chunks.Count} Chunks";
        }