Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs	(revision 1073)
@@ -8,5 +8,5 @@
     /// </summary>
     [Serializable]
-    public class CGAppointments : IEnumerable
+    public class CGAppointments : IEnumerable, ICloneable
     {
         private Hashtable apptList = new Hashtable();
@@ -56,4 +56,14 @@
             }
         }
+
+        //smh test
+        //one problem: Hashtable is a shallow copy.
+        //so it shouldn't work. But let's see.
+        public object Clone()
+        {
+            CGAppointments appts = new CGAppointments();
+            appts.apptList = (Hashtable)apptList.Clone();
+            return appts;
+        }
     }
 }
Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs	(revision 1073)
@@ -270,6 +270,8 @@
         }
 
-
-        public void RefreshDocument()
+        //sam: This is a test that duplicates RefreshDocument, but without the UpdateAllViews,
+        // as that has to be done synchornously.
+        //XXXXXX: Needs to be refactored obviously, but now for testing.
+        public void RefreshDocumentAsync()
         {
             bool bRet = false;
@@ -290,4 +292,27 @@
 
             bRet = RefreshSchedule();
+        }
+
+        
+        public void RefreshDocument()
+        {
+            bool bRet = false;
+            if (m_sResourcesArray.Count == 0)
+                return;
+            if (m_sResourcesArray.Count == 1)
+            {
+                bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate);
+            }
+            else
+            {
+                this.m_dStartDate = m_dSelectedDate;
+                this.m_dEndDate = m_dSelectedDate;
+                this.m_dEndDate = this.m_dEndDate.AddHours(23);
+                this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
+                this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
+            }
+
+            bRet = RefreshSchedule();
+            
             this.UpdateAllViews();
         }
@@ -344,5 +369,4 @@
                         this.DocManager,
                         m_dStartDate,
-                        this.Appointments,
                         this.DocName);
 
Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs	(revision 1073)
@@ -207,5 +207,5 @@
             //A view is a specific arrangement of appointments and availabilites that constitute a document
             CGView view = new CGView();
-            view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
+            view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
 
             //Handle BMX Event
@@ -1068,5 +1068,5 @@
 
                 CGView view = new CGView();
-                view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
+                view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
 
                 view.Show();
@@ -1117,5 +1117,5 @@
 
                 CGView view = new CGView();
-                view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
+                view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
 
                 view.Show();
Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs	(revision 1073)
@@ -8,5 +8,5 @@
 using System.Threading;
 using IndianHealthService.BMXNet;
-
+using System.Runtime.InteropServices;
 
 namespace IndianHealthService.ClinicalScheduling
@@ -128,5 +128,4 @@
 			CGDocumentManager docMgr,
 			DateTime dStartDate,
