using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using VEPROMS.CSLA.Library;
using Volian.Controls.Library;
using DevComponents.DotNetBar;
namespace Volian.Controls.Library
{
	public delegate void DisplayTabControlEvent(object sender,EventArgs args);
	public partial class DisplayTabControl : UserControl
	{
		public event DisplayTabControlEvent ToggleRibbonExpanded;
		public void OnToggleRibbonExpanded(object sender, EventArgs args)
		{
			if (ToggleRibbonExpanded != null) ToggleRibbonExpanded(sender,args);
		}
		public event DisplayTabControlEvent SelectedDisplayTabItemChanged;
		public void OnSelectedDisplayTabItemChanged(object sender, EventArgs args)
		{
			if (SelectedDisplayTabItemChanged != null)SelectedDisplayTabItemChanged(sender, args);
		}
		#region Private Fields
		/// 
		/// This is a lookup table for all of the DisplayTabItems that are currently open
		/// The key is:
		///		"Item - " + Procedure ItemID for step pages
		///		"Doc - " + DocumentID for Word Documents
		/// 
		private Dictionary _MyDisplayTabItems;
		/// 
		/// When a Tab is closed it is added to this list.
		/// When another Tab is opened, any Tabs in this list are closed
		/// 
		private List _RemovedDisplayTabItems = null;
		/// 
		/// This stores a UniqueID for Bars as they are opened.  
		/// A bar is the docking location for the DisplayTabItems.
		/// 
		private int _UniqueBarCount;
		private ItemInfo _MyItemInfo = null;
		private EditItem _MyEditItem = null;
		private StepRTB _MyStepRTB = null;
		private bool _RibbonExpanded=true;
		public bool RibbonExpanded
		{
			get { return _RibbonExpanded; }
			set 
			{
				_RibbonExpanded = value;
				foreach (DisplayTabItem tabItem in _MyDisplayTabItems.Values)
					if (tabItem.MyStepTabPanel != null)
						tabItem.MyStepTabPanel.MyStepTabRibbon.Expanded = _RibbonExpanded;
			}
		}
		private ItemInfo _MyCopyStep;
		public ItemInfo MyCopyStep
		{
			get { return _MyCopyStep; }
			set { _MyCopyStep = value; }
		}
		#endregion
		#region Events
		/// 
		/// This event is raised when a the "Tab" of a DisplayItem is clicked with a mouse.  
		/// So far this has just been used for demo purposes.  It could be used to select a
		/// step and it's children for the purpose of copying.
		/// 
		public event StepPanelEvent ItemClick;
		/// 
		/// Checks to see if the ItemClick event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnItemClick(object sender, StepPanelEventArgs args)
		{
			if (ItemClick != null) ItemClick(sender, args);
		}
		/// 
		/// This occurs when the user moves onto or off of a link within a RichTextBox 
		/// or moves between RichTextBoxes or Pages.
		/// 
		public event StepPanelLinkEvent LinkActiveChanged;
		/// 
		/// Checks to see if the LinkActiveChanged event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnLinkActiveChanged(object sender, StepPanelLinkEventArgs args)
		{
			if (LinkActiveChanged != null) LinkActiveChanged(sender, args);
			else MessageBox.Show(args.LinkInfoText, "Unhandled Link Active Changed", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		/// 
		/// This occurs when a Transition is inserted
		/// 
		public event StepPanelLinkEvent LinkInsertTran;
		/// 
		/// Checks to see if the 'LinkInsertTran' event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnLinkInsertTran(object sender, StepPanelLinkEventArgs args)
		{
			if (LinkInsertTran != null) LinkInsertTran(sender, args);
			else MessageBox.Show(args.LinkInfoText, "Unhandled Link Insert Tran", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		/// 
		/// This occurs when an RO is inserted
		/// 
		public event StepPanelLinkEvent LinkInsertRO;
		/// 
		/// Checks to see if the 'LinkInsertRO' event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnLinkInsertRO(object sender, StepPanelLinkEventArgs args)
		{
			if (LinkInsertRO != null) LinkInsertRO(sender, args);
			else MessageBox.Show(args.LinkInfoText, "Unhandled Link Insert RO", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		/// 
		///  This occurs when a Transition is modified
		/// 
		public event StepPanelLinkEvent LinkModifyTran;
		/// 
		/// Checks to see if the 'LinkModifyTran' event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnLinkModifyTran(object sender, StepPanelLinkEventArgs args)
		{
			if (LinkModifyTran != null) LinkModifyTran(sender, args);
			else MessageBox.Show(args.LinkInfoText, "Unhandled Link Modify Tran", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		/// 
		/// This occurs when an RO is modified
		/// 
		public event StepPanelLinkEvent LinkModifyRO;
		/// 
		/// Checks to see if the 'LinkModifyRO' event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnLinkModifyRO(object sender, StepPanelLinkEventArgs args)
		{
			if (LinkModifyRO != null) LinkModifyRO(sender, args);
			else MessageBox.Show(args.LinkInfoText, "Unhandled Link Modify RO", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		/// 
		/// Occurs when the user selects a different item or page
		/// 
		public event ItemSelectedChangedEvent ItemSelectedChanged;
		/// 
		/// Checks to see if the 'ItemSelectedChanged' event is handled and launches it
		/// 
		/// 
		/// 
		internal void OnItemSelectedChanged(object sender, ItemSelectedChangedEventArgs args)
		{
			if (args != null)
			{
				_MyItemInfo = args.MyItemInfo;
				_MyEditItem = args.MyEditItem;
				if (_MyEditItem != null)
				{
					_MyStepRTB = _MyEditItem.MyStepRTB;
					if(_MyStepRTB != null)
						_MyStepRTB.Disposed += new EventHandler(_MyStepRTB_Disposed);
				}
				else
					_MyStepRTB = null;
			}
			else
			{
				_MyItemInfo = null;
				_MyEditItem = null;
				_MyStepRTB = null;
			}
			if (ItemSelectedChanged != null) ItemSelectedChanged(sender, args);
		}
		void _MyStepRTB_Disposed(object sender, EventArgs e)
		{
			_MyStepRTB = null;
		}
		public event StepPanelModeChangeEvent ModeChange;
		internal void OnModeChange(object sender, StepRTBModeChangeEventArgs args)
		{
			if (ModeChange != null) ModeChange(sender, args);
			else MessageBox.Show("Cannot change mode");
		}
		public event StepPanelTabDisplayEvent PanelTabDisplay;
		internal void OnPanelTabDisplay(object sender, StepPanelTabDisplayEventArgs args)
		{
			if (PanelTabDisplay != null) PanelTabDisplay(sender, args);
			else MessageBox.Show("Cannot display information");
		}
		public event StepPanelWordSectionCloseEvent WordSectionClose;
		internal void OnWordSectionClose(object sender, WordSectionEventArgs args)
		{
			if (WordSectionClose != null) WordSectionClose(sender, args);
			else MessageBox.Show("Cannot close associated Word section");
		}
		public event StepPanelWordSectionDeletedEvent WordSectionDeleted;
		internal void OnWordSectionDeleted(object sender, WordSectionEventArgs args)
		{
			if (WordSectionDeleted != null) WordSectionDeleted(sender, args);
			else MessageBox.Show("Cannot delete associated Word section");
		}
		public event StepPanelItemPastedEvent ItemPaste;
		internal void OnItemPaste(object sender, vlnTreeItemInfoPasteEventArgs args)
		{
			if (ItemPaste != null) ItemPaste(sender, args);
			else MessageBox.Show("Cannot adjust panels for pasted item");
		}
		#endregion
		#region Contructor & Setup
		public DisplayTabControl()
		{
			InitializeComponent();
			SetUp();
		}
		private void SetUp()
		{
			_RemovedDisplayTabItems = new List();
			Dock = DockStyle.Fill;
			dotNetBarManager1.Style = DevComponents.DotNetBar.eDotNetBarStyle.Office2007;
			_MyDisplayTabItems = new Dictionary();
			SetupBar(_MyBar);
			dotNetBarManager1.BarTearOff += new EventHandler(dotNetBarManager1_BarTearOff);
			this.Resize += new EventHandler(DisplayTabControl_Resize);
		}
		void DisplayTabControl_Resize(object sender, EventArgs e)
		{
			// If the currently selected Item is in a Step, then adjust the scroll as necessary to keep it visible
			if (_MyEditItem != null)
				_MyEditItem.ItemShow();
		}
		private void SetupBar(Bar myBar)
		{
			if (myBar.DockTabControl != null)
			{
				myBar.DockTabControl.CloseButtonOnTabsVisible = true;
				myBar.DockTabControl.CloseButtonVisible = false;
				myBar.DockTabControl.CloseButtonPosition = DevComponents.DotNetBar.eTabCloseButtonPosition.Right;
				myBar.DockTabControl.Width = ClientRectangle.Width;
			}
			myBar.DockTabClosing += new DockTabClosingEventHandler(myBar_DockTabClosing);
			if (!myBar.Visible)
				myBar.Visible = true;
			myBar.RecalcLayout();
		}
		#endregion
		#region Internal Event Handlers
		/// 
		/// This is code recommended by DotNetBar
		/// 
		/// 
		/// 
		void dotNetBarManager1_BarTearOff(object sender, EventArgs e)
		{
			Bar myBar = sender as Bar;
			myBar.Enter += new EventHandler(myBar_Enter);
		}
		/// 
		/// This sets-up the bar after it is selected.
		/// 
		/// 
		/// 
		void myBar_Enter(object sender, EventArgs e)
		{
			Bar myBar = sender as Bar;
			myBar.Enter -= new EventHandler(myBar_Enter);
			SetupBar(sender as Bar);
		}
		/// 
		/// This handles the closing of a document page
		/// 
		/// 
		/// 
		void myBar_DockTabClosing(object sender, DockTabClosingEventArgs e)
		{
			e.RemoveDockTab = true;
			_RemovedDisplayTabItems.Add((DisplayTabItem)e.DockContainerItem);
			DisplayTabItem dti = e.DockContainerItem as DisplayTabItem;
			if (dti != null && dti.MyStepTabPanel != null)
				dti.MyStepTabPanel.MyStepPanel.Dispose();
			DisplayTabItem myTabItem = e.DockContainerItem as DisplayTabItem;
			if (myTabItem != null)
			{
				if (myTabItem.MyDSOTabPanel != null)
				{
					myTabItem.MyDSOTabPanel.CloseDSO();
				}
			}
			if (((Bar)sender).Items == null) return;
			if (((Bar)sender).Items.Count == 1)// Remove bar if last item is closed...
			{
				Bar bar = sender as Bar;
				if (bar != null)
				{
					if (dotNetBarManager1.Bars.Contains(bar.Name))
						dotNetBarManager1.Bars.Remove(bar);
					ActivateRemainingTab();
				}
			}
			else
			{
				ActivateRemainingTab((Bar)sender);
			}
		}
		#endregion
		#region Public Methods
		/// 
		/// Open a Step Item or a Word Item
		/// 
		/// 
		/// 
		public DisplayTabItem OpenItem(ItemInfo myItemInfo)
		{
			CleanUpClosedItems();
			if (myItemInfo == null) return null;
			// if this is an auto table of contents section, don't edit it:
			if (myItemInfo.IsAutoTOCSection) 
			{
				MessageBox.Show("This is an automatically generated 'Table of Contents' section. It is not editable. It is generated during Print.", "Item not Editable", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return SelectedDisplayTabItem;
			}
			_MyBar = GetParentBar(myItemInfo); // Get the docking bar associated with this item.
			if (myItemInfo.MyContent.MyEntry == null) // If it is a Word document open in step editor
				return OpenStepTabPage(myItemInfo);
			else // Otherwise open it in the Word editor
				return OpenDSOTabPage(myItemInfo);
		}
		public bool PasteRTBItem(ItemInfo myItemInfo, int copyStartID, ItemInfo.EAddpingPart pasteType, int type)
		{
			CleanUpClosedItems();
			ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item
			string key = "Item - " + proc.ItemID.ToString();
			if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it
			{
				DisplayTabItem pg = _MyDisplayTabItems[key];
				if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID))
				{
					EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID];
					switch (pasteType)
					{
						case ItemInfo.EAddpingPart.Before:
							edtitm.PasteSiblingBefore(copyStartID);
							break;
						case ItemInfo.EAddpingPart.After:
							edtitm.PasteSiblingAfter(copyStartID);
							break;
						case ItemInfo.EAddpingPart.Replace:
							edtitm.PasteReplace(copyStartID);
							edtitm.Dispose();
							break;
						default:
							return false; ;
					}
					return true;
				}
			}
			return false;
		}
		public bool DeleteRTBItem(ItemInfo myItemInfo)
		{
			CleanUpClosedItems();
			
			//removeitem!
			ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item
			string key = "Item - " + proc.ItemID.ToString();
			
			if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it
			{
				DisplayTabItem pg = _MyDisplayTabItems[key];
				// if deleting a procedure, close the tab.
				if (proc.ItemID == myItemInfo.ItemID)
				{
					// do we need to close open doc tabs associated with this proc.
					CloseTabItem(pg);
					return false;
				}
				if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID))
				{
					EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID];
					edtitm.RemoveItem();
					return true;
				}
			}
			return false;
		}
		public bool InsertRTBItem(ItemInfo myItemInfo, string text, E_InsertType insertType, E_FromType fromType, int type,bool updateSelection)
		{
			CleanUpClosedItems();
			ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item
			string key = "Item - " + proc.ItemID.ToString();
			if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it
			{
				DisplayTabItem pg = _MyDisplayTabItems[key];
				if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID))
				{
					EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID];
					switch (insertType)
					{
						case E_InsertType.Before:
							edtitm.AddSiblingBefore(text,updateSelection);
							break;
						case E_InsertType.After:
							edtitm.AddSiblingAfter(text,updateSelection);
							break;
						case E_InsertType.Child:
							edtitm.AddChild(text, fromType, type, null);
							break;
						default:
							return false; ;
					}
					return true;
				}
			}
			return false; 
		}
		private void CleanUpClosedItems()
		{
			while (_RemovedDisplayTabItems.Count > 0) // Clean-up any items that have been closed.
			{
				DisplayTabItem myTabItem = _RemovedDisplayTabItems[0];
				_RemovedDisplayTabItems.RemoveAt(0);
				RemoveItem(myTabItem);
			}
		}
		public void CloseWordItem(ItemInfo myItemInfo)
		{
			CloseWordItem(myItemInfo, false);
		}
		public void CloseWordItem(ItemInfo myItemInfo, bool isBeingDeleted)
		{
			CleanUpClosedItems();
			string key = "Doc - ";
			// there is no entry if it is an auto table of contents:
			if (myItemInfo.MyContent.MyEntry != null)
				 key = key + myItemInfo.MyContent.MyEntry.MyDocument.DocID.ToString();
			else
				key = key + "0";
			DisplayTabItem myTabItem = null;
			if (_MyDisplayTabItems.ContainsKey(key)) // If page open, close it
			{
				myTabItem = _MyDisplayTabItems[key];
				if (myTabItem.MyDSOTabPanel != null)
				{
					myTabItem.MyDSOTabPanel.IsBeingDeleted = isBeingDeleted;
					CloseTabItem(myTabItem);
				}
			}
		}
		public void CloseTabItem(DisplayTabItem myTabItem)
		{
			Bar b = myTabItem.ContainerControl as Bar;
			b.CloseDockTab(myTabItem);
			//b.Items.Remove(myTabItem);
			RemoveItem(myTabItem);
		}
		/// 
		/// Look for a tab and set it to active.
		/// 
		private void ActivateRemainingTab()
		{
			foreach (Bar myBar in dotNetBarManager1.Bars)
			{
				if (myBar.DockSide == eDockSide.Document && myBar.Visible)
				{
					ActivateRemainingTab(myBar);
					return;
				}
			}
			// No Document Tabs Remaining - need to raise OnItemSelectedChanged
			OnItemSelectedChanged(this, null);
		}
		private DisplayTabItem FindRemainingTab(Bar myBar)
		{
			foreach (DisplayTabItem itm in myBar.Items)
			{
				if (!_RemovedDisplayTabItems.Contains(itm)) return itm;
			}
			return null;
		}
		private void ActivateRemainingTab(Bar myBar)
		{
			if (myBar.SelectedDockContainerItem != null)
			{
				if (_RemovedDisplayTabItems.Contains(myBar.SelectedDockContainerItem as DisplayTabItem))
					myBar.SelectedDockContainerItem = FindRemainingTab(myBar);
				myBar.SelectedDockContainerItem.Selected = true;
				StepTabPanel pnl = myBar.SelectedDockContainerItem.Control as StepTabPanel;
				if (pnl != null)
					pnl.MyStepPanel.ItemShow();
			}
		}
		#endregion
		#region Public Properties
		public DevComponents.DotNetBar.Bar MyBar
		{
			get { return _MyBar; }
		}
		public Panel PnlCaret
		{
			get { return _PnlCaret; }
		}
		private Color _OldForeColor = Color.Empty;
		private Color _OldBackColor = Color.Empty;
		public void ShowCaret()
		{
			if (_MyStepRTB != null)
			{
				if (_MyEditItem.RTBLastFocus)
				{
					if (!_MyStepRTB.Visible)
						_MyStepRTB.Visible = true;
					if (_MyStepRTB.SelectionLength == 0)
					{
						Point pt = _MyStepRTB.GetPositionFromCharIndex(_MyStepRTB.SelectionStart);
						pt = _MyStepRTB.PointToScreen(pt);
						pt = this.PointToClient(pt);
						PnlCaret.Location = pt;
						PnlCaret.BackColor = _MyStepRTB.ForeColor;
						using (Graphics gr = this.CreateGraphics())
						{
							SizeF sf = gr.MeasureString("Mg", _MyStepRTB.SelectionFont);
							sf.Width = 1;
							PnlCaret.Size = sf.ToSize();
						}
						tmrCaret.Enabled = true;
					}
					else
					{
						if (_MyStepRTB.SelectionColor != Color.Empty && _OldForeColor == Color.Empty)
						{
							_OldForeColor = _MyStepRTB.SelectionColor;
							_MyStepRTB.SelectionColor = Color.White;
						}
						if (_MyStepRTB.SelectionBackColor != Color.Empty && _OldBackColor == Color.Empty)
						{
							_OldBackColor = _MyStepRTB.SelectionBackColor;
							_MyStepRTB.SelectionBackColor = Color.FromName("Highlight");
						}
					}
				}
			}
		}
		public void HideCaret()
		{
			if (_MyStepRTB != null && !_MyStepRTB.Disposing && !_MyStepRTB.Closed)
			{
				if (_MyStepRTB.SelectionLength == 0)
				{
					tmrCaret.Enabled = false;
					PnlCaret.Visible = false;
				}
				else
				{
					if (_OldForeColor != Color.Empty)
					{
						_MyStepRTB.SelectionColor = _OldForeColor;
						_OldForeColor = Color.Empty;
					}
					if (_OldBackColor != Color.Empty)
					{
						_MyStepRTB.SelectionBackColor = _OldBackColor;
						_OldBackColor = Color.Empty;
					}
				}
			}
		}
		private void tmrCaret_Tick(object sender, EventArgs e)
		{
			PnlCaret.Visible = !PnlCaret.Visible;
		}
		#endregion
		#region Private Methods
		///// 
		///// Gets and sets the SelectedDisplayTabItem (Active Tab)
		///// 
		//public DisplayTabItem SelectedDisplayTabItem1
		//{
		//  get { return (DisplayTabItem)_MyBar.SelectedDockContainerItem; }
		//  set
		//  {
		//    //Volian.Base.Library.vlnStackTrace.ShowStackLocal("SelectedDisplayTabItem");
		//    if (value != null)
		//    {
		//      value.Focus();
		//      value.Selected = true;
		//    }
		//  }
		//}
		public void SelectDisplayTabItem(DisplayTabItem myDisplayTabItem)
		{
			if (myDisplayTabItem != null)
			{
				if (!myDisplayTabItem.Selected)
				{
					myDisplayTabItem.Focus();
					myDisplayTabItem.Selected = true;
				}
			}
		}
		private DisplayTabItem _SelectedDisplayTabItem=null;
		public DisplayTabItem SelectedDisplayTabItem
		{
			get { return _SelectedDisplayTabItem; }
			set 
			{
				if (_SelectedDisplayTabItem != value)
				{
					if (_SelectedDisplayTabItem != null && _SelectedDisplayTabItem.MyDSOTabPanel != null)
						_SelectedDisplayTabItem.MyDSOTabPanel.InActive();
					_SelectedDisplayTabItem = value;
					OnSelectedDisplayTabItemChanged(this, new EventArgs());
				}
			}
		}
		/// 
		/// This returns the parent bar (current docking location) for an item.  
		/// It creates a bar if none exist
		/// 
		/// 
		/// 
		private Bar GetParentBar(ItemInfo myItemInfo)
		{
			Bar myBar = null;
			foreach (Bar b in dotNetBarManager1.Bars)
			{
				if (b.DockSide == eDockSide.Document && b.Visible)
				{
					if (myBar == null) myBar = b;// Remember the first available bar if a specific bar cannot be found
					foreach (object itm in b.Items)
					{
						DisplayTabItem myTabItem = itm as DisplayTabItem;
						if (myTabItem != null && myTabItem.MyStepTabPanel != null)
							if (myTabItem.MyStepTabPanel.MyProcedureItemInfo.ItemID == myItemInfo.MyProcedure.ItemID)
								return b;
					}
				}
			}
			if (myBar == null)
			{
				// If no documents bars found, create new one
				_UniqueBarCount++;
				myBar = BarUtilities.CreateDocumentBar();
				myBar.DockTabClosing += new DockTabClosingEventHandler(myBar_DockTabClosing);
				myBar.Name = "barDocuments" + _UniqueBarCount.ToString();
				fillDocDockSite.GetDocumentUIManager().Dock(myBar);
				SetupBar(myBar);
			}
			return myBar;
		}
		public StepTabPanel GetProcedureTabPanel(ItemInfo myItemInfo)
		{
			Bar myBar = null;
			foreach (Bar b in dotNetBarManager1.Bars)
			{
				if (b.DockSide == eDockSide.Document && b.Visible)
				{
					if (myBar == null) myBar = b;// Remember the first available bar if a specific bar cannot be found
					foreach (object itm in b.Items)
					{
						DisplayTabItem myTabItem = itm as DisplayTabItem;
						if (myTabItem != null && myTabItem.MyStepTabPanel != null && myTabItem.MyStepTabPanel.MyProcedureItemInfo != null)
							if (myTabItem.MyStepTabPanel.MyProcedureItemInfo.ItemID == myItemInfo.MyProcedure.ItemID)
								return myTabItem.MyStepTabPanel;
					}
				}
			}
			return null;
		}
		/// 
		/// Save the current EditItem if it is in Edit mode
		/// 
		/// ProcedureInfo
		public void SaveCurrentEditItem(ProcedureInfo pi)
		{
			DisplayTabItem dti = GetProcDisplayTabItem(pi);
			if (dti == null) return;
			EditItem ei = dti.MyStepTabPanel.SelectedEditItem;
			if (ei == null) return;
			ei.SaveCurrentAndContents();
		}
		/// 
		/// Save the current EditItem if it is in Edit mode
		/// 
		public void SaveCurrentEditItem()
		{
			foreach (DisplayTabItem dti in _MyDisplayTabItems.Values)
			{
				StepTabPanel stp = dti.MyStepTabPanel;
				if (stp != null)
				{
					EditItem ei = stp.SelectedEditItem;
					if (ei != null)
						ei.SaveCurrentAndContents();
				}
			}
		}
		public DisplayTabItem GetProcDisplayTabItem(ItemInfo myItemInfo)
		{
			ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item
			string key = "Item - " + proc.ItemID.ToString();
			DisplayTabItem pg = null;
			if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it
				return _MyDisplayTabItems[key];
			return null;
		}
		/// 
		/// This opens a Step page based upon a ItemInfo.
		/// 
		/// 
		/// 
		/// 
		private DisplayTabItem OpenStepTabPage(ItemInfo myItemInfo)
		{
			ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item
			string key = "Item - " + proc.ItemID.ToString();
			DisplayTabItem pg = null;
			if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it
			{
				pg = _MyDisplayTabItems[key];
				pg.Selected = true;
				if (SelectedDisplayTabItem != pg) // If the selected page doesn't match
					SelectDisplayTabItem(pg); // Set the selected page
			}
			else // If not already open, create a new Page
			{
				pg = new DisplayTabItem(this.components, this, proc, key); // Open a new Procedure Tab
				_MyDisplayTabItems.Add(key, pg);
				pg.Selected = true;
				SelectDisplayTabItem(pg);
				pg.MyStepTabPanel.MyProcedureItemInfo = proc;
				
				// When more than one procedure is openned, the ribbon control cuts off the bottom of the buttons.
				// This happened to all the procedure tabs after the first one.
				// This is to kludge the logic into sizing the ribbon control properly.
				// This is done by toggling "pg.MyStepTabPanel.MyStepTabRibbon.Expanded"
				// Note that we are doing the NOT of its current setting.  This takes care of when the
				// ribbon bar is minimized and a new procedure tab is created
					pg.MyStepTabPanel.MyStepTabRibbon.Expanded = !pg.MyStepTabPanel.MyStepTabRibbon.Expanded;
					pg.MyStepTabPanel.MyStepTabRibbon.Expanded = !pg.MyStepTabPanel.MyStepTabRibbon.Expanded;
			}
			Application.DoEvents();
			pg.SelectedItemInfo = myItemInfo; // Select the item
			return pg;
		}
		/// 
		/// This opens a Word page based upon an itemInfo.  Since a word document may be a library
		/// document, the related DocID is used for the Word document.
		/// 
		/// 
		/// 
		private DisplayTabItem OpenDSOTabPage(ItemInfo myItemInfo)
		{
			DisplayTabItem pg = null;
			EntryInfo myEntry = myItemInfo.MyContent.MyEntry;
			string key = "Doc - " + myEntry.DocID;
			if (_MyDisplayTabItems.ContainsKey(key)) // If document page  open use it
			{
				pg = _MyDisplayTabItems[key];
				if (pg.MyItemInfo.ItemID != myItemInfo.ItemID)
				{
					string msg = string.Format("{0} is already open", myItemInfo.MyContent.MyEntry.MyDocument.LibTitle);
					MessageBox.Show(msg, "Library Document is Already Open", MessageBoxButtons.OK);
				}
			}
			else
			{
				if (DSOTabPanel.Count >= DSOTabPanel.MSWordLimit) // Limit the number of open document pages to 18
				{
					MessageBox.Show("Too many Word Documents Open.  Please close one of the Documents before attempting to open another");
					return null;
				}
				//if ((myItemInfo.MyContent.MyEntry.MyDocument.LibTitle ?? "") != "")
				//    MessageBox.Show("WARNING: All edits made to this Library Document will be applied to all uses of the Document");
				pg = new DisplayTabItem(this.components, this, myItemInfo, key); // Open a new document page
					_MyDisplayTabItems.Add(key, pg);
			}
			SelectDisplayTabItem(pg);
			pg.MyDSOTabPanel.EnterPanel();
			return pg;
		}
		public DisplayTabItem OpenDSOTabPage(DocumentInfo myDocumentInfo)
		{
			CleanUpClosedItems();
			DisplayTabItem pg = null;
			string key = "Doc - " + myDocumentInfo.DocID;
			if (_MyDisplayTabItems.ContainsKey(key)) // If document page  open use it
				pg = _MyDisplayTabItems[key];
			else
			{
				if (DSOTabPanel.Count > 18) // Limit the number of open document pages to 18
				{
					MessageBox.Show("Too many Word Documents Open.  Please close one of the Documents before attempting to open another");
					return null;
				}
				pg = new DisplayTabItem(this.components, this, myDocumentInfo, key); // Open a new document page
				_MyDisplayTabItems.Add(key, pg);
			}
			SelectDisplayTabItem(pg);
			pg.MyDSOTabPanel.EnterPanel();
			return pg;
		}
		/// 
		/// Clean-up after a page is closed
		/// 
		/// 
		internal void RemoveItem(DisplayTabItem myDisplayTabItem)
		{
			_MyDisplayTabItems.Remove(myDisplayTabItem.MyKey);
			// Dispose the Panel
			if (myDisplayTabItem.MyStepTabPanel != null)
				myDisplayTabItem.MyStepTabPanel.Dispose();
			if (myDisplayTabItem.MyDSOTabPanel != null)
				myDisplayTabItem.MyDSOTabPanel.CloseDSO();
			components.Remove(myDisplayTabItem);
			myDisplayTabItem.Dispose();
		}
		#endregion
	}
}