/// <summary>
        /// Generates the visualization that we will return as the result object, based on
        /// the currents state of the controls.
        /// </summary>
        /// <returns>New Visualization or VisWireframeAnimation object.</returns>
        private Visualization PrepResultVis()
        {
            VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;

            Debug.Assert(item != null);

            // Generate parameter dictionary.  Save a reference to it for next time.
            bool isWireframe = (item.VisDescriptor.VisualizationType == VisDescr.VisType.Wireframe);
            ReadOnlyDictionary <string, object> valueDict = CreateVisGenParams(isWireframe);

            sLastParams = valueDict;

            string trimTag = Visualization.TrimAndValidateTag(TagString, out bool isTagValid);

            Debug.Assert(isTagValid);
            Visualization vis;

            if (isWireframe && IsWireframeAnimated)
            {
                vis = new VisWireframeAnimation(trimTag, item.VisDescriptor.Ident, valueDict,
                                                mOrigVis, mWireObj);
            }
            else
            {
                vis = new Visualization(trimTag, item.VisDescriptor.Ident, valueDict, mOrigVis);
            }

            // Set the thumbnail image.
            if (isWireframe)
            {
                Debug.Assert(mWireObj != null);
                vis.CachedImage = Visualization.GenerateWireframeImage(mWireObj,
                                                                       Visualization.THUMBNAIL_DIM, valueDict);
            }
            else
            {
                Debug.Assert(mThumbnail != null);
                vis.CachedImage = mThumbnail;
            }

            return(vis);
        }
        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog fileDlg = new SaveFileDialog()
            {
                Filter        = Res.Strings.FILE_FILTER_GIF + "|" + Res.Strings.FILE_FILTER_ALL,
                FilterIndex   = 1,
                ValidateNames = true,
                AddExtension  = true,
                FileName      = mFileNameBase + ".gif"
            };

            if (fileDlg.ShowDialog() != true)
            {
                return;
            }
            string pathName = Path.GetFullPath(fileDlg.FileName);

            Debug.WriteLine("Save path: " + pathName);

            try {
                OutputSize item = (OutputSize)sizeComboBox.SelectedItem;
                if (mVis is VisWireframeAnimation)
                {
                    Debug.Assert(item.Width == item.Height);
                    AnimatedGifEncoder encoder = new AnimatedGifEncoder();
                    ((VisWireframeAnimation)mVis).EncodeGif(encoder, item.Width);

                    using (FileStream stream = new FileStream(pathName, FileMode.Create)) {
                        encoder.Save(stream, out int dispWidth, out int dispHeight);
                    }
                }
                else
                {
                    BitmapSource outImage;
                    if (IsBitmap)
                    {
                        int scale = item.Width / (int)mVis.CachedImage.Width;
                        Debug.Assert(scale >= 1);
                        if (scale == 1)
                        {
                            outImage = mVis.CachedImage;
                        }
                        else
                        {
                            outImage = mVis.CachedImage.CreateScaledCopy(scale);
                        }
                    }
                    else
                    {
                        Debug.Assert(item.Width == item.Height);
                        outImage = Visualization.GenerateWireframeImage(mWireObj,
                                                                        item.Width, mVis.VisGenParams);
                    }

                    GifBitmapEncoder encoder = new GifBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(outImage));

                    using (FileStream stream = new FileStream(pathName, FileMode.Create)) {
                        encoder.Save(stream);
                    }
                }
            } catch (Exception ex) {
                // Error handling is a little sloppy, but this shouldn't fail often.
                MessageBox.Show(ex.Message, Res.Strings.ERR_FILE_GENERIC_CAPTION,
                                MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // After successful save, close dialog box.
            DialogResult = true;
        }