context: using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using System.Text.RegularExpressions;
  using System.IO;
  using Gooey;
  
  namespace CarbonCopy {
  	public partial class frmMain : Form {
  		#region Private classes
  
  		/// <summary>
  		/// Represents a verbosity level in the 'output verbosity' listbox
  		/// </summary>
  		public class VerbosityListItem {
  			public VerbosityLevel OutputDetail { get; set; }
  			public string Description { get; set; }
  
  			public override string ToString() {
  				return this.Description;
  			}
  		}
  
  		#endregion
  
  		#region Private vars
  
  		private Gooey.Utilities utils;
  		private CCOFunctions optFunc;
  
  		#endregion
  
  		#region Constructors
  
  		public frmMain() {
  			InitializeComponent();
  
  			this.utils = new Gooey.Utilities();
  			this.optFunc = new CCOFunctions();
  		}
  
  		#endregion
  
  		#region Private methods
  
  		private void btnSourceBrowse_Click(object sender, EventArgs e) {
  			folderBrowserDialog1.Description = "Select a source directory to backup...";
  			string codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
  			string driveName = utils.GetFragmentFromFileUrl(codeBase, Utilities.FileUrlFragmentPart.DriveName);
  			folderBrowserDialog1.SelectedPath = driveName + ":\\";
  			folderBrowserDialog1.ShowNewFolderButton = false;
  			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
  				txtSourceDir.Text = folderBrowserDialog1.SelectedPath;
  			}
  		}
  
  		private void frmMain_Load(object sender, EventArgs e) {
  			// Set title to version number, etc.
  			this.Text = this.Text.Replace("$ver", this.utils.GetVersionString(System.Reflection.Assembly.GetExecutingAssembly(), VersionStringType.MajorMinor));
  
  			// Automatic label height, but force width to that of the backup dirs list
  			lblDestDir.MinimumSize = new Size(lstSourceDirs.Width, 0);
  			lblDestDir.MaximumSize = new Size(lstSourceDirs.Width, 0);
  			lblDestDir.Text = "";
  
  			// Set colours of example labels
  			var ccoColours = new CCOColours();
  			lblInformational.ForeColor = ccoColours.Black;
  			lblError.ForeColor = ccoColours.Red;
  			lblDebug.ForeColor = ccoColours.Green;
  			lblVerbose.ForeColor = ccoColours.Blue;
  
  			// Initialize options information/default selections
  			radCarbon.Checked = true;
              chkDryRun.Checked = true;
  
  			lstVerbosity.Items.Add(new VerbosityListItem { Description = "Brief", OutputDetail = VerbosityLevel.Brief });
  			lstVerbosity.Items.Add(new VerbosityListItem { Description = "Normal", OutputDetail = VerbosityLevel.Normal });
  			lstVerbosity.Items.Add(new VerbosityListItem { Description = "Debug", OutputDetail = VerbosityLevel.Debug });
  			lstVerbosity.Items.Add(new VerbosityListItem { Description = "Verbose", OutputDetail = VerbosityLevel.Verbose });
  			lstVerbosity.SelectedIndex = 1;  // Default to Normal
  		}
  
  		private void btnAddDir_Click(object sender, EventArgs e) {
  			DirectoryInfo fixedPath = null;
  			string errorHolder;
  
  			// Is path string valid?
  			if (!optFunc.CheckDirValidity(txtSourceDir.Text, ref fixedPath, out errorHolder)) {
  				utils.ShowError(errorHolder);
  				return;
  			}
  
  			// Is it a dupe?
  			foreach (CCODirinfoHolder dirPath1 in lstSourceDirs.Items) {
  				DirectoryInfo dirPath2 = fixedPath;
  				if (dirPath1.ToString().Equals(dirPath2.FullName, StringComparison.CurrentCultureIgnoreCase)) {
  					utils.ShowError("Directory '" + dirPath2.FullName + "' is already in the list.");
  					return;
  				}
  			}
  
  			lstSourceDirs.Items.Add(new CCODirinfoHolder(fixedPath));
  			txtSourceDir.Text = "";
  		}
  
  		private void btnDestSet_Click(object sender, EventArgs e) {
  			DirectoryInfo fixedPath = null;
  			string errorHolder;
  
  			// Is path string valid?
  			if (!optFunc.CheckDirValidity(txtDestDir.Text, ref fixedPath, out errorHolder)) {
  				utils.ShowError(errorHolder);
  				return;
  			}
  
  			lblDestDir.Text = fixedPath.FullName;
  			lblDestDir.Tag = fixedPath;
  			txtDestDir.Text = "";
  		}
  
  		private void btnRemDir_Click(object sender, EventArgs e) {
  			if (lstSourceDirs.SelectedIndex >= 0) {
  				int oldIndex = lstSourceDirs.SelectedIndex;
  				lstSourceDirs.Items.RemoveAt(lstSourceDirs.SelectedIndex);
  				if (lstSourceDirs.Items.Count-1 >= oldIndex) {
  					lstSourceDirs.SelectedIndex = oldIndex;
  				}
  				else {
  					if (lstSourceDirs.Items.Count > 0) {
  						lstSourceDirs.SelectedIndex = lstSourceDirs.Items.Count-1;
  					}
  				}
  			}
  			else {
  				System.Media.SystemSounds.Beep.Play();
  			}
  		}
  
  		private void btnDestBrowse_Click(object sender, EventArgs e) {
  			folderBrowserDialog1.Description = "Select a destination directory to backup to...";
  			string codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
  			string driveName = utils.GetFragmentFromFileUrl(codeBase, Utilities.FileUrlFragmentPart.DriveName);
  			if (Directory.Exists(txtDestDir.Text)) { folderBrowserDialog1.SelectedPath = txtDestDir.Text; }
  			else { folderBrowserDialog1.SelectedPath = driveName + ":\\"; }
  			folderBrowserDialog1.ShowNewFolderButton = false;
  			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
  				txtDestDir.Text = folderBrowserDialog1.SelectedPath;
  			}
  		}
  
  		private void grpDest_Paint(object sender, PaintEventArgs e) {
  			// Paint bevel around 'destination directory' text
  			System.Drawing.Pen greyPen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0x80, 0x80, 0x80));
  			System.Drawing.Pen whitePen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0xFF, 0xFF, 0xFF));
  			System.Drawing.Graphics grpDestGraphics = grpDest.CreateGraphics();
  			Point ptTopLeft = new Point(lblDestDir.Left-1, lblDestDir.Top-1);
  			Point ptTopRight = new Point(lblDestDir.Left+lblDestDir.Width, lblDestDir.Top-1);
  			Point ptBottomLeft = new Point(lblDestDir.Left-1, lblDestDir.Top+lblDestDir.Height);
  			Point ptBottomRight = new Point(lblDestDir.Left+lblDestDir.Width, lblDestDir.Top+lblDestDir.Height);
  
  			grpDestGraphics.DrawLine(greyPen, ptTopLeft, ptTopRight);
  			grpDestGraphics.DrawLine(greyPen, ptTopLeft, ptBottomLeft);
  			grpDestGraphics.DrawLine(whitePen, ptBottomLeft, ptBottomRight);
  			grpDestGraphics.DrawLine(whitePen, ptTopRight, ptBottomRight);
  
  			grpDestGraphics.Dispose();
  			greyPen.Dispose();
  			whitePen.Dispose();
  		}
  
  		private void btnStart_Click(object sender, EventArgs e) {
  			// Generate options to be passed in to the backup form
  			CCO passingOptions = generatePassingOptions();
  
  			string errors;
  			if (!optFunc.SanityCheck(passingOptions, out errors)) {
  				utils.ShowError("Error(s) found in backup profile:\r\n" + errors);
  			}
  			else {
  				frmBackup backupForm = new frmBackup(passingOptions);
  
  				backupForm.ShowDialog();
  			}
  		}
  
  		private CCO generatePassingOptions() {
  			CCO options = new CCO();
  
  			foreach (CCODirinfoHolder dirInfoHolder in lstSourceDirs.Items) {
  				options.SourceDirs.Add(dirInfoHolder.DirInfo);
  			}
  
  			options.DestDir = (DirectoryInfo)lblDestDir.Tag;
  
  			if (radCarbon.Checked) { options.Type = CCOTypeOfBackup.CarbonCopy; }
  			else if (radIncremental.Checked) { options.Type = CCOTypeOfBackup.Incremental; }
  
              options.IsDryRun = chkDryRun.Checked;
  
  			options.OutputDetail = ((VerbosityListItem)lstVerbosity.SelectedItem).OutputDetail;
  
  			return options;
  		}
  
  		private void setupFromOptions(CCO options) {
  			// This method assumes 'options' has already been sanity checked (dupes, etc.)
  			// Setup source dir(s)
  			lstSourceDirs.Items.Clear();
  			foreach (DirectoryInfo di in options.SourceDirs) {
  				lstSourceDirs.Items.Add(new CCODirinfoHolder(di));
  			}
  
  			// Setup dest dir
  			lblDestDir.Text = "";
  			lblDestDir.Tag = null;
  			lblDestDir.Text = options.DestDir.FullName;
  			lblDestDir.Tag = options.DestDir;
  
  			// Setup type of backup
  			if (options.Type == CCOTypeOfBackup.CarbonCopy) {
  				radCarbon.Checked = true;
  			}
  			else if (options.Type == CCOTypeOfBackup.Incremental) {
  				radIncremental.Checked = true;
  			}
  
  			chkDryRun.Checked = options.IsDryRun;
  
  			// Setup what to display
  
gt: 			for (int i = 0; i < lstVerbosity.Items.Count; i++) {