Index: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs
===================================================================
--- Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs	(revision 1081)
+++ Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs	(revision 1083)
@@ -61,5 +61,4 @@
         {
             CGAppointments newappts = new CGAppointments();
-            //appts.apptList = (Hashtable)apptList.Clone();
             foreach (DictionaryEntry d in this.apptList)
             {
Index: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs
===================================================================
--- Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs	(revision 1081)
+++ Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs	(revision 1083)
@@ -272,7 +272,10 @@
         //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.
+        //XXX: Needs to be refactored obviously, but now for testing.
+        //XXX: Tested extensively enough. Less refactoring now. 2011-01-26
         public void RefreshDocumentAsync()
         {
+            Debug.WriteLine("IN REFERSH DOCUMENT ASYNC\n\n");
+
             bool bRet = false;
             if (m_sResourcesArray.Count == 0)
@@ -423,6 +426,4 @@
                     m_DocManager.ConnectInfo.LoadConnectInfo();
                 }
-
-                m_pAvArray.Clear();
 
                 ArrayList saryApptTypes = new ArrayList();
@@ -464,57 +465,65 @@
                 string sAccessRuleList;
 
-
-                foreach (DataRow rTemp in rAvailabilitySchedule.Rows)
-                {
-                    //get StartTime, EndTime and Slots 
-                    dStart = (DateTime)rTemp["START_TIME"];
-                    dEnd = (DateTime)rTemp["END_TIME"];
-
-                    //TODO: Fix this slots datatype problem
-                    string sSlots = rTemp["SLOTS"].ToString();
-                    nSlots = Convert.ToInt16(sSlots);
-
-                    sResourceList = rTemp["RESOURCE"].ToString();
-                    sAccessRuleList = rTemp["ACCESS_TYPE"].ToString();
-
-                    string sNote = rTemp["NOTE"].ToString();
-
-                    if ((nSlots < -1000) || (sAccessRuleList == ""))
+                //smh: moved clear availabilities down here.
+                //smh: Temporary solution to make sure that people don't touch the availability table at the same time!!!
+                //NOTE: This lock makes sure that availabilities aren't queried for slots when the array is an intermediate
+                //state. The other place that has this lock is SlotsAvailable function.
+                lock (this.m_pAvArray)
+                {
+                    m_pAvArray.Clear();
+
+                    foreach (DataRow rTemp in rAvailabilitySchedule.Rows)
                     {
-                        nApptTypeID = 0;
-                    }
-                    else
-                    {
-                        foreach (DataRow rType in rTypeSchedule.Rows)
+                        //get StartTime, EndTime and Slots 
+                        dStart = (DateTime)rTemp["START_TIME"];
+                        dEnd = (DateTime)rTemp["END_TIME"];
+
+                        //TODO: Fix this slots datatype problem
+                        string sSlots = rTemp["SLOTS"].ToString();
+                        nSlots = Convert.ToInt16(sSlots);
+
+                        sResourceList = rTemp["RESOURCE"].ToString();
+                        sAccessRuleList = rTemp["ACCESS_TYPE"].ToString();
+
+                        string sNote = rTemp["NOTE"].ToString();
+
+                        if ((nSlots < -1000) || (sAccessRuleList == ""))
                         {
-
-                            dTypeStart = (DateTime)rType["StartTime"];
-                            dTypeEnd = (DateTime)rType["EndTime"];
-                            //if start & end times overlap, then
-                            string sTypeResource = rType["ResourceName"].ToString();
-                            if ((dTypeStart.DayOfYear == dStart.DayOfYear) && (sResourceList == sTypeResource))
+                            nApptTypeID = 0;
+                        }
+                        else
+                        {
+                            foreach (DataRow rType in rTypeSchedule.Rows)
                             {
-                                crRectA.Y = GetTotalMinutes(dStart);
-                                crRectA.Height = GetTotalMinutes(dEnd) - crRectA.Top;
-                                crRectB.Y = GetTotalMinutes(dTypeStart);
-                                crRectB.Height = GetTotalMinutes(dTypeEnd) - crRectB.Top;
-                                bIsect = crRectA.IntersectsWith(crRectB);
-                                if (bIsect == true)
+
+                                dTypeStart = (DateTime)rType["StartTime"];
+                                dTypeEnd = (DateTime)rType["EndTime"];
+                                //if start & end times overlap, then
+                                string sTypeResource = rType["ResourceName"].ToString();
+                                if ((dTypeStart.DayOfYear == dStart.DayOfYear) && (sResourceList == sTypeResource))
                                 {
-                                    //TODO: This code:
-                                    //	nApptTypeID = (int) rType["AppointmentTypeID"];
-                                    //Causes this exception:
-                                    //Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
-                                    string sTemp = rType["AppointmentTypeID"].ToString();
-                                    nApptTypeID = Convert.ToInt16(sTemp);
-                                    break;
+                                    crRectA.Y = GetTotalMinutes(dStart);
+                                    crRectA.Height = GetTotalMinutes(dEnd) - crRectA.Top;
+                                    crRectB.Y = GetTotalMinutes(dTypeStart);
+                                    crRectB.Height = GetTotalMinutes(dTypeEnd) - crRectB.Top;
+                                    bIsect = crRectA.IntersectsWith(crRectB);
+                                    if (bIsect == true)
+                                    {
+                                        //TODO: This code:
+                                        //	nApptTypeID = (int) rType["AppointmentTypeID"];
+                                        //Causes this exception:
+                                        //Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
+                                        string sTemp = rType["AppointmentTypeID"].ToString();
+                                        nApptTypeID = Convert.ToInt16(sTemp);
+                                        break;
+                                    }
                                 }
-                            }
-                        }//end foreach datarow rType
-                    }
-
-                    AddAvailability(dStart, dEnd, nApptTypeID, nSlots, false, sResourceList, sAccessRuleList, sNote);
-                }//end foreach datarow rTemp
-
+                            }//end foreach datarow rType
+                        }
+
+
+                        AddAvailability(dStart, dEnd, nApptTypeID, nSlots, false, sResourceList, sAccessRuleList, sNote);
+                    }//end foreach datarow rTemp
+                }//end lock
                 return true;
             }