-			CGAppointments cgAppts,
 			string sText)
 		{
@@ -135,6 +134,12 @@
 			this.StartDate = dStartDate;
 			this.Document = doc;
-			this.Appointments = cgAppts;
-			
+            
+            //Rather strangely, this line is needed for God knows Why...
+            //Without it, the Grid tries to draw appointments, but can't.
+            //Making a constructor in the Calendar Grid itself didn't work. Don't know why.
+            //XXX: For later investigation.
+            this.Appointments = new CGAppointments();
+            
+
             // Set username and division up top
             this.Text = this.DocManager.ConnectInfo.UserName;
@@ -150,44 +155,5 @@
 
 		private BMXNetConnectInfo.BMXNetEventDelegate m_bmxDelegate;
-		delegate void OnUpdateScheduleDelegate();
-
-		private void BMXNetEventHandler(Object obj, BMXNet.BMXNetEventArgs e)
-		{
-			try
-			{
-				if (e.BMXEvent == "BMXNet AutoFire")
-				{
-					Debug.Write("CGView caught AutoFire event.\n");
-					if (this == null)
-						return;
-					OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
-					this.BeginInvoke(ousd);
-					return;
-				}
-
-				if (e.BMXEvent != "BSDX SCHEDULE")
-				{
-					return;
-				}
-				string sResourceName;
-				for (int j=0; j < m_Document.m_sResourcesArray.Count; j++)
-				{
-					sResourceName = m_Document.m_sResourcesArray[j].ToString();
-					if (e.BMXParam == sResourceName)
-					{
-						OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
-						if (this == null)
-							return;
-						this.BeginInvoke(ousd);
-						Debug.Write("CGView caught BSDX SCHEDULE event.\n");
-						break;
-					}
-				}
-			}
-			catch (Exception ex)
-			{
-				Debug.Write(ex.Message);
-			}
-        }
+		
 
         #endregion initialization
@@ -651,5 +617,5 @@
             this.tvSchedules.Location = new System.Drawing.Point(0, 0);
             this.tvSchedules.Name = "tvSchedules";
-            this.tvSchedules.Size = new System.Drawing.Size(128, 437);
+            this.tvSchedules.Size = new System.Drawing.Size(128, 395);
             this.tvSchedules.Sorted = true;
             this.tvSchedules.TabIndex = 1;
@@ -698,5 +664,5 @@
             this.panelRight.Location = new System.Drawing.Point(941, 0);
             this.panelRight.Name = "panelRight";
-            this.panelRight.Size = new System.Drawing.Size(128, 437);
+            this.panelRight.Size = new System.Drawing.Size(128, 395);
             this.panelRight.TabIndex = 3;
             this.panelRight.Visible = false;
@@ -796,5 +762,5 @@
             this.panelCenter.Location = new System.Drawing.Point(136, 24);
             this.panelCenter.Name = "panelCenter";
-            this.panelCenter.Size = new System.Drawing.Size(802, 389);
+            this.panelCenter.Size = new System.Drawing.Size(802, 347);
             this.panelCenter.TabIndex = 7;
             // 
@@ -818,5 +784,5 @@
             this.calendarGrid1.Resources = ((System.Collections.ArrayList)(resources.GetObject("calendarGrid1.Resources")));
             this.calendarGrid1.SelectedAppointment = 0;
-            this.calendarGrid1.Size = new System.Drawing.Size(802, 389);
+            this.calendarGrid1.Size = new System.Drawing.Size(802, 347);
             this.calendarGrid1.StartDate = new System.DateTime(2003, 1, 27, 0, 0, 0, 0);
             this.calendarGrid1.TabIndex = 0;
@@ -826,4 +792,5 @@
             this.calendarGrid1.CGSelectionChanged += new IndianHealthService.ClinicalScheduling.CalendarGrid.CGSelectionChangedHandler(this.calendarGrid1_CGSelectionChanged);
             this.calendarGrid1.DoubleClick += new System.EventHandler(this.calendarGrid1_DoubleClick);
+            this.calendarGrid1.MouseEnter += new System.EventHandler(this.calendarGrid1_MouseEnter);
             // 
             // ctxCalendarGrid
@@ -910,5 +877,5 @@
             this.panelBottom.Controls.Add(this.statusBar1);
             this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
-            this.panelBottom.Location = new System.Drawing.Point(136, 413);
+            this.panelBottom.Location = new System.Drawing.Point(136, 371);
             this.panelBottom.Name = "panelBottom";
             this.panelBottom.Size = new System.Drawing.Size(802, 24);
@@ -928,5 +895,5 @@
             this.splitter1.Location = new System.Drawing.Point(128, 24);
             this.splitter1.Name = "splitter1";
-            this.splitter1.Size = new System.Drawing.Size(8, 413);
+            this.splitter1.Size = new System.Drawing.Size(8, 371);
             this.splitter1.TabIndex = 9;
             this.splitter1.TabStop = false;
@@ -937,5 +904,5 @@
             this.splitter2.Location = new System.Drawing.Point(938, 24);
             this.splitter2.Name = "splitter2";
-            this.splitter2.Size = new System.Drawing.Size(3, 413);
+            this.splitter2.Size = new System.Drawing.Size(3, 371);
             this.splitter2.TabIndex = 10;
             this.splitter2.TabStop = false;
@@ -949,5 +916,5 @@
             // 
             this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
-            this.ClientSize = new System.Drawing.Size(1069, 437);
+            this.ClientSize = new System.Drawing.Size(1069, 395);
             this.Controls.Add(this.panelCenter);
             this.Controls.Add(this.panelBottom);
@@ -1060,4 +1027,5 @@
 
 		#endregion
+
 
 		#region AppointmentMenu Handlers
@@ -1512,5 +1480,11 @@
 			}
 
-			//If this Document has no resources then use it (happens when the GUI has nothing open, typically after log-in)
+            //So if it is not a view that's already open, it means we have to grab the data for
+            //So we tell the user to wait wait wait
+            this.Cursor = Cursors.WaitCursor;
+            this.LoadSplash();  //Open "Loading" splash
+            
+            
+            //If this Document has no resources then use it (happens when the GUI has nothing open, typically after log-in)
 			//Else, create a new document
             CGDocument doc;
@@ -1548,5 +1522,5 @@
 			v =this.DocManager.GetViewByResource(sSelectedTreeResourceArray);
 			
