using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using VEPROMS.CSLA.Library;
using System.IO;
using Volian.Controls.Library;
using DevComponents.DotNetBar;
using JR.Utils.GUI.Forms;

namespace VEPROMS
{
	public partial class frmBatchRefresh : Form
	{
		private SessionInfo _MySessionInfo;
		public SessionInfo MySessionInfo
		{
			get { return _MySessionInfo; }
			set { _MySessionInfo = value; }
		}
		public frmBatchRefresh(SessionInfo sessionInfo)
		{
			InitializeComponent();
			_MySessionInfo = sessionInfo;
			setupProgessSteps1();
		}
		//private AdminTools adminToolsList;
		//private AdminTool selectedAdminTool;
		// removed the Refresh ROs and Refresh Transitions and ROs options (now only Transitions can be refreshed)
		// the Update ROs and Refresh ROs logic was merged together.  The Update ROs will functionally do both
		// also annotations will be placed on step elements that have RO changes
		private void SetUpAdminTools()
		{
			//adminToolsList = new AdminTools();
			//adminToolsList.Add("Update RO Values"
			//	, "Update RO Values Guidance"
			//	, "This allows the user to update referenced objects values for multiple working drafts in a batch mode."
			//	, "It is recommended that this be done during off hours."
			//	, "WARNING:"
			//	, true // True means Exclude Procedures
			//	, false
			//	, UpdateROValues);
			//adminToolsList.Add("Refresh Transitions", "Refresh Transitions Guidance", "Occasionally, transitions do not get updated.\r\n\r\nThis function will refresh transitions in all procedures selected below whether they were selected individually or as a group via a procedure set.", "If more than one procedure is selected, it is recommened that this be performed during off hours.", "WARNING:", false, false, RefreshTransitions);
			//adminToolsList.Add("Fix Hyphens", "Fix Hyphens", "Replace various forms of Hyphens with a consistent Hyphen so that search will find all Hyphens", "", "", true, true, "vesp_FixHyphens", FixHyphens);
			//adminToolsList.Add("Delete PDFs", "Delete PDFs Guidance", "It is sometimes desirable to clean up the database by removing extra pdf files.  This process allows for this to occur", "", "", true, true, "vesp_DeletePDFs", DeletePDFs);
			//adminToolsList.Add("Identify Disconnected Items"
			//	, "Identify Disconnected Items Guidance"
			//	, "Everything in PROMS is inter-related.  A working draft knows what is its first procedure and a procedure knows what is its first step.  Likewise, a procedure knows what procedure is before it and after it.\r\n\r\nOccasionally, an item will become disconnected and does not know where it fits into the relationships.  This tool identifies whether the database has this condition."
			//	, "This tool may take an extended period of time to execute."
			//	, "NOTE:"
			//	, true
			//	, true
			//	, "vesp_GetDisconnectedItemsCount"
			//	, IdentifyDisconnectedItems);
			//adminToolsList.Add("Purge Disconnected Items"
			//	, "Purge Disconnected Items Guidance"
			//	, "Everything in PROMS is inter-related.  A working draft knows what is its first procedure and a procedure knows what is its first step.  Likewise, a procedure knows what procedure is before it and after it.\r\n\r\nOccasionally, an item will become disconnected and does not know where it fits into the relationships.  This tool removes any disconnected items from the database."
			//	, "Be sure to have a backup prior to running this!!\r\n\r\nThis tool may take an extended period of time to execute."
			//	, "Warning:"
			//	, true
			//	, true
			//	, "vesp_PurgeDisconnectedData"
			//	, PurgeDisconnectedItems);
			//adminToolsList.Add("Identify Non-Editable Items", "Identify Non-Editable Items Guidance", "Typically, a section in PROMS only has sub-sections or sub-steps.  There are times when a section has both.  When this occurs, the sub-step data can be marked as non-editable.  If this occurs, the user can no longer get to these steps and they can become forgotten.\r\n\r\nThis tool will identify if the database has non-editable steps and provide a listing of these steps.", "This tool may take an extended period of time to execute.", "NOTE:", true, true, "vesp_GetNonEditableItems", IdentifyNonEditableItems);
			//adminToolsList.Add("Get Database Users", "Get Database Users Guidance", "This administrative tool will return all of the users currently with open sessions in the database and the details of any items they have checked out", "", "", true, true, "vesp_GetDatabaseSessions", GetDatabaseSessions);
			//adminToolsList.Add("Clean Up Referenced Object Associations"
			//	, "Clean Up Referenced Object Associations Guidance"
			//	, "Referenced Objects are associated with a procedure set (such as Working Draft).  If unnecessary associations exist, these can be removed."
			//	, "Be sure to have a backup prior to running this!!"
			//	, "NOTE:"
			//	, true
			//	, true
			//	, "vesp_CleanUpROAssociations"
			//	, CleanUpROAssociations);
			//adminToolsList.Add("Remove Unused ROFSTs and Figures"
			//	, "Remove Unused ROFSTs and Figures Guidance"
			//	, "This tool removes any ROFSTs and Figures that are no longer used."
			//	, "Be sure to have a backup prior to running this!!"
			//	, "NOTE:"
			//	, true
			//	, true
			//	, "vesp_RemoveUnusedRoFstsAndFigures"
			//	, RemoveUnusedRoFstsAndFigures);
			//adminToolsList.Add("Identify Unused RO Associations"
			//	, "Identify Unused RO Associations Guidance"
			//	, "Referenced Objects are associated with a procedure set (such as Working Draft).  If unnecessary associations exist, these can be removed."
			//	, ""
			//	, "NOTE:"
			//	, true
			//	, true
			//	, "vesp_GetUnusedROAssociationsCount"
			//	, IdentifyROAssociations);
			//adminToolsList.Add("Identify Unused ROFSTs and Figures"
			//	, "Identify Unused ROFSTs and Figures Guidance"
			//	, "This tool identifies any ROFSTs and Figures that are no longer used."
			//	, ""
			//	, "NOTE:"
			//	, true
			//	, true
			//	, "vesp_GetUnusedRoFstsCount"
			//	, IdentifyUnusedRoFstsAndFigures);

			////adminToolsList.Add("Find Referenced Object Problems", "Find Referenced Object Problems Guidance", "description for find ro problems", "", "", true, true, "vesp_FindROProblems", FindROProblems);
			//adminToolsList.Sort();
			//cbxAdminTools.DataSource = adminToolsList;
			//cbxAdminTools.DisplayMember = "Title";
			//cbxAdminTools.SelectedIndex = -1;
		}
		private void FixHyphens()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Standardizing Hyphens");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int affectedRows = ESP_FixHyphens.Execute("vesp_FixHyphens") / 2;// Two results for each change
			txtProcess.AppendText(string.Format("Fixed {0} Hyphens", affectedRows));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			txtResults.AppendText(string.Format("{0} Hyphens were Fixed.", affectedRows));
			txtResults.AppendText(Environment.NewLine);
			txtResults.AppendText(Environment.NewLine);
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			//MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		}
		private Dictionary<TreeNode, ProcedureInfo> myProcedures = new Dictionary<TreeNode, ProcedureInfo>();
		private Dictionary<TreeNode, DocVersionInfo> myDocVersions = new Dictionary<TreeNode, DocVersionInfo>();
		private void frmBatchRefresh_Load(object sender, EventArgs e)
		{
			SetUpAdminTools();
			//lblWarning.Visible = false;
		}
		private bool AtLeastOneNodeChecked()
		{
			foreach (TreeNode tn in myTV.Nodes)
				if (NodeIsChecked(tn))
					return true;
			return false;
		}
		private bool NodeIsChecked(TreeNode tn)
		{
			if (tn.Checked) return true;
			if (tn.GetNodeCount(true) > 0)
				foreach (TreeNode chnd in tn.Nodes)
					if (NodeIsChecked(chnd))
						return true;
			return false;
		}
		private List<string> myTreeNodePath;
		private void ResetTV()
		{
			ResetTV(false);
		}
		private void ResetTV(bool noProcs)
		{
			btnFixLinks.Enabled = false;
			this.Cursor = Cursors.WaitCursor;
			myTreeNodePath = new List<string>();
			myTV.Nodes.Clear();
			myDocVersions.Clear();
			//if (!selectedAdminTool.NoTreeView)
			//{
				FolderInfo fi = FolderInfo.GetTop();
				TreeNode tn = myTV.Nodes.Add(fi.Name);
				tn.Tag = fi;
				if (fi.ChildFolderCount > 0)
					LoadChildFolders(fi, tn, noProcs);
				if (myTV.SelectedNode != null)
					myTV.SelectedNode.Expand();
			//}
			this.Cursor = Cursors.Default;
		}
		private void LoadChildFolders(FolderInfo fi, TreeNode tn, bool noProcs)
		{
			foreach (FolderInfo fic in fi.SortedChildFolders)
			{
				TreeNode tnc = tn.Nodes.Add(fic.Name);
				tnc.Tag = fic;
				if (fic.ChildFolderCount > 0)
					LoadChildFolders(fic, tnc, noProcs);
				if (fic.FolderDocVersionCount > 0)
					LoadDocVersions(fic, tnc, noProcs);
			}
		}
		private void LoadDocVersions(FolderInfo fic, TreeNode tnc, bool noProcs)
		{
			foreach (DocVersionInfo dvi in fic.FolderDocVersions)
			{
				UserInfo ui = UserInfo.GetByUserID(MySessionInfo.UserID);
				if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi))
				{
					tnc.Tag = dvi;
					myDocVersions.Add(tnc, dvi);
					if (!noProcs)
					{
						if (dvi.Procedures.Count > 0)
							LoadProcedures(dvi, tnc);
					}
					myTreeNodePath.Add(tnc.FullPath);
				}
				else
				{
					while (tnc != null && tnc.Text != "VEPROMS" && !IsUsedPath(tnc.FullPath))
					{
						TreeNode tmp = tnc.Parent;
						tnc.Remove();
						tnc = tmp;
					}
				}
			}
		}
		private bool IsUsedPath(string path)
		{
			foreach (string s in myTreeNodePath)
			{
				if (s.StartsWith(path))
					return true;
			}
			return false;
		}
		private void LoadProcedures(DocVersionInfo dvi, TreeNode tnc)
		{
			foreach (ProcedureInfo pi in dvi.Procedures)
			{
				TreeNode tn = tnc.Nodes.Add(string.Format("{0} {1}", pi.DisplayNumber, pi.DisplayText));
				myProcedures.Add(tn, pi);
				tn.Tag = pi;
			}
		}
		private void LoadFolderInfo(FolderInfo f)
		{
			TreeNode tn = myTV.Nodes.Add(f.Name);
			tn.Tag = f;
			if (f.ChildFolderCount > 0)
				foreach (FolderInfo cf in f.SortedChildFolders)
					LoadFolderInfo(cf);
		}
		private void UpdateROValues()
		{
			this.Cursor = Cursors.WaitCursor;
			List<DocVersionInfo> dvil = new List<DocVersionInfo>();
			foreach (TreeNode tn in myDocVersions.Keys)
				if (tn.Checked)
					dvil.Add(myDocVersions[tn]);
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Update RO Values");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(pStart.ToString("MM/dd/yyyy @ HH:mm"));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			pbProcess.Minimum = 0;
			pbProcess.Maximum = dvil.Count;
			pbProcess.Step = 1;
			while (dvil.Count > 0)
			{
				StringBuilder sbDocVersions = new StringBuilder();
				Queue<DocVersionInfo> dviq = new Queue<DocVersionInfo>();
				foreach (DocVersionInfo dvi in dvil)
					dviq.Enqueue(dvi);
				dvil.Clear();
				// if we are processing more than one procedure set, use MessageList to hold the summary results for each set
				if (dviq.Count > 1)
					ROFstInfo.MessageList = new StringBuilder();
				while (dviq.Count > 0)
				{
					string msg = string.Empty;
					DocVersionInfo dq = dviq.Dequeue();
					if (!MySessionInfo.CanCheckOutItem(dq.VersionID, CheckOutType.DocVersion, ref msg))
					{
						dvil.Add(dq);
						sbDocVersions.AppendLine(msg);
					}
					else
					{
						ContentInfo.StaticContentInfoChange += new StaticContentInfoEvent(ContentInfo_StaticContentInfoChange);
						ProcessUpdateROValues(dq);
						ContentInfo.StaticContentInfoChange -= new StaticContentInfoEvent(ContentInfo_StaticContentInfoChange);
						pbProcess.PerformStep();
						Application.DoEvents();
					}
				}
				DateTime pEnd = DateTime.Now;
				txtProcess.AppendText(string.Format("Completed: {0} {1} Seconds Elapsed", pEnd.ToString("MM/dd/yyyy @ HH:mm"), TimeSpan.FromTicks(pEnd.Ticks - pStart.Ticks).TotalSeconds));
				Application.DoEvents();
				// when processing more than one procedure set, display only one completed message after all are processed
				if (ROFstInfo.MessageList != null)
				{
					FlexibleMessageBox.Show(ROFstInfo.MessageList.ToString(), "RO Update Complete");
					ROFstInfo.MessageList = null;
				}
				if (dvil.Count > 0)
				{
					StringBuilder sb = new StringBuilder();
					sb.AppendLine("The batch update process was not usccessful for all working drafts selected.");
					sb.AppendLine("The following working drafts were not able to be refreshed...");
					sb.AppendLine();
					sb.AppendLine(sbDocVersions.ToString());
					sb.AppendLine();
					sb.AppendLine("If you want to update these working drafts, please contact the respective users and have them close any procedures in the working draft.");
					sb.AppendLine("Once this is complete you can continue the process otherwise you may terminate the process immediately.");
					sb.AppendLine();
					sb.AppendLine("Have you requested the users to close the procedures and do you want to continue the process?");
					frmBatchRefreshCheckedOut frmCO = new frmBatchRefreshCheckedOut();
					frmCO.MySessionInfo = MySessionInfo;
					//frmCO.CheckedOutProcedures = dvil;
					frmCO.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - frmCO.Width, Screen.PrimaryScreen.WorkingArea.Height - frmCO.Height);
					frmCO.Show(this);
					while (!this.Visible)
						Application.DoEvents();
				}
			}
			this.Cursor = Cursors.Default;
		}

		private void RefreshTransitions()
		{
			int numTransProcessed = 0;
			int numTransFixed = 0;
			this.Cursor = Cursors.WaitCursor;
			List<ProcedureInfo> pil = new List<ProcedureInfo>();
			foreach (TreeNode tn in myProcedures.Keys)
				if (tn.Checked)
					pil.Add(myProcedures[tn]);
			//PopulateTransitionInfoLists(pil);
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Refresh Transitions");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			pbProcess.Minimum = 0;
			pbProcess.Maximum = pil.Count;
			pbProcess.Step = 1;
			while (pil.Count > 0)
			{
				ContentInfo.StaticContentInfoChange += new StaticContentInfoEvent(ContentInfo_StaticContentInfoChange);
				StringBuilder sbProcs = new StringBuilder();
				Queue<ProcedureInfo> piq = new Queue<ProcedureInfo>();
				foreach (ProcedureInfo pi in pil)
					piq.Enqueue(pi);
				pil.Clear();
				while (piq.Count > 0)
				{
					string msg = string.Empty;
					ProcedureInfo pq = piq.Dequeue();
					if (!MySessionInfo.CanCheckOutItem(pq.ItemID, CheckOutType.Procedure, ref msg))
					{
						pil.Add(pq);
						sbProcs.AppendLine(msg);
					}
					else
					{
						txtResults.AppendText(string.Format("Processing {0} {1}", pq.DisplayNumber, pq.DisplayText));
						txtResults.AppendText(Environment.NewLine);
						RefreshProcedureTransitions(pq);
						numTransProcessed += ProcedureInfo.TranCheckCount;
						numTransFixed += ProcedureInfo.TranFixCount;
						pbProcess.PerformStep();
						Application.DoEvents();
					}
				}
				ContentInfo.StaticContentInfoChange -= new StaticContentInfoEvent(ContentInfo_StaticContentInfoChange);
				DateTime pEnd = DateTime.Now;
				txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
				Application.DoEvents();
				if (pil.Count > 0)
				{
					StringBuilder sb = new StringBuilder();
					sb.AppendLine("The batch refresh process was not usccessful for all procedures selected.");
					sb.AppendLine("The following procedures were not able to be refreshed...");
					sb.AppendLine();
					sb.AppendLine(sbProcs.ToString());
					sb.AppendLine();
					sb.AppendLine("If you want to refresh these prcoedures, please contact the respective users and have them close the procedures.");
					sb.AppendLine("Once this is complete you can continue the process otherwise you may terminate the process immediately.");
					sb.AppendLine();
					sb.AppendLine("Have you requested the users to close the procedures and do you want to continue the process?");
					frmBatchRefreshCheckedOut frmCO = new frmBatchRefreshCheckedOut();
					frmCO.MySessionInfo = MySessionInfo;
					frmCO.CheckedOutProcedures = pil;
					frmCO.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - frmCO.Width, Screen.PrimaryScreen.WorkingArea.Height - frmCO.Height);
					frmCO.Show(this);
					while (!this.Visible)
						Application.DoEvents();
				}
			}
			this.Cursor = Cursors.Default;
			if (numTransFixed == 0)
				MessageBox.Show(string.Format("{0} Transitions Checked.\n\nNo Transitions needed fixed.",numTransProcessed), "Refresh Transitions Completed");
			else
				MessageBox.Show(string.Format("{0} Transitions Checked.\n\n {1} Transitions needed fixed.", numTransProcessed, numTransFixed), "Refresh Transitions Completed");
		}
		private void DeletePDFs()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Refreshing Word Attachments");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int affectedRows = ESP_DeletePDFs.Execute("vesp_DeletePDFs");
			//txtProcess.AppendText(string.Format("Deleted {0} PDFs", affectedRows));
			txtProcess.AppendText(string.Format("Word Attachments Refreshed: {0}", affectedRows));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			txtResults.AppendText(string.Format("{0} Word Attachments Refreshed.", affectedRows));
			txtResults.AppendText(Environment.NewLine);
			txtResults.AppendText(Environment.NewLine);
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			//MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		}
		private void IdentifyDisconnectedItems()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Identifing Orphan Items");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCount = ESP_IdentifyDisconnectedItems.Execute("vesp_GetDisconnectedItemsCount");
			txtProcess.AppendText(string.Format("Orphan Items Count:  {0}", rowCount));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			if (rowCount > 0)
			{
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contains {0} Orphan items.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				//txtResults.AppendText("It is recommended you contact Volian to assist in resolving this condition");
			}
			else
			{
				txtResults.AppendText("No Orphan Records Found");// B2017-108 Always output results even if there isn't any 
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			//MessageBox.Show(string.Format("{0} Completed", "Orphan Items Check"), "Orphan Items");
		}
		private void PurgeDisconnectedItems()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Purging Orphan Items");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCount = ESP_IdentifyDisconnectedItems.Execute("vesp_GetDisconnectedItemsCount");
			if (rowCount > 0)
			{
				ESP_PurgeDisconnectedItems.Execute("vesp_PurgeDisconnectedData");
				int rowCount2 = ESP_IdentifyDisconnectedItems.Execute("vesp_GetDisconnectedItemsCount");
				txtProcess.AppendText(string.Format("Orphan Items Purged: {0}", rowCount));
				txtProcess.AppendText(Environment.NewLine);
				//txtProcess.AppendText(Environment.NewLine);
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contained {0} Orphan items.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database now contains {0} Orphan items.", rowCount2));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				if (rowCount2 > 0)
				{
					txtResults.AppendText("** Some or all Orphan items could not be purged.**");
					txtResults.AppendText("** It is recommended you contact Volian to assist in resolving this condition.**");
					txtResults.AppendText(Environment.NewLine);
					txtResults.AppendText(Environment.NewLine);
				}
			}
			else
			{
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contained {0} Orphan items.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("No Orpan Items to Purge!"));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			//MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		}
		private void IdentifyUnusedRoFstsAndFigures()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Identifing Unused RoFsts and Figures");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCountRoFst = ESP_GetUnusedRoFsts.Execute("vesp_GetUnusedRoFstsCount");
			int rowCountFigures = ESP_GetUnusedFigures.Execute("vesp_GetUnusedFiguresCount");
			txtProcess.AppendText(string.Format("Unused RoFsts Count:  {0}, Unused Figures Count:  {1}", rowCountRoFst, rowCountFigures));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			if (rowCountRoFst > 0 || rowCountFigures > 0)
			{
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contains {0} unused RoFsts.", rowCountRoFst));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database contains {0} unused Figures items.", rowCountFigures));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			else
			{
				txtResults.AppendText("No Unused  RoFsts or Figures Found"); // B2017-108 Always output results even if there isn't any
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}

			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;

			//MessageBox.Show(string.Format("{0} Completed", "Unused ROFSTs and Figures Check"), "Unused ROFSTs and Figures");
		}
		private void RemoveUnusedRoFstsAndFigures()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Purging Unused RoFSTs and Figures Items");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCountRoFst = ESP_GetUnusedRoFsts.Execute("vesp_GetUnusedRoFstsCount");
			int rowCountFigures = ESP_GetUnusedFigures.Execute("vesp_GetUnusedFiguresCount");
			if (rowCountRoFst > 0 || rowCountFigures > 0)
			{
				ESP_PurgeUnusedRoFstsAndFigures.Execute("vesp_RemoveUnusedRoFstsAndFigures");
				int rowCountRoFst2 = ESP_GetUnusedRoFsts.Execute("vesp_GetUnusedRoFstsCount");
				int rowCountFigures2 = ESP_GetUnusedFigures.Execute("vesp_GetUnusedFiguresCount");
				txtProcess.AppendText(string.Format("{0} Unsed ROFSTs Purged", rowCountRoFst));
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(string.Format("{0} Unsed Figures Purged", rowCountFigures));
				txtProcess.AppendText(Environment.NewLine);
				//txtProcess.AppendText(Environment.NewLine);
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contained {0} unused ROFSTs.", rowCountRoFst));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database contained {0} unused Figures items.", rowCountFigures));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database now contains {0} unused ROFSTs.", rowCountRoFst2));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database now contains {0} unused Figures.", rowCountFigures2));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				if (rowCountRoFst2 > 0 || rowCountFigures2 > 0)
				{
					txtResults.AppendText("** Could not purge all or some of the unsed ROFSTs and Figures.** ");
					txtResults.AppendText("** It is recommended you contact Volian to assist in resolving this condition. **");
					txtResults.AppendText(Environment.NewLine);
					txtResults.AppendText(Environment.NewLine);
				}
			}
			else
			{
				//txtResults.Clear();
				txtProcess.AppendText(string.Format("The database contained {0} unused RoFSTs or Figures.", rowCountRoFst + rowCountFigures));
				txtProcess.AppendText(Environment.NewLine);
				//txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("No Unused ROFSTs To Remove."));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;

			//MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		}
		private void IdentifyROAssociations()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Identifing Unused RO Associations");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCount = ESP_GetROAssoc.Execute("vesp_GetUnusedROAssociationsCount");
			txtProcess.AppendText(string.Format("Unused RO Associations Count:  {0}", rowCount));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			if (rowCount > 0)
			{
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contains {0} unused RO Associations.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			else
			{
				txtResults.AppendText("No unused RO Associations Found");// B2017-108 Always output results even if there isn't any
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;

			//MessageBox.Show(string.Format("{0} Completed", "Unused RO Associations Check"), "Unused RO Associations");
		}
		private void CleanUpROAssociations()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Purging Unused Referenced Object Associations");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			int rowCount = ESP_GetROAssoc.Execute("vesp_GetUnusedROAssociationsCount");
			if (rowCount > 0)
			{
				ESP_CleanupROAssoc.Execute("vesp_GetUnusedROAssociationsCount");
				int rowCount2 = ESP_GetROAssoc.Execute("vesp_GetUnusedROAssociationsCount");
				txtProcess.AppendText(string.Format("{0} Unused Referenced Object Associations Purged", rowCount));
				txtProcess.AppendText(Environment.NewLine);
				//txtProcess.AppendText(Environment.NewLine);
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contained {0} Unused RO Associations.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("The database now contains {0} Unused RO Associations.", rowCount2));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				if (rowCount2 > 0)
				{
					txtResults.AppendText("** Could not purge all or some of the Unused RO Associations.** ");
					txtResults.AppendText("** It is recommended you contact Volian to assist in resolving this condition.**");
					txtResults.AppendText(Environment.NewLine);
					txtResults.AppendText(Environment.NewLine);
				}
			}
			else
			{
				//txtResults.Clear();
				txtResults.AppendText(string.Format("The database contained {0} Unused RO Associations.", rowCount));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(string.Format("No Unused RO Associations to Purge."));
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			
			//MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		}
		private void IdentifyNonEditableItems()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText("Identifing Hidden Item Locations");
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(string.Format("Started: {0}",pStart.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			List<ItemInfo> myItems = ESP_IdentifyNonEditableItems.Execute("vesp_GetNonEditableItems");
			txtProcess.AppendText(string.Format("Hidden Items Count:  {0}",myItems.Count));
			txtProcess.AppendText(Environment.NewLine);
			//txtProcess.AppendText(Environment.NewLine);
			if (myItems.Count > 0)
			{
				//txtResults.Clear();
				txtResults.AppendText("The following items are hidden (non-editable)...");
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				foreach (ItemInfo ii in myItems)
				{
					txtResults.AppendText(ii.Path);
					txtResults.AppendText(Environment.NewLine);
				}
				txtResults.AppendText(Environment.NewLine);
			}
			else
			{
				txtResults.AppendText("No Hidden Data Found");// B2017-108 Always output results even if there isn't any
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
			}
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(string.Format("Completed: {0}",pEnd.ToString("MM/dd/yyyy @ HH:mm")));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			//MessageBox.Show(string.Format("{0} Completed", "Hidden Data Locations Check"), "Hidden Data Locations");
		}
		private void GetDatabaseSessions()
		{
			this.Cursor = Cursors.WaitCursor;
			DateTime pStart = DateTime.Now;
			txtProcess.AppendText(pStart.ToString("MM/dd/yyyy @ HH:mm"));
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			txtResults.Clear();
			txtResults.AppendText(ESP_GetDatabaseSessions.Execute("vesp_GetDatabaseSessions"));
			DateTime pEnd = DateTime.Now;
			txtProcess.AppendText(pEnd.ToString("MM/dd/yyyy @ HH:mm"));
			Application.DoEvents();
			this.Cursor = Cursors.Default;
			MessageBox.Show( "Show Users Completed", "Show Users");
		}
		//private void FindROProblems()
		//{
		//	this.Cursor = Cursors.WaitCursor;
		//	DateTime pStart = DateTime.Now;
		//	txtProcess.AppendText(pStart.ToString("MM/dd/yyyy @ HH:mm"));
		//	txtProcess.AppendText(Environment.NewLine);
		//	txtProcess.AppendText(Environment.NewLine);
		//	Application.DoEvents();
		//	txtResults.Clear();
		//	//txtResults.AppendText(ExecuteStoredProcedureString.Execute(selectedAdminTool.StoredProcedure));
		//	DateTime pEnd = DateTime.Now;
		//	txtProcess.AppendText(pEnd.ToString("MM/dd/yyyy @ HH:mm"));
		//	Application.DoEvents();
		//	this.Cursor = Cursors.Default;
		//	MessageBox.Show(string.Format("{0} Completed", selectedAdminTool.Title), string.Format("{0} Complete", selectedAdminTool.Title));
		//}
		private void btnRefresh_Click(object sender, EventArgs e)
		{
			//txtProcess.Clear();
			//txtResults.Clear();// C2017-027 - Clear results before admin tool is run
			//Application.DoEvents();
			//if (btnRefresh.Text == "NO OPTION SELECTED")
			//{
			//	MessageBox.Show("You must select an option under the Option panel", btnRefresh.Text);
			//	return;
			//}
			//if (chkLater.Checked)
			//{
			//	long later = long.Parse(dtpDate.Value.ToString("yyyyMMdd") + dtpTime.Value.ToString("HHmm"));
			//	long now = long.Parse(DateTime.Now.ToString("yyyyMMddHHmm"));
			//	while (now < later)
			//	{
			//		txtProcess.Clear();
			//		txtProcess.AppendText("Waiting...");
			//		System.Threading.Thread.Sleep(60000);
			//		now = long.Parse(DateTime.Now.ToString("yyyyMMddHHmm"));
			//	}
			//}
			//selectedAdminTool.Execute();
		}
		private void ProcessUpdateROValues(DocVersionInfo dq)
		{
			string statmsg = string.Format("Updating ROs for {0}", dq.MyFolder.Name);
			InitialProgressBarMessage = statmsg;
			txtProcess.AppendText(statmsg);
			txtProcess.AppendText(Environment.NewLine);
			txtResults.AppendText(statmsg);
			txtResults.AppendText(Environment.NewLine);
			Application.DoEvents();
			if (dq.DocVersionAssociationCount < 1)
			{
				ProgressBar.ColorTable = eProgressBarItemColor.Error;
				FinalProgressBarMessage = "No ROs associated";
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText("Error Updating ro.fst. No associated ro.fst");
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				txtResults.AppendText("Error Updating ro.fst. No associated ro.fst");
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				return;
			}
			ROFstInfo roFstInfo = dq.DocVersionAssociations[0].MyROFst;
			string rofstPath = roFstInfo.MyRODb.FolderPath + @"\ro.fst";
			if (!File.Exists(rofstPath))
			{
				ProgressBar.ColorTable = eProgressBarItemColor.Error;
				FinalProgressBarMessage = "No existing RO.FST";
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText("No existing ro.fst in path " + roFstInfo.MyRODb.FolderPath + ". Check for invalid path");
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				txtResults.AppendText("No existing ro.fst in path " + roFstInfo.MyRODb.FolderPath + ". Check for invalid path");
				txtResults.AppendText(Environment.NewLine);
				txtResults.AppendText(Environment.NewLine);
				return;
			}
			FileInfo fiRofst = new FileInfo(rofstPath);
			Cursor = Cursors.WaitCursor;
			using (DocVersion dv = DocVersion.Get(dq.VersionID))
			{
				roFstInfo.ROTableUpdate += new ROFstInfoROTableUpdateEvent(roFstInfo_ROTableUpdate);
				ROFst newrofst = ROFstInfo.RefreshROFst(roFstInfo.MyRODb, dv.DocVersionAssociations[0], dv, roFstInfo, DoProgressBarRefresh, txtProcess);
				roFstInfo.ROTableUpdate -= new ROFstInfoROTableUpdateEvent(roFstInfo_ROTableUpdate);
			}
			Cursor = Cursors.Default;
			ProgressBar.ColorTable = eProgressBarItemColor.Normal;
			FinalProgressBarMessage = "ROs values updated";
			txtProcess.AppendText(Environment.NewLine);
			txtProcess.AppendText(Environment.NewLine);
			txtResults.AppendText("ROs values updated");
			txtResults.AppendText(Environment.NewLine);
			txtResults.AppendText(Environment.NewLine);
			return;
		}
		private void RefreshProcedureTransitions(ProcedureInfo pq)
		{
			DateTime start = DateTime.Now;
			myFixes = new StringBuilder();
			ProcedureInfo.ResetTranCounters();
			ProcedureInfo.RefreshTransitions(pq);//, transitionsToDisconnected, transitionsToNonEditable);
			TimeSpan ts = DateTime.Now - start;
			txtProcess.AppendText(string.Format("Procedure:  {1}{0}Checked {2} Transitions{0}Fixed {3} Transitions{0}Elapsed Seconds:{4}{0}{0}", Environment.NewLine, pq.DisplayNumber, ProcedureInfo.TranCheckCount, ProcedureInfo.TranFixCount, ts.TotalSeconds));
			if (myFixes.Length > 0)
			{
				txtResults.AppendText(myFixes.ToString());
				txtResults.AppendText(Environment.NewLine);
			}
			else
			{
				txtResults.AppendText("No Transitions needed fixed");
				txtResults.AppendText(Environment.NewLine);
			}
		}
		public List<string> roFstInfo_ROTableUpdate(object sender, ROFstInfoROTableUpdateEventArgs args)
		{
			return VlnFlexGrid.ROTableUpdate(sender, args);
		}
		private void PopulateTransitionInfoLists(List<ProcedureInfo> pil)
		{
			Dictionary<int, int> dic = new Dictionary<int, int>();
			StringBuilder sb = new StringBuilder();
			foreach (ProcedureInfo pi in pil)
				if (!dic.ContainsKey(pi.MyDocVersion.VersionID))
				{
					dic.Add(pi.MyDocVersion.VersionID, pi.MyDocVersion.VersionID);
					sb.Append(sb.Length == 0 ? pi.MyDocVersion.VersionID.ToString() : "," + pi.MyDocVersion.VersionID.ToString());
				}
			txtProcess.AppendText("Preparing to process...");
			txtProcess.AppendText(Environment.NewLine);
			Application.DoEvents();
			//transitionsToDisconnected = TransitionInfoList.GetTransitionsToDisconnected(sb.ToString());
			//transitionsToNonEditable = TransitionInfoList.GetTransitionsToNonEditable(sb.ToString());
		}
		private void ProgressBarShowText()
		{
			pbProcess.Refresh();
			int percent = (int)(((double)(pbProcess.Value - pbProcess.Minimum) /
			(double)(pbProcess.Maximum - pbProcess.Minimum)) * 100);
			using (Graphics gr = pbProcess.CreateGraphics())
			{
				gr.DrawString(percent.ToString() + "%",
						SystemFonts.DefaultFont,
						Brushes.Black,
						new PointF(pbProcess.Width / 2 - (gr.MeasureString(percent.ToString() + "%",
								SystemFonts.DefaultFont).Width / 2.0F),
						pbProcess.Height / 2 - (gr.MeasureString(percent.ToString() + "%",
								SystemFonts.DefaultFont).Height / 2.0F)));
			}
			Application.DoEvents();
		}
		StringBuilder myFixes;
		// show the changes made in the Results pannel, include the ItemId of the step element
		void ContentInfo_StaticContentInfoChange(object sender, StaticContentInfoEventArgs args)
		{
			if (args.Type == "TX")
			{
				if (args.NewValue.StartsWith("Reason for Change:"))
					myFixes.AppendLine(string.Format("Fixed Transition for {1}({4}){0}Old Text: {2}{0}{3}{0}", Environment.NewLine, (sender as ItemInfo).ShortPath, args.OldValue, args.NewValue, (sender as ItemInfo).ItemID));
				else
					myFixes.AppendLine(string.Format("Fixed Transition for {1}({4}){0}Old Text: {2}{0}New Text: {3}{0}", Environment.NewLine, (sender as ItemInfo).ShortPath, args.OldValue, args.NewValue, (sender as ItemInfo).ItemID));
			}
			else if (args.Type == "RO")
			{
				txtResults.AppendText(string.Format("Fixed Referenced Object for {1}({4}){0}Old Text: {2}{0}New Text: {3}{0}{0}", Environment.NewLine, (sender as ItemInfo).ShortPath, args.OldValue, args.NewValue,(sender as ItemInfo).ItemID));
				Application.DoEvents();
				//myFixes.AppendLine(string.Format("Fixed Referenced Object for {1}{0}Old Text: {2}{0}New Text: {3}{0}", Environment.NewLine, (sender as ItemInfo).ShortPath, args.OldValue, args.NewValue));
			}
		}
		private void btnClear_Click(object sender, EventArgs e)
		{
			txtResults.Clear();
		}
		private void btnSave_Click(object sender, EventArgs e)
		{
			SaveFileDialog sfd = new SaveFileDialog();
			sfd.DefaultExt = "txt";
			sfd.AddExtension = true;
			sfd.Filter = "Text Files (*.txt)|*.txt";
			sfd.FileName = string.Format("BatchRefreshResults_{0}", DateTime.Now.ToString("yyyyMMdd_HHmm"));
			sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\VEPROMS";
			DialogResult dr = sfd.ShowDialog();
			if (dr == DialogResult.OK)
			{
				System.IO.StreamWriter sw = new System.IO.StreamWriter(sfd.FileName);
				sw.Write(txtResults.Text);
				sw.Close();
			}
		}
		private void myTV_AfterCheck(object sender, TreeViewEventArgs e)
		{
			if (e.Action != TreeViewAction.Unknown)
				if(e.Node.Nodes.Count > 0)
					CheckChildNodes(e.Node, e.Node.Checked);
			btnFixLinks.Enabled = AtLeastOneNodeChecked();
		}
		private void CheckChildNodes(TreeNode treeNode, bool ischecked)
		{
			foreach (TreeNode tn in treeNode.Nodes)
			{
				tn.Checked = ischecked;
				if (tn.Nodes.Count > 0)
					CheckChildNodes(tn, ischecked);
			}
		}
		private ProgressBarItem _ProgressBar = null;
		public ProgressBarItem ProgressBar
		{
			get { return _ProgressBar; }
			set 
			{ 
				_ProgressBar = value; 
				_ProgressBar.TextVisible = true;
			}
		}
		private void DoProgressBarRefresh(int value, int max, string text)
		{
			if (ProgressBar == null) return;
			ProgressBar.Maximum = max;
			ProgressBar.Value = value;
			ProgressBar.Text = text;
			Application.DoEvents();
		}
		private string InitialProgressBarMessage
		{
			set
			{
				if (ProgressBar == null) return;
				ProgressBar.Maximum = 100;
				ProgressBar.Value = 0;
				ProgressBar.Text = value;
				txtProcess.AppendText(value);
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				Application.DoEvents();
			}
		}
		private string FinalProgressBarMessage
		{
			set
			{
				if (ProgressBar == null) return;
				ProgressBar.Value = 100;
				ProgressBar.Maximum = 100;
				ProgressBar.Text = value;
				txtProcess.AppendText(value);
				txtProcess.AppendText(Environment.NewLine);
				txtProcess.AppendText(Environment.NewLine);
				Application.DoEvents();
			}
		}
		private void cbxAdminTools_SelectedIndexChanged(object sender, EventArgs e)
		{
			//selectedAdminTool = cbxAdminTools.SelectedItem as AdminTool;
			//if (selectedAdminTool == null)
			//{
			//	lblCaption.Text = string.Empty;
			//	lblDescription.Text = string.Empty;
			//	lblWarning.Text = string.Empty;
			//	myTV.Nodes.Clear();
			//	btnRefresh.Text = "NO OPTION SELECTED";
			//}
			//else
			//{
			//	lblCaption.Text = selectedAdminTool.Caption;
			//	lblDescription.Text = selectedAdminTool.Description;
			//	lblWarning.Text = selectedAdminTool.WarningPrefix + "  " + selectedAdminTool.Warning;
			//	lblWarning.Visible = selectedAdminTool.Warning.Length > 0;
			//	ResetTV(selectedAdminTool.NoProcedures);
			//	btnRefresh.Text = selectedAdminTool.Title;
			//	lblCaption.Focus();
			//}
		}
		private void chkLater_CheckedChanged(object sender, EventArgs e)
		{
			pnlLater.Enabled = chkLater.Checked;
		}
		private void cbxAdminTools_Click(object sender, EventArgs e)
		{
			//cbxAdminTools.DroppedDown = true; // expand dropdown list if user clicks anywhere on the dropdown control
		}

		private void sideNavItmCheck_Click(object sender, EventArgs e)
		{
			AdminToolType = E_AdminToolType.Check;
			lblAdmToolProgressType.Text = "Checking:";
			setupProgessSteps1();
		}

		private void sideNavItmRepair_Click(object sender, EventArgs e)
		{
			AdminToolType = E_AdminToolType.Repair;
			lblAdmToolProgressType.Text = "Repairing:";
			setupProgessSteps1();
		}

		private void sideNavItmLinks_Click(object sender, EventArgs e)
		{
			AdminToolType = E_AdminToolType.Links;
			setupProgessSteps1();
			if (swUpdateROVals.Value)
				ResetTV(true);
			else
				ResetTV(false);
		}

		private void sideNavItmUsers_Click(object sender, EventArgs e)
		{
			AdminToolType = E_AdminToolType.Users;
			setupProgessSteps1();
		}

		private void sideNavItmExit_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		private void btn_ShowUsers_Click(object sender, EventArgs e)
		{
			txtProcess.Clear();
			txtResults.Clear();
			GetDatabaseSessions();

		}
		#region On/Off Swiches
		private enum E_AdminToolType : int
		{
			Check = 0,
			Repair = 1,
			Links = 2,
			Users = 3
		};
		private E_AdminToolType AdminToolType = 0;

		DevComponents.DotNetBar.StepItem siOrphDatRecs = new DevComponents.DotNetBar.StepItem("siOrphDatRecs", "Orphan Data Records");
		DevComponents.DotNetBar.StepItem siHiddenDataLocs = new DevComponents.DotNetBar.StepItem("siHiddenDataLocs", "Hidden Data");
		DevComponents.DotNetBar.StepItem siObsoleteROData = new DevComponents.DotNetBar.StepItem("siObsoleteROData", "Obsolete RO Data");
		DevComponents.DotNetBar.StepItem siStandardHyphens = new DevComponents.DotNetBar.StepItem("siStandardHyphens", "Standardize Hyphens");
		DevComponents.DotNetBar.StepItem siRefreshAttmts = new DevComponents.DotNetBar.StepItem("siRefreshAttmts", "Refresh Word Attachments");
	
		private void setupProgessSteps1()
		{
			progressSteps1.Visible = false;
			progressSteps1.Items.Clear();
			switch (AdminToolType)
			{
				case E_AdminToolType.Check:
					if (swCkOrphanDataRecs.Value)
						progressSteps1.Items.Add(siOrphDatRecs);
					if (swHiddenDataLocs.Value)
						progressSteps1.Items.Add(siHiddenDataLocs);
					if (swCkObsoleteROData.Value)
						progressSteps1.Items.Add(siObsoleteROData);
					splitContainer3.Panel2Collapsed = false;
					progressSteps1.Visible = true;
					progressSteps1.Refresh();
					break;
				case E_AdminToolType.Repair:
					if (swRmOrphanDataRecs.Value)
						progressSteps1.Items.Add(siOrphDatRecs);
					if (swRmObsoleteROData.Value)
						progressSteps1.Items.Add(siObsoleteROData);
					if (swStandardHypenChars.Value)
						progressSteps1.Items.Add(siStandardHyphens);
					if (swRefreshWordAttmts.Value)
						progressSteps1.Items.Add(siRefreshAttmts);
					splitContainer3.Panel2Collapsed = false;
					progressSteps1.Visible = true;
					progressSteps1.Refresh();
					break;
				case E_AdminToolType.Links:
				case E_AdminToolType.Users:
					splitContainer3.Panel2Collapsed = true;
					progressSteps1.Visible = false;
					break;
			}
		}
		// used for all of the Switch buttons (ON/OFF buttons)
		private void swCk_ValueChanged(object sender, EventArgs e)
		{
			setupProgessSteps1();
		}
		#endregion

		private void swUpdateROVals_ValueChanged(object sender, EventArgs e)
		{
			if (swUpdateROVals.Value)
			{
				swRefreshTrans.Value = false;
				ResetTV(true);
			}
		}

		private void swRefreshTrans_ValueChanged(object sender, EventArgs e)
		{
			if (swRefreshTrans.Value)
			{
				swUpdateROVals.Value = false;
				ResetTV(false);
			}
		}

		private void btnFixLinks_Click(object sender, EventArgs e)
		{
			txtProcess.Clear();
			txtResults.Clear();
			if (swRefreshTrans.Value)
				RefreshTransitions();
			if (swUpdateROVals.Value)
				UpdateROValues();
		}

		private void btnRunCheck_Click(object sender, EventArgs e)
		{
			int prgStpIdx = -1;
			txtResults.Clear();
			txtProcess.Clear();
			if (swCkOrphanDataRecs.Value)
			{
				StepProgress(++prgStpIdx, 50);
				IdentifyDisconnectedItems(); // orphan items
				StepProgress(prgStpIdx, 100);
			}
			if (swHiddenDataLocs.Value)
			{
				StepProgress(++prgStpIdx, 50);
				IdentifyNonEditableItems(); // hidden items
				StepProgress(prgStpIdx, 100);
			}
			if (swCkObsoleteROData.Value)
			{
				StepProgress(++prgStpIdx, 25);
				IdentifyROAssociations();
				StepProgress(prgStpIdx, 50);
				IdentifyUnusedRoFstsAndFigures();
				StepProgress(prgStpIdx, 100);
			}
			MessageBox.Show("Check Functions Completed", "Check");
			ClearStepProgress();
		}

		private void StepProgress(int prgStpIdx, int val)
		{
			((DevComponents.DotNetBar.StepItem)progressSteps1.Items[prgStpIdx]).Value = val;
			return;
		}
		private void ClearStepProgress()
		{
			for (int i =0; i< progressSteps1.Items.Count; i++)
				((DevComponents.DotNetBar.StepItem)progressSteps1.Items[i]).Value = 0;
		}
		private void btnRunRepair_Click(object sender, EventArgs e)
		{
			int prgStpIdx = -1;
			txtResults.Clear();
			txtProcess.Clear();
			if (swRmOrphanDataRecs.Value)
			{
				StepProgress(++prgStpIdx, 50);
				PurgeDisconnectedItems(); // Orphan Items
				StepProgress(prgStpIdx, 100);
			}
			if (swRmObsoleteROData.Value)
			{
				StepProgress(++prgStpIdx, 25);
				CleanUpROAssociations();
				StepProgress(prgStpIdx, 50);
				RemoveUnusedRoFstsAndFigures();
				StepProgress(prgStpIdx, 100);
			}
			if (swStandardHypenChars.Value)
			{
				StepProgress(++prgStpIdx, 50);
				FixHyphens();
				StepProgress(prgStpIdx, 100);
			}
			if (swRefreshWordAttmts.Value)
			{
				StepProgress(++prgStpIdx, 50);
				DeletePDFs();  // refresh word attachments
				StepProgress(prgStpIdx, 100);
			}

			MessageBox.Show("Repair Functions Completed", "Repair");
			ClearStepProgress();
		}

	}
	//public class AdminTool : IComparable<AdminTool>
	//{
	//	private string _Title;
	//	public string Title
	//	{
	//		get { return _Title; }
	//		set { _Title = value; }
	//	}
	//	private string _Caption;
	//	public string Caption
	//	{
	//		get { return _Caption; }
	//		set { _Caption = value; }
	//	}
	//	private string _Description;
	//	public string Description
	//	{
	//		get { return _Description; }
	//		set { _Description = value; }
	//	}
	//	private string _Warning;
	//	public string Warning
	//	{
	//		get { return _Warning; }
	//		set { _Warning = value; }
	//	}
	//	private string _WarningPrefix;
	//	public string WarningPrefix
	//	{
	//		get { return _WarningPrefix; }
	//		set { _WarningPrefix = value; }
	//	}
	//	private bool _NoProcedures;
	//	public bool NoProcedures
	//	{
	//		get { return _NoProcedures; }
	//		set { _NoProcedures = value; }
	//	}
	//	private bool _NoTreeView;
	//	public bool NoTreeView
	//	{
	//		get { return _NoTreeView; }
	//		set { _NoTreeView = value; }
	//	}
	//	private AdminToolExecute _MyExecute;
	//	public AdminToolExecute MyExecute
	//	{
	//		get { return _MyExecute; }
	//		set { _MyExecute = value; }
	//	}
	//	private string _StoredProcedure;
	//	public string StoredProcedure
	//	{
	//		get { return _StoredProcedure; }
	//		set { _StoredProcedure = value; }
	//	}
	//	public void Execute()
	//	{
	//		if (MyExecute != null) MyExecute();
	//	}
	//	public AdminTool()
	//	{
	//	}
	//	public AdminTool(string title, string caption, string description, string warning, string warningPrefix, bool noProcedures, bool noTreeView, AdminToolExecute myExecute)
	//	{
	//		_Title = title;
	//		_Caption = caption;
	//		_Description = description;
	//		_Warning = warning;
	//		_WarningPrefix = warningPrefix;
	//		_NoProcedures = noProcedures;
	//		_NoTreeView = noTreeView;
	//		_MyExecute = myExecute;
	//	}
	//	public AdminTool(string title, string caption, string description, string warning, string warningPrefix, bool noProcedures, bool noTreeView, string storedProcedure, AdminToolExecute myExecute)
	//	{
	//		_Title = title;
	//		_Caption = caption;
	//		_Description = description;
	//		_Warning = warning;
	//		_WarningPrefix = warningPrefix;
	//		_NoProcedures = noProcedures;
	//		_NoTreeView = noTreeView;
	//		_StoredProcedure = storedProcedure;
	//		_MyExecute = myExecute;
	//	}
	//	public int CompareTo(AdminTool at)
	//	{
	//		return this.Title.CompareTo(at.Title);
	//	}
	//}
	//public class AdminTools : List<AdminTool>
	//{
	//	public void Add(string title, string caption, string description, string warning, string warningPrefix, bool noProcedures, bool noTreeView, AdminToolExecute myExecute)
	//	{
	//		base.Add(new AdminTool(title, caption, description, warning, warningPrefix, noProcedures, noTreeView, myExecute));
	//	}
	//	public void Add(string title, string caption, string description, string warning, string warningPrefix, bool noProcedures, bool noTreeView, string storedProcedure, AdminToolExecute myExecute)
	//	{
	//		base.Add(new AdminTool(title, caption, description, warning, warningPrefix, noProcedures, noTreeView, storedProcedure, myExecute));
	//	}
	//}
	//public delegate void AdminToolExecute();
}