@@ -531,4 +540,16 @@
         }
 
+        /// <summary>
+        /// Adds Availability to Availability Array held by document
+        /// </summary>
+        /// <param name="StartTime">Self-Explan</param>
+        /// <param name="EndTime">Self-Explan</param>
+        /// <param name="nType"></param>
+        /// <param name="nSlots"></param>
+        /// <param name="UpdateView"></param>
+        /// <param name="sResourceList"></param>
+        /// <param name="sAccessRuleList"></param>
+        /// <param name="sNote"></param>
+        /// <returns></returns>
         public int AddAvailability(DateTime StartTime, DateTime EndTime, int nType, int nSlots, bool UpdateView, string sResourceList, string sAccessRuleList, string sNote)
         {
@@ -579,11 +600,4 @@
             //TODO:  Test that resource is not currently in list, that it IS a resource, etc
             this.m_sResourcesArray.Add(sResource);
-            //SAM: removing: Remove UpdateAllViews: Redraws all the open views. But does not call server.
-            //this.UpdateAllViews();
-        }
-
-        public void ClearResources()
-        {
-            this.m_sResourcesArray.Clear();
         }
 
@@ -604,37 +618,51 @@
             crRectB.Height = GetTotalMinutes(dSelEnd) - crRectB.Y;
 