-            //Position the Grid
+            //Position the Grid to start at a certain day.
             //XXX: This must be a better way to do this.
             v.dateTimePicker1.Value = dDate;
@@ -1628,4 +1602,8 @@
 			v.calendarGrid1.SetOverlapTable();
 			v.calendarGrid1.Refresh();
+
+            // Set cursor back and stop splash screen
+            this.Cursor = Cursors.Default;
+            StopSplash();
 		}
 
@@ -2224,10 +2202,76 @@
 		}
 
+        #region BMX Event Processing and Callbacks
+        /// <summary>
+        /// Loosely typed delegate used several times below.
+        /// </summary>
+        delegate void OnUpdateScheduleDelegate();
+        
+        /// <summary>
+        /// Subscription point for each CGView to process BMX events polled from the server
+        /// </summary>
+        /// <param name="obj">Not used</param>
+        /// <param name="e">BMXEvent Args: 
+        /// e.BMXEvent is free text for Event Type; e.BMXParam is free text for Event Arguments</param>
+        private void BMXNetEventHandler(Object obj, BMXNet.BMXNetEventArgs e)
+        {
+            try
+            {
+                // if this class is undefined (e.g. if the user just closed the form, do nothing
+                if (this == null) return;
+
+                // if event is Autofire event
+                if (e.BMXEvent == "BMXNet AutoFire")
+                {
+                    Debug.Write("CGView caught AutoFire event.\n");
+                   
+                    //Create a delegate to OnUpdateSchedule and call Async
+                    //Once Async Call is done, go to OnUpdateScheduleCallback
+                    OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
+                    ousd.BeginInvoke(OnUpdateScheduleCallback, null);
+
+                    return;
+                }
+
+                // if event is BSDX SCHEDULE
+                else if (e.BMXEvent == "BSDX SCHEDULE")
+                {
+                    //See if any of the resources in the event argument matches BSDX Schedule.
+                    //If yes, fire off the delegate
+                    string sResourceName;
+                    for (int j = 0; j < m_Document.m_sResourcesArray.Count; j++)
+                    {
+                        sResourceName = m_Document.m_sResourcesArray[j].ToString();
+                        if (e.BMXParam == sResourceName)
+                        {
+                            Debug.Write("CGView caught BSDX SCHEDULE event.\n");
+
+                            //Create a delegate to OnUpdateSchedule and call Async
+                            //Once Async Call is done, go to OnUpdateScheduleCallb
+                            OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
+                            ousd.BeginInvoke(OnUpdateScheduleCallback, null);
+                            
+                            break;
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.Write(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// Update Appointments and Availabilites using Document.RefreshDocumentAsync on a different thread
+        /// </summary>
+        /// <remarks>
+        /// This method is expected to be called asynchornously.
+        /// </remarks>
 		public void OnUpdateSchedule()
 		{
 			try
 			{
-				this.Cursor = Cursors.WaitCursor;
-				m_Document.RefreshDocument();
+				m_Document.RefreshDocumentAsync(); //new
 			}
 			catch (Exception ex)
@@ -2235,9 +2279,36 @@
 				MessageBox.Show("Unable to refresh document " +  ex.Message, "Clinical Scheduling");
 			}
-			finally
-			{
-				this.Cursor = Cursors.Default;
-			}
-		}
+		}
+
+        /// <summary>
+        /// Callback for when OnUpdateSchedule is done. Triggers the Grid to redraw itself by calling UpdateArrays.
+        /// </summary>
+        /// <param name="itfAR">not used</param>
+        /// <remarks>Calls UpdateArrays via this.Invoke to make sure that the grid is redrawn on the UI thread</remarks>
+        private void OnUpdateScheduleCallback(IAsyncResult itfAR)
+        {
+            OnUpdateScheduleDelegate d = new OnUpdateScheduleDelegate(UpdateArrays);
+            this.Invoke(d);
+        }
+
+        /// <summary>
+        /// Create a new event in RPMS. Wrapper around BMXConnectInfo.RaiseEvent
+        /// </summary>
+        /// <param name="sEvent">Name of Event to Raise</param>
+        /// <param name="sParams">Parameter of Event to Raise</param>
+        public void RaiseRPMSEvent(string sEvent, string sParams)
+        {
+            try
+            {
+                //Signal RPMS to raise an event
+                m_ConnectInfo.RaiseEvent(sEvent, sParams, true);
+            }
+            catch (Exception ex)
+            {
+                Debug.Write(ex.Message);
+            }
+        }
+
+        #endregion
 
         /// <summary>
@@ -2251,8 +2322,10 @@
 			try 
 			{
-				this.calendarGrid1.AvailabilityArray = this.m_Document.AvailabilityArray;
+                //Tell the grid about Avails, Appts, and Resources.
+                this.calendarGrid1.AvailabilityArray = this.m_Document.AvailabilityArray;
+                //Appts are cloned b/c if we tie into  the class directly, we shoot off errors when we manipulate it.
+                this.calendarGrid1.Appointments = (CGAppointments)this.m_Document.Appointments.Clone(); //smh new line again
 				this.calendarGrid1.Resources = this.m_Document.Resources;
-                // this.calendarGrid1.Columns = 7; //test
-                // this.calendarGrid1.StartDate = DateTime.Parse("10-10-2007"); // another test
+                //Redraw the calendar grid
 				this.calendarGrid1.OnUpdateArrays(); // this draws the Calendar
 				this.lblResource.Text = this.m_Document.DocName;
@@ -2262,17 +2335,4 @@
 			{
 				MessageBox.Show("Unable to update arrays " +  ex.Message, "Clinical Scheduling");
-			}
-		}
-
-		public void RaiseRPMSEvent(string sEvent, string sParams)
-		{
-			try
-			{
-				//Signal RPMS to raise an event
-				m_ConnectInfo.RaiseEvent(sEvent, sParams, true);
-			}
-			catch (Exception ex)
-			{
-				Debug.Write(ex.Message);
 			}
 		}
@@ -2372,5 +2432,23 @@
 		#region Events
 
-		private void CGView_Load(object sender, System.EventArgs e)
+        /// <summary>
+        /// Special import to get the GetActiveWindow method from Win32
+        /// </summary>
+        /// <returns>Windows Handle number for Foregreound Active Window</returns>
+        [DllImport("user32.dll")]
+        static extern IntPtr GetActiveWindow();
+
+        /// <summary>
+        /// If a mouse enters the grid, check if the grid is on the active form first before stealing the focus
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void calendarGrid1_MouseEnter(object sender, EventArgs e)
+        {
+            if (GetActiveWindow() == this.Handle)
+                calendarGrid1.Focus();
+        }
+        
+        private void CGView_Load(object sender, System.EventArgs e)
 		{
 			Debug.Assert (this.Document != null);
@@ -3163,4 +3241,7 @@
         }
 
+        
+
+
     }//End class
 }
Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs	(revision 1073)
@@ -71,4 +71,5 @@
             this.m_selectedRange = new CGRange();
             this.m_SelectedAppointments = new CGAppointments();
+            //this.m_Appointments = new CGAppointments();
             this.m_dtStart = new DateTime(2003, 1, 27);
             this.m_ApptOverlapTable = new Hashtable();
@@ -89,10 +90,4 @@
             this.m_sfHour.Alignment = StringAlignment.Far;
             this.m_bInitialUpdate = false;
-            this.MouseEnter += new EventHandler(CalendarGrid_MouseEnter);
-        }
-
-        void CalendarGrid_MouseEnter(object sender, EventArgs e)
-        {
-            this.Focus();
         }
 
Index: /Scheduling/trunk/cs/bsdx0200GUISourceCode/LoadingSplash.Designer.cs
===================================================================
--- /Scheduling/trunk/cs/bsdx0200GUISourceCode/LoadingSplash.Designer.cs	(revision 1072)
+++ /Scheduling/trunk/cs/bsdx0200GUISourceCode/LoadingSplash.Designer.cs	(revision 1073)
@@ -39,5 +39,5 @@
             this.lblLoading.AutoSize = true;
             this.lblLoading.Font = new System.Drawing.Font("Tahoma", 48F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-            this.lblLoading.Location = new System.Drawing.Point(228, 181);
+            this.lblLoading.Location = new System.Drawing.Point(138, 108);
             this.lblLoading.Name = "lblLoading";
             this.lblLoading.Size = new System.Drawing.Size(255, 77);
@@ -51,10 +51,9 @@
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.BackColor = System.Drawing.SystemColors.ControlLightLight;
-            this.ClientSize = new System.Drawing.Size(722, 449);
+            this.ClientSize = new System.Drawing.Size(537, 315);
             this.Controls.Add(this.lblLoading);
             this.ForeColor = System.Drawing.SystemColors.ControlLight;
             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
             this.Name = "LoadingSplash";
-            this.Opacity = 0.8D;
             this.ShowIcon = false;
             this.ShowInTaskbar = false;
