context: using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.IO;
  using System.Windows;
  using System.Windows.Controls;
  
  
  namespace Uber.MmeMuxer
  {
      public enum FileNamingMethod
      {
          NoChange,
          AddPrefix,
          AddSuffix,
          ApplyRegExp
      }
  
      public enum VideoCodec
      {
          Raw,
          Copy,
          Lagarith,
          Lavc,
          CustomVfw
      }
  
      public partial class UmmApp
      {
          private class CodecSettings
          {
              public VideoCodec Codec;
              public string Description;
              public RadioButton Button;
          }
  
          private class BuiltInVideoCodecSettings : CodecSettings
          {
              public static BuiltInVideoCodecSettings New(VideoCodec codec, string description)
              {
                  var info = new BuiltInVideoCodecSettings();
                  info.Codec = codec;
                  info.Description = description;
  
                  return info;
              }
          }
  
          private class CustomVideoCodecSettings : CodecSettings
          {
              public bool VideoForWindows;
              public TextBox EditBox;
              public FrameworkElement Panel;
  
              public static CustomVideoCodecSettings New(bool vfw)
              {
                  var info = new CustomVideoCodecSettings();
                  info.Codec = vfw ? VideoCodec.CustomVfw : VideoCodec.Lavc;
                  info.VideoForWindows = vfw;
                  info.Description = vfw ? "Custom VFW DLL" : "libavcodec";
  
                  return info;
              }
          }
  
          private class VideoCodecSettings
          {
              private readonly List<CodecSettings> _allCodecs = new List<CodecSettings>();
  
              private readonly List<CustomVideoCodecSettings> CustomCodecs = new List<CustomVideoCodecSettings>
              {
                  CustomVideoCodecSettings.New(false),
                  CustomVideoCodecSettings.New(true)
              };
  
              public readonly List<BuiltInVideoCodecSettings> BuiltInCodecs = new List<BuiltInVideoCodecSettings>();
              public string RadioButtonGroupName;
              public string Title;
              public CheckBox ShowCodecDialogCheckBox;
  
              public FrameworkElement CreateGui()
              {
                  _allCodecs.AddRange(BuiltInCodecs);
                  _allCodecs.AddRange(CustomCodecs);
  
                  foreach(var settings in BuiltInCodecs)
                  {
                      var codecRadioButton = new RadioButton();
                      settings.Button = codecRadioButton;
                      codecRadioButton.HorizontalAlignment = HorizontalAlignment.Left;
                      codecRadioButton.VerticalAlignment = VerticalAlignment.Top;
                      codecRadioButton.Margin = new Thickness(5, 5, 5, 0);
                      codecRadioButton.GroupName = RadioButtonGroupName;
                      codecRadioButton.Content = settings.Description;
                  }
  
                  foreach(var settings in CustomCodecs)
                  {
                      var customCodecRadioButton = new RadioButton();
                      settings.Button = customCodecRadioButton;
                      customCodecRadioButton.HorizontalAlignment = HorizontalAlignment.Left;
                      customCodecRadioButton.VerticalAlignment = VerticalAlignment.Center;
                      customCodecRadioButton.Margin = new Thickness(5, 5, 5, 0);
                      customCodecRadioButton.GroupName = RadioButtonGroupName;
                      customCodecRadioButton.Content = settings.Description;
              
                      var customCodecEditBox = new TextBox();
                      settings.EditBox = customCodecEditBox;
                      customCodecEditBox.HorizontalAlignment = HorizontalAlignment.Left;
                      customCodecEditBox.VerticalAlignment = VerticalAlignment.Center;
                      customCodecEditBox.Margin = new Thickness(5, 5, 5, 0);
                      if(settings.VideoForWindows)
                      {
                          customCodecEditBox.Width = 100;
                      }
                      else
                      {
                          customCodecEditBox.MinWidth = 100;
                      }
                      
                      var customCodecRowList = new List<FrameworkElement> { customCodecRadioButton, customCodecEditBox };
                      var customCodecRow = WpfHelper.CreateRow(customCodecRowList, 120, 0, 0);
                      customCodecRow.Margin = new Thickness(0);
                      settings.Panel = customCodecRow;
                  }
  
                  var showCodecDialogCheckBox = new CheckBox();
                  ShowCodecDialogCheckBox = showCodecDialogCheckBox;
                  showCodecDialogCheckBox.HorizontalAlignment = HorizontalAlignment.Left;
                  showCodecDialogCheckBox.VerticalAlignment = VerticalAlignment.Center;
                  showCodecDialogCheckBox.Margin = new Thickness(5);
                  showCodecDialogCheckBox.Content = "  Show CODEC Dialog? (Only for the first job)";
  
                  var videoCodecStackPanel = new StackPanel();
                  videoCodecStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
                  videoCodecStackPanel.VerticalAlignment = VerticalAlignment.Stretch;
                  videoCodecStackPanel.Margin = new Thickness(5, 5, 5, 0);
                  videoCodecStackPanel.Orientation = Orientation.Vertical;
                  foreach(var settings in BuiltInCodecs) videoCodecStackPanel.Children.Add(settings.Button);
                  foreach(var settings in CustomCodecs) videoCodecStackPanel.Children.Add(settings.Panel);
                  videoCodecStackPanel.Children.Add(showCodecDialogCheckBox);
  
                  var videoCodecGroupBox = new GroupBox();
                  videoCodecGroupBox.HorizontalAlignment = HorizontalAlignment.Left;
                  videoCodecGroupBox.VerticalAlignment = VerticalAlignment.Top;
                  videoCodecGroupBox.Margin = new Thickness(5);
                  videoCodecGroupBox.Header = Title;
                  videoCodecGroupBox.Content = videoCodecStackPanel;
  
                  return videoCodecGroupBox;
              }
  
              public void LoadSettings(VideoCodec codec, string customOptionsLavc, string customNameVfw, bool showCodecDialog)
              {
                  foreach(var codecSettings in _allCodecs)
                  {
                      if(codecSettings.Codec == codec)
                      {
                          codecSettings.Button.IsChecked = true;
                          break;
                      }
                  }
  
                  CustomCodecs[0].EditBox.Text = customOptionsLavc;
                  CustomCodecs[1].EditBox.Text = customNameVfw;
                  ShowCodecDialogCheckBox.IsChecked = showCodecDialog;
              }
  
              public void SaveSettings(out VideoCodec codec, out string customOptionsLavc, out string customNameVfw, out bool showCodecDialog)
              {
                  codec = VideoCodec.Copy;
                  foreach(var codecSettings in _allCodecs)
                  {
                      if(codecSettings.Button.IsChecked ?? false)
                      {
                          codec = codecSettings.Codec;
                          break;
                      }
                  }
  
                  customOptionsLavc = CustomCodecs[0].EditBox.Text;
                  customNameVfw = CustomCodecs[1].EditBox.Text;
                  showCodecDialog = ShowCodecDialogCheckBox.IsChecked ?? false;
              }
          }
  
          private class FileNamingOption
          {
              public FileNamingOption(FileNamingMethod method, RadioButton button)
              {
                  Method = method;
                  Button = button;
              }
  
              public FileNamingMethod Method;
              public RadioButton Button;
          }
  
          // CODEC.
          private readonly VideoCodecSettings _colorCodecSettings = new VideoCodecSettings();
          private readonly VideoCodecSettings _monochromeCodecSettings = new VideoCodecSettings();
  
          // General.
          private TextBox _mEncoderFilePathEditBox;
          private TextBox _inputFrameRateEditBox;
          private TextBox _outputFrameRateEditBox;
          private TextBox _framesToSkipEditBox;
          private CheckBox _displayMEncoderStdErrCheckBox;
          private CheckBox _outputAllFilesToSameFolderCheckBox;
          private CheckBox _useFolderFrameRateCheckBox;
          private TextBox _outputFolderTextBox;
  
          // File naming.
          private readonly List<FileNamingOption> _fileNamingOptions = new List<FileNamingOption>();
          private TextBox _fileNamingPrefixTextBox;
          private TextBox _fileNamingSuffixTextBox;
          private TextBox _fileNamingRegExpMatchTextBox;
          private TextBox _fileNamingReplacementTextBox;
  
          // Image sequence file naming.
          private RadioButton _fileNamingUseImageNameRadioButton;
  
          // Output file overwrite.
          private RadioButton _fileOverwriteAllowRadioButton;
  
          private FrameworkElement CreateSettingsTab()
          {
              _colorCodecSettings.Title = "Color Video CODEC";
              _colorCodecSettings.RadioButtonGroupName = "Color Video CODEC";
              _colorCodecSettings.BuiltInCodecs.Add(BuiltInVideoCodecSettings.New(VideoCodec.Raw, "Raw"));
              _colorCodecSettings.BuiltInCodecs.Add(BuiltInVideoCodecSettings.New(VideoCodec.Copy, "Copy"));
              _colorCodecSettings.BuiltInCodecs.Add(BuiltInVideoCodecSettings.New(VideoCodec.Lagarith, "Lagarith"));
              var colorCodecPanel = _colorCodecSettings.CreateGui();
  
              _monochromeCodecSettings.Title = "Monochrome Video CODEC (only for depth/stencil sequences)";
              _monochromeCodecSettings.RadioButtonGroupName = "Monochrome Video CODEC";
              _monochromeCodecSettings.BuiltInCodecs.Add(BuiltInVideoCodecSettings.New(VideoCodec.Raw, "Raw"));
              _monochromeCodecSettings.BuiltInCodecs.Add(BuiltInVideoCodecSettings.New(VideoCodec.Copy, "Copy"));
              var monochromeCodecPanel = _monochromeCodecSettings.CreateGui();
  
              var generalGroupBox = CreateGeneralSettingsGui();
              var fileNamingGroupBox = CreateFileNamingRulesGui();
              var fileNamingSequenceGroupBox = CreateSequenceNamingRulesGui();
              var fileOverwriteGroupBox = CreateFileOverwriteRulesGui();
  
              var wrapPanel = new WrapPanel();
              wrapPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
              wrapPanel.VerticalAlignment = VerticalAlignment.Stretch;
              wrapPanel.Margin = new Thickness(5);
              wrapPanel.Orientation = Orientation.Horizontal;
              wrapPanel.Children.Add(colorCodecPanel);
              wrapPanel.Children.Add(monochromeCodecPanel);
              wrapPanel.Children.Add(generalGroupBox);
              wrapPanel.Children.Add(fileNamingSequenceGroupBox);
              wrapPanel.Children.Add(fileNamingGroupBox);
              wrapPanel.Children.Add(fileOverwriteGroupBox);
  
              var scrollViewer = new ScrollViewer();
              scrollViewer.HorizontalAlignment = HorizontalAlignment.Stretch;
              scrollViewer.VerticalAlignment = VerticalAlignment.Stretch;
              scrollViewer.Margin = new Thickness(5);
              scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
              scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
              scrollViewer.Content = wrapPanel;
  
              return scrollViewer;
          }
  
          private FrameworkElement CreateGeneralSettingsGui()
          {
              var mEncoderFilePathLabel = new Label();
              mEncoderFilePathLabel.HorizontalAlignment = HorizontalAlignment.Stretch;
              mEncoderFilePathLabel.VerticalAlignment = VerticalAlignment.Center;
              mEncoderFilePathLabel.Margin = new Thickness(4, 5, 5, 0);
              mEncoderFilePathLabel.Content = "MEncoder Path";
  
              var mEncoderFilePathEditBox = new TextBox();
              _mEncoderFilePathEditBox = mEncoderFilePathEditBox;
              mEncoderFilePathEditBox.HorizontalAlignment = HorizontalAlignment.Stretch;
              mEncoderFilePathEditBox.VerticalAlignment = VerticalAlignment.Center;
              mEncoderFilePathEditBox.Margin = new Thickness(5, 5, 5, 0);
              mEncoderFilePathEditBox.MinWidth = 150;
  
              var mEncoderFilePathButton = new Button();
              mEncoderFilePathButton.HorizontalAlignment = HorizontalAlignment.Left;
              mEncoderFilePathButton.VerticalContentAlignment = VerticalAlignment.Center;
              mEncoderFilePathButton.Margin = new Thickness(5, 5, 5, 0);
              mEncoderFilePathButton.Width = 35;
              mEncoderFilePathButton.Height = 20;
              mEncoderFilePathButton.Content = "...";
              mEncoderFilePathButton.Click += (obj, args) => OnMEncoderFilePathBrowse();
  
              var mEncoderFilePathStackPanel = new DockPanel();
              mEncoderFilePathStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
              mEncoderFilePathStackPanel.VerticalAlignment = VerticalAlignment.Stretch;
              mEncoderFilePathStackPanel.Margin = new Thickness(0);
              mEncoderFilePathStackPanel.LastChildFill = true;
              mEncoderFilePathStackPanel.Children.Add(mEncoderFilePathButton);
              mEncoderFilePathStackPanel.Children.Add(mEncoderFilePathLabel);
              mEncoderFilePathStackPanel.Children.Add(mEncoderFilePathEditBox);
              DockPanel.SetDock(mEncoderFilePathButton, Dock.Right);
              DockPanel.SetDock(mEncoderFilePathLabel, Dock.Left);
              DockPanel.SetDock(mEncoderFilePathEditBox, Dock.Left);
  
              var inputFrameRateLabel = new Label();
              inputFrameRateLabel.HorizontalAlignment = HorizontalAlignment.Stretch;
              inputFrameRateLabel.VerticalAlignment = VerticalAlignment.Center;
              inputFrameRateLabel.Margin = new Thickness(4, 5, 5, 0);
              inputFrameRateLabel.Content = "Input Frame Rate";
  
              var outputFrameRateLabel = new Label();
              outputFrameRateLabel.HorizontalAlignment = HorizontalAlignment.Stretch;
              outputFrameRateLabel.VerticalAlignment = VerticalAlignment.Center;
              outputFrameRateLabel.Margin = new Thickness(4, 5, 5, 0);
              outputFrameRateLabel.Content = "Output Frame Rate";
              outputFrameRateLabel.ToolTip = "Output FPS is only used for image sequences";
  
              var inputFrameRateEditBox = new TextBox();
              _inputFrameRateEditBox = inputFrameRateEditBox;
              inputFrameRateEditBox.HorizontalAlignment = HorizontalAlignment.Left;
              inputFrameRateEditBox.VerticalAlignment = VerticalAlignment.Center;
              inputFrameRateEditBox.Margin = new Thickness(5, 5, 5, 0);
              inputFrameRateEditBox.Width = 30;
  
              var outputFrameRateEditBox = new TextBox();
              _outputFrameRateEditBox = outputFrameRateEditBox;
              outputFrameRateEditBox.HorizontalAlignment = HorizontalAlignment.Left;
              outputFrameRateEditBox.VerticalAlignment = VerticalAlignment.Center;
              outputFrameRateEditBox.Margin = new Thickness(5, 5, 5, 0);
              outputFrameRateEditBox.Width = 30;
              outputFrameRateEditBox.ToolTip = "Output FPS is only used for image sequences";
  
              var framesToSkipLabel = new Label();
              framesToSkipLabel.HorizontalAlignment = HorizontalAlignment.Stretch;
              framesToSkipLabel.VerticalAlignment = VerticalAlignment.Center;
              framesToSkipLabel.Margin = new Thickness(4, 5, 5, 0);
              framesToSkipLabel.Content = "Frames to Skip";
  
              var framesToSkipEditBox = new TextBox();
              _framesToSkipEditBox = framesToSkipEditBox;
              framesToSkipEditBox.HorizontalAlignment = HorizontalAlignment.Left;
              framesToSkipEditBox.VerticalAlignment = VerticalAlignment.Center;
              framesToSkipEditBox.Margin = new Thickness(5, 5, 5, 0);
              framesToSkipEditBox.Width = 30;
  
              var frameRatePanelList = new List<Tuple<FrameworkElement, FrameworkElement>>();
              var inputFrameRatePanelTuple = Tuple.Create<FrameworkElement, FrameworkElement>(inputFrameRateLabel, inputFrameRateEditBox);
              var outputFrameRatePanelTuple = Tuple.Create<FrameworkElement, FrameworkElement>(outputFrameRateLabel, outputFrameRateEditBox);
              var framesToSkipPanelTuple = Tuple.Create<FrameworkElement, FrameworkElement>(framesToSkipLabel, framesToSkipEditBox);
              frameRatePanelList.Add(inputFrameRatePanelTuple);
              frameRatePanelList.Add(outputFrameRatePanelTuple);
              frameRatePanelList.Add(framesToSkipPanelTuple);
              var frameRatePanel = WpfHelper.CreateDualColumnPanel(frameRatePanelList, 120, 0, 0);
              frameRatePanel.Margin = new Thickness(0);
  
              var displayMEncoderStdErrCheckBox = new CheckBox();
              _displayMEncoderStdErrCheckBox = displayMEncoderStdErrCheckBox;
              displayMEncoderStdErrCheckBox.HorizontalAlignment = HorizontalAlignment.Left;
              displayMEncoderStdErrCheckBox.VerticalAlignment = VerticalAlignment.Center;
              displayMEncoderStdErrCheckBox.Margin = new Thickness(7, 5, 5, 5);
              displayMEncoderStdErrCheckBox.Content = "  Display MEncoder's stderr output?";
  
              var outputAllFilesToSameFolderCheckBox = new CheckBox();
              _outputAllFilesToSameFolderCheckBox = outputAllFilesToSameFolderCheckBox;
              outputAllFilesToSameFolderCheckBox.HorizontalAlignment = HorizontalAlignment.Left;
              outputAllFilesToSameFolderCheckBox.VerticalAlignment = VerticalAlignment.Center;
              outputAllFilesToSameFolderCheckBox.Margin = new Thickness(7, 5, 5, 5);
              outputAllFilesToSameFolderCheckBox.Content = "  Output all files to this folder?";
              outputAllFilesToSameFolderCheckBox.Checked += (obj, args) => OnOutputAllFilesToSameFolderChecked();
              outputAllFilesToSameFolderCheckBox.Unchecked += (obj, args) => OnOutputAllFilesToSameFolderChecked();
  
              var useFolderFrameRateCheckBox = new CheckBox();
              _useFolderFrameRateCheckBox = useFolderFrameRateCheckBox;
              useFolderFrameRateCheckBox.HorizontalAlignment = HorizontalAlignment.Left;
              useFolderFrameRateCheckBox.VerticalAlignment = VerticalAlignment.Center;
              useFolderFrameRateCheckBox.Margin = new Thickness(7, 5, 5, 5);
              useFolderFrameRateCheckBox.Content = "  Use capture folder FPS? (only for Reflex atm)";
  
              var outputFolderTextBox = new TextBox();
              _outputFolderTextBox = outputFolderTextBox;
              outputFolderTextBox.HorizontalAlignment = HorizontalAlignment.Left;
              outputFolderTextBox.VerticalAlignment = VerticalAlignment.Center;
              outputFolderTextBox.Margin = new Thickness(7, 5, 5, 5);
              outputFolderTextBox.MinWidth = 150;
  
              var outputFolderBrowseButton = new Button();
              outputFolderBrowseButton.HorizontalAlignment = HorizontalAlignment.Stretch;
              outputFolderBrowseButton.VerticalAlignment = VerticalAlignment.Center;
              outputFolderBrowseButton.Margin = new Thickness(5);
              outputFolderBrowseButton.Width = 35;
              outputFolderBrowseButton.Height = 20;
              outputFolderBrowseButton.Content = "...";
              outputFolderBrowseButton.Click += (obj, args) => OnOutputFolderBrowse();
  
              var outputFolderOpenButton = new Button();
              outputFolderOpenButton.HorizontalAlignment = HorizontalAlignment.Left;
              outputFolderOpenButton.VerticalAlignment = VerticalAlignment.Center;
              outputFolderOpenButton.Margin = new Thickness(5);
              outputFolderOpenButton.Width = 70;
              outputFolderOpenButton.Height = 20;
              outputFolderOpenButton.Content = "Open";
              outputFolderOpenButton.Click += (obj, args) => OnOutputFolderOpen();
  
              var outputFolderStackPanel = new DockPanel();
              outputFolderStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
              outputFolderStackPanel.VerticalAlignment = VerticalAlignment.Stretch;
              outputFolderStackPanel.Margin = new Thickness(0);
              outputFolderStackPanel.LastChildFill = true;
              outputFolderStackPanel.Children.Add(outputFolderOpenButton);
              outputFolderStackPanel.Children.Add(outputFolderBrowseButton);
              outputFolderStackPanel.Children.Add(outputFolderTextBox);
              DockPanel.SetDock(outputFolderOpenButton, Dock.Right);
              DockPanel.SetDock(outputFolderBrowseButton, Dock.Right);
              DockPanel.SetDock(outputFolderTextBox, Dock.Right);
  
  
gt:             var generalStackPanel = new StackPanel();