-            //			//loop thru m_pAvArray
-            //			//Compare the start time and end time of eachblock
-            while (i < m_pAvArray.Count)
-            {
-                pAv = (CGAvailability)m_pAvArray[i];
-                dStart = pAv.StartTime;
-                dEnd = pAv.EndTime;
-                if ((sResource == pAv.ResourceList) &&
-                    ((dSelStart.Date == dStart.Date) || (dSelStart.Date == dEnd.Date)))
-                {
-                    crRectA.Y = (dStart.Date < dSelStart.Date) ? 0 : GetTotalMinutes(dStart);
-                    crRectA.Height = (dEnd.Date > dSelEnd.Date) ? 1440 : GetTotalMinutes(dEnd);
-                    crRectA.Height = crRectA.Height - crRectA.Y;
-                    bIsect = crRectA.IntersectsWith(crRectB);
-                    if (bIsect != false)
+            //NOTE: What's this lock? This lock makes sure that nobody is editing the availability array
+            //when we are looking at it. Since the availability array could potentially be updated on
+            //a different thread, we are can be potentially left stuck with an empty array.
+            //
+            //The other place that uses this lock is the RefershAvailabilitySchedule method
+            //
+            //This is a temporary fix until I figure out how to divorce the availbilities here from those drawn
+            //on the calendar. Appointments are cloned b/c they are in an object that supports that; and b/c I
+            //don't need to suddenly query them at runtime like I do with Availabilities.
+
+            lock (this.m_pAvArray)
+            {
+                //loop thru m_pAvArray
+                //Compare the start time and end time of eachblock
+                while (i < m_pAvArray.Count)
+                {
+                    pAv = (CGAvailability)m_pAvArray[i];
+                    dStart = pAv.StartTime;
+                    dEnd = pAv.EndTime;
+                    if ((sResource == pAv.ResourceList) &&
+                        ((dSelStart.Date == dStart.Date) || (dSelStart.Date == dEnd.Date)))
                     {
-                        nSlots = pAv.Slots;
-                        if (nSlots < 1)
+                        crRectA.Y = (dStart.Date < dSelStart.Date) ? 0 : GetTotalMinutes(dStart);
+                        crRectA.Height = (dEnd.Date > dSelEnd.Date) ? 1440 : GetTotalMinutes(dEnd);
+                        crRectA.Height = crRectA.Height - crRectA.Y;
+                        bIsect = crRectA.IntersectsWith(crRectB);
+                        if (bIsect != false)
                         {
-                            nAvailableSlots = 0;
-                            break;
-                        }
-                        if (nSlots < nAvailableSlots)
-                        {
-                            nAvailableSlots = nSlots;
-                            sAccessType = pAv.AccessTypeName;
-                            sAvailabilityMessage = pAv.Note;
-
-                        }
-                    }
-                }
-                i++;
-            }
+                            nSlots = pAv.Slots;
+                            if (nSlots < 1)
+                            {
+                                nAvailableSlots = 0;
+                                break;
+                            }
+                            if (nSlots < nAvailableSlots)
+                            {
+                                nAvailableSlots = nSlots;
+                                sAccessType = pAv.AccessTypeName;
+                                sAvailabilityMessage = pAv.Note;
+
+                            }
+                        }//end if
+                    }//end if
+                    i++;
+                }//end while
+            }//end lock
+
             if (nAvailableSlots == 999)
             {
@@ -759,4 +787,5 @@
             aCopy.HealthRecordNumber = rApptInfo.HealthRecordNumber;
             aCopy.AccessTypeID = rApptInfo.AccessTypeID;
+            aCopy.WalkIn = bWalkin ? true : false;
 
             string sSql = "BSDX ADD NEW APPOINTMENT^" + sStart + "^" + sEnd + "^" + sPatID + "^" + sResource + "^" + sLen + "^" + sNote + "^" + sApptID;
@@ -773,8 +802,12 @@
             aCopy.AppointmentKey = nApptID;
             this.m_appointments.AddAppointment(aCopy);
-
-            bool bRet = RefreshAvailabilitySchedule();
-
-            UpdateAllViews();
+            
+            
+            //Have make appointment from CGView responsible for requesting an update for the avialability.
+            //bool bRet = RefreshAvailabilitySchedule();
+
+            //Sam: don't think this is needed as it is called from CGView.
+            //Make CGView responsible for all drawing.
+            //UpdateAllViews();
 
             return nApptID;
@@ -822,9 +855,5 @@
             string sErrorID = r["ERRORID"].ToString();
 
-            if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
-            {
-                bool bRet = RefreshSchedule();
-                UpdateAllViews();
-            }
+
         }
 
Index: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs
===================================================================
--- Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs	(revision 1081)
+++ Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs	(revision 1083)
@@ -1182,7 +1182,4 @@
             DataTable dtOut;
 
-#if TRACE
-            DateTime sendTime = DateTime.Now;
-#endif
 			try
 			{
@@ -1198,10 +1195,4 @@
 				throw ex;
 			}
-
-#if TRACE
-            DateTime receiveTime = DateTime.Now;
-            TimeSpan executionTime = receiveTime - sendTime;
-            Debug.Write("CGDocumentManager::RPMSDataTable Execution Time: " + executionTime.Milliseconds + " ms.\n");
-#endif
 
             return dtOut;
Index: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs
===================================================================
--- Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs	(revision 1081)
+++ Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs	(revision 1083)
@@ -617,5 +617,5 @@
             this.tvSchedules.Location = new System.Drawing.Point(0, 0);
             this.tvSchedules.Name = "tvSchedules";
-            this.tvSchedules.Size = new System.Drawing.Size(128, 332);
+            this.tvSchedules.Size = new System.Drawing.Size(128, 290);
             this.tvSchedules.Sorted = true;
             this.tvSchedules.TabIndex = 1;
@@ -664,5 +664,5 @@
             this.panelRight.Location = new System.Drawing.Point(941, 0);
             this.panelRight.Name = "panelRight";
-            this.panelRight.Size = new System.Drawing.Size(128, 332);
+            this.panelRight.Size = new System.Drawing.Size(128, 290);
             this.panelRight.TabIndex = 3;
             this.panelRight.Visible = false;
@@ -762,5 +762,5 @@
             this.panelCenter.Location = new System.Drawing.Point(136, 24);
             this.panelCenter.Name = "panelCenter";
-            this.panelCenter.Size = new System.Drawing.Size(802, 284);
+            this.panelCenter.Size = new System.Drawing.Size(802, 242);
             this.panelCenter.TabIndex = 7;
             // 
@@ -848,5 +848,5 @@
             this.panelBottom.Controls.Add(this.statusBar1);
             this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
-            this.panelBottom.Location = new System.Drawing.Point(136, 308);
+            this.panelBottom.Location = new System.Drawing.Point(136, 266);
             this.panelBottom.Name = "panelBottom";
             this.panelBottom.Size = new System.Drawing.Size(802, 24);
@@ -866,5 +866,5 @@
             this.splitter1.Location = new System.Drawing.Point(128, 24);
             this.splitter1.Name = "splitter1";
-            this.splitter1.Size = new System.Drawing.Size(8, 308);
+            this.splitter1.Size = new System.Drawing.Size(8, 266);
             this.splitter1.TabIndex = 9;
             this.splitter1.TabStop = false;
@@ -875,5 +875,5 @@
             this.splitter2.Location = new System.Drawing.Point(938, 24);
             this.splitter2.Name = "splitter2";
-            this.splitter2.Size = new System.Drawing.Size(3, 308);
+            this.splitter2.Size = new System.Drawing.Size(3, 266);
             this.splitter2.TabIndex = 10;
             this.splitter2.TabStop = false;
@@ -903,5 +903,5 @@
             this.calendarGrid1.Resources = ((System.Collections.ArrayList)(resources.GetObject("calendarGrid1.Resources")));
             this.calendarGrid1.SelectedAppointment = 0;
-            this.calendarGrid1.Size = new System.Drawing.Size(802, 284);
+            this.calendarGrid1.Size = new System.Drawing.Size(802, 242);
             this.calendarGrid1.StartDate = new System.DateTime(2003, 1, 27, 0, 0, 0, 0);
             this.calendarGrid1.TabIndex = 0;
@@ -916,5 +916,5 @@
             // 
             this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
-            this.ClientSize = new System.Drawing.Size(1069, 332);
+            this.ClientSize = new System.Drawing.Size(1069, 290);
             this.Controls.Add(this.panelCenter);
             this.Controls.Add(this.panelBottom);
@@ -1923,6 +1923,7 @@
 			Debug.Assert(nApptID != 0);
 
-			CGAppointment a = (CGAppointment) this.Appointments.AppointmentTable[nApptID];
-
+            //smh
+			//CGAppointment a = (CGAppointment) this.Appointments.AppointmentTable[nApptID];
+            CGAppointment a = (CGAppointment)this.Document.Appointments.AppointmentTable[nApptID];
 			try
 			{
@@ -1980,5 +1981,10 @@
 				DateTime dtCheckIn = dlgCheckin.CheckInTime;
 
-				this.Document.CheckInAppointment(nApptID, dtCheckIn);
+				//Save to Database
+                this.Document.CheckInAppointment(nApptID, dtCheckIn);
+
+                //Tell appointment that it is checked in--smh cancel that!
+                //a.CheckInTime = DateTime.Now;
+
                 //smh new code
                 if (dlgCheckin.PrintRouteSlip)
@@ -1986,4 +1992,5 @@
                 // end new code
 
+                //redraw grid (would this work???)
 				this.calendarGrid1.Invalidate();
 			}
@@ -2034,5 +2041,6 @@
 				 * 8-10-05 Added overbook prompt for walkin
 				*/
-				this.Document.RefreshDocument();
+                //SMH: Takes too long to do.
+				//this.Document.RefreshDocument();
 				string sAccessType = "";
 				string sAvailabilityMessage = "";
@@ -2067,5 +2075,6 @@
 				appt.HealthRecordNumber = dPat.HealthRecordNumber;
 
-				this.Document.RefreshDocument();
+                //smh: Takes too long
+				//this.Document.RefreshDocument();
 
 				//Call Document to add a walkin appointment
@@ -2074,23 +2083,37 @@
 				//Now check them in.
 				calendarGrid1.SelectedAppointment = nApptID;
-
 				AppointmentCheckIn();
 
-				try
-				{
-					RaiseRPMSEvent("BSDX SCHEDULE" , m_Document.DocName);
-				}
-				catch (Exception ex)
-				{
-					Debug.Write(ex.Message);
-				}
+                //Show the new set of appointments by calling UpdateArrays. Fetches Document's CGAppointments
+                this.UpdateArrays();
+
+                //Get the appointments and availabilities, async, from Server. Callback updates this thread's controls.
+                OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
+                ousd.BeginInvoke(OnUpdateScheduleCallback, null);
+
+
+			}
+			catch (Exception ex)
+			{
+                string msg;
+                if (BMXNetLib.Piece(ex.Message, "~", 1) == "-10") // -10 means that BSDXAPI reported an error.
+                    msg = BMXNetLib.Piece(ex.Message, "~", 4);
+                else
+                    msg = ex.Message;
+
+                MessageBox.Show("VISTA says: \r\n" + msg, "Unable to Make Walk-in Appointment");
+                return;
+			}
+
+            try
+            {
+                RaiseRPMSEvent("BSDX SCHEDULE", m_Document.DocName);
+            }
+            catch (Exception ex)
+            {
+                Debug.Write(ex.Message);
+            }
 			
-			}
-			catch (Exception ex)
-			{
-				MessageBox.Show("Unable to add walk-in appointment  " +  ex.Message, "Clinical Scheduling");
-				return;
-
-			}
+
 		}
 
@@ -2133,5 +2156,7 @@
 				Debug.Assert(nDuration > 0);
 
-				this.Document.RefreshDocument();
+
+                //Sam: takes too long. Remove this call; deal with the issue of concurrent appointments another way.
+                //this.Document.RefreshDocument();
 				string sAccessType = "";
 				string sAvailabilityMessage = "";
@@ -2180,15 +2205,26 @@
 				appt.AccessTypeID = nAccessTypeID;
 
-				//Call Document to add a new appointment
+				//Call Document to add a new appointment. Document adds appointment to CGAppointments array.
 				this.Document.CreateAppointment(appt);
-                this.Document.RefreshDocument();
-
+
+                //Show the new set of appointments by calling UpdateArrays. Fetches Document's CGAppointments
+                this.UpdateArrays();
+                
+                //Get the appointments and availabilities, async, from Server. Callback updates this thread's controls.
+                OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
+                ousd.BeginInvoke(OnUpdateScheduleCallback, null);
 			}
 			catch (Exception ex)
-			{
-				MessageBox.Show("Unable to add new appointment  " +  ex.Message, "Clinical Scheduling");
+			{   
+                string msg;
+                if (BMXNetLib.Piece(ex.Message, "~", 1) == "-10") // -10 means that BSDXAPI reported an error.
+                    msg = BMXNetLib.Piece(ex.Message, "~", 4);
+                else
+                    msg = ex.Message;
+
+				MessageBox.Show("VISTA says: \r\n" + msg, "Unable to Make Appointment");
 				return;
-
-			}
+			}
+
 			try
 			{
@@ -2320,10 +2356,16 @@
 			Debug.Assert(this.InvokeRequired == false,"CGView.UpdateArrays InvokeRequired");
             // This is where you set how the grid will look
+
+            //Create Deep copy of Availability Array
+            ArrayList availArrayCopy = new ArrayList();
+            foreach (CGAvailability av in this.m_Document.AvailabilityArray)
+                availArrayCopy.Add(av);
+
 			try 
 			{
                 //Tell the grid about Avails, Appts, and Resources.
-                this.calendarGrid1.AvailabilityArray = this.m_Document.AvailabilityArray;
+                this.calendarGrid1.AvailabilityArray = availArrayCopy;
                 //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.Appointments = (CGAppointments)this.m_Document.Appointments.Clone();
 				this.calendarGrid1.Resources = this.m_Document.Resources;
                 //Redraw the calendar grid
@@ -3135,5 +3177,9 @@
 
         
-
+        /// <summary>
+        /// Update Selection of date if user does not pick a date/time
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void dateTimePicker1_Leave(object sender, EventArgs e)
         {
@@ -3142,4 +3188,9 @@
         }
 
+        /// <summary>
+        /// Handle Selection of Date via mouse from datetimepicker dropdown
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void dateTimePicker1_CloseUp(object sender, EventArgs e)
         {
@@ -3148,4 +3199,9 @@
         }
 
+        /// <summary>
+        /// Handle Enter and Escape key on dateTimePicker
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void dateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
         {
Index: Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs
===================================================================
--- Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs	(revision 1081)
+++ Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs	(revision 1083)
@@ -1028,4 +1028,7 @@
         }
 
+        /// <summary>
+        /// Draws Availabilities. Draws Some of the Empty cells (don't know where the rest go) with the Khaki color
+        /// </summary>
         private void SetAppointmentTypes()
         {
