Esempio n. 1
0
		///<summary>Used by parent form when a dialog needs to be displayed on the mouse down.</summary>
		public void MouseUpForced() {
			if(pinBoard.SelectedIndex!=-1) {
				CancelPinMouseDown=true;
			}
			if(!mouseIsDown) {
				return;
			}
			mouseIsDown=false;
			if(TempApptSingle!=null) {
				TempApptSingle.Dispose();
				TempApptSingle=null;
			}
		}
Esempio n. 2
0
		private void PrintApptSchedule(object sender,System.Drawing.Printing.PrintPageEventArgs e) {
			//Logic needs to be added here for calculating if printing will fit on the page. Then call drawing in a loop for number of required pages. 
			Rectangle pageBounds=e.PageBounds;
			int headerOffset=75;
			int footerOffset=40;
			int marginOffset=30;
			//The extra 15 is for the right side of that page.  For some reason the right margin needs a little extra room.
			ApptDrawing.ApptSheetWidth=pageBounds.Width-((marginOffset*2)+15);
			ApptDrawing.ComputeColWidth(apptPrintColsPerPage);
			ApptDrawing.SetLineHeight(apptPrintFontSize);//Measure size the user set to determine the line height for printout.
			int startHour=apptPrintStartTime.Hour;
			int stopHour=apptPrintStopTime.Hour;
			if(stopHour==0) {
				stopHour=24;
			}
			float totalHeight=ApptDrawing.LineH*ApptDrawing.RowsPerHr*(stopHour-startHour);
			//Figure out how many pages are needed to print.
			int pagesAcross=(int)Math.Ceiling((decimal)ApptDrawing.VisOps.Count/(decimal)apptPrintColsPerPage);
			int pagesTall=(int)Math.Ceiling((decimal)totalHeight/(decimal)(pageBounds.Height-(headerOffset+footerOffset)));
			int totalPages=pagesAcross*pagesTall;
			if(ApptDrawing.IsWeeklyView) {
				pagesAcross=1;
				totalPages=1*pagesTall;
			}
			//Decide what page currently on thus knowing what hours to print.
			#region HoursOnPage
			int hoursPerPage=(int)Math.Floor((decimal)(pageBounds.Height-(headerOffset+footerOffset))/(decimal)(ApptDrawing.LineH*ApptDrawing.RowsPerHr));
			int hourBegin=startHour;
			int hourEnd=hourBegin+hoursPerPage;
			if(pageRow>0) {
				hourBegin=startHour+(hoursPerPage*pageRow);
				hourEnd=hourBegin+hoursPerPage;
			}
			if(hourEnd>stopHour) {//Don't show too many hours.
				hourEnd=stopHour;
			}
			ApptDrawing.ApptSheetHeight=ApptDrawing.LineH*ApptDrawing.RowsPerHr*(hourEnd-hourBegin);
			if(hourEnd>23) {//Midnight must be 0.
				hourEnd=0;
			}
			DateTime beginTime=new DateTime(1,1,1,hourBegin,0,0);
			DateTime endTime=new DateTime(1,1,1,hourEnd,0,0);
			#endregion
			e.Graphics.TranslateTransform(marginOffset,headerOffset);//Compensate for header and margin.
			ApptDrawing.DrawAllButAppts(e.Graphics,false,beginTime,endTime,apptPrintColsPerPage,pageColumn,apptPrintFontSize,true);
			//Draw the appointments.
			#region ApptSingleDrawing
			//Clear out the ProvBar from previous page.
			ApptDrawing.ProvBar=new int[ApptDrawing.VisProvs.Count][];
			for(int i=0;i<ApptDrawing.VisProvs.Count;i++) {
				ApptDrawing.ProvBar[i]=new int[24*ApptDrawing.RowsPerHr]; //[144]; or 24*6
			}
			if(ContrApptSingle3!=null) {//I think this is not needed.
				for(int i=0;i<ContrApptSingle3.Length;i++) {
					if(ContrApptSingle3[i]!=null) {
						ContrApptSingle3[i].Dispose();
					}
					ContrApptSingle3[i]=null;
				}
				ContrApptSingle3=null;
			}
			ContrApptSingle3=new ContrApptSingle[DS.Tables["Appointments"].Rows.Count];
			for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) {
				DataRow dataRoww=DS.Tables["Appointments"].Rows[i];
				if(!ApptDrawing.IsWeeklyView) {
					ApptDrawing.ProvBarShading(dataRoww);//Always fill prov bars.
				}
				//Filter the list of appointments here for those those within the time frame.
				if(!ApptSingleDrawing.ApptWithinTimeFrame(dataRoww,beginTime,endTime,apptPrintColsPerPage,pageColumn)) {
					continue;
				}
				ContrApptSingle3[i]=new ContrApptSingle();
				ContrApptSingle3[i].Visible=false;
				ContrApptSingle3[i].DataRoww=dataRoww;
				ContrApptSingle3[i].TableApptFields=DS.Tables["ApptFields"];
				ContrApptSingle3[i].TablePatFields=DS.Tables["PatFields"];
				ContrApptSingle3[i].PatternShowing=ApptSingleDrawing.GetPatternShowing(dataRoww["Pattern"].ToString());
				ContrApptSingle3[i].Size=ApptSingleDrawing.SetSize(dataRoww);
				ContrApptSingle3[i].Location=ApptSingleDrawing.SetLocation(dataRoww,hourBegin,apptPrintColsPerPage,pageColumn);
				e.Graphics.ResetTransform();
				e.Graphics.TranslateTransform(ContrApptSingle3[i].Location.X+marginOffset,ContrApptSingle3[i].Location.Y+headerOffset);
				ApptSingleDrawing.DrawEntireAppt(e.Graphics,dataRoww,ContrApptSingle3[i].PatternShowing,ContrApptSingle3[i].Size.Width,ContrApptSingle3[i].Size.Height,
					false,false,-1,ApptViewItemL.ApptRows,ApptViewItemL.ApptViewCur,DS.Tables["ApptFields"],DS.Tables["PatFields"],apptPrintFontSize,true);
			}
			#endregion
			e.Graphics.ResetTransform();
			//Cover the portions of the appointments that don't belong on the page.
			e.Graphics.FillRectangle(new SolidBrush(Color.White),0,0,pageBounds.Width,headerOffset-1);
			e.Graphics.FillRectangle(new SolidBrush(Color.White),0,ApptDrawing.ApptSheetHeight+headerOffset,pageBounds.Width,totalHeight);
			//Draw the header
			DrawPrintingHeader(e.Graphics,totalPages,pageBounds.Width,pageBounds.Height);
			pagesPrinted++;
			pageColumn++;
			if(totalPages==pagesPrinted) {
				e.HasMorePages=false;
			}
			else {
				e.HasMorePages=true;
				if(pagesPrinted==pagesAcross*(pageRow+1)) {
					pageRow++;
					pageColumn=0;
				}
			}
		}
Esempio n. 3
0
		///<summary>Mouse down event anywhere on the sheet.  Could be a blank space or on an actual appointment.</summary>
		private void ContrApptSheet2_MouseDown(object sender,System.Windows.Forms.MouseEventArgs e) {
			if(infoBubble.Visible) {
				infoBubble.Visible=false;
			}
			if(ApptDrawing.VisOps.Count==0) {//no ops visible.
				return;
			}
			if(mouseIsDown) {//if user clicks right mouse button while dragging
				return;
			}
			//some of this is a little redundant, but still necessary for now.
			SheetClickedonHour=ApptDrawing.YPosToHour(e.Y);
			SheetClickedonMin=ApptDrawing.YPosToMin(e.Y);
			TimeSpan sheetClickedOnTime=new TimeSpan(SheetClickedonHour,SheetClickedonMin,0);
			ContrApptSingle.ClickedAptNum=HitTestAppt(e.Location);
			SheetClickedonOp=ApptDrawing.VisOps[ApptDrawing.XPosToOpIdx(e.X)].OperatoryNum;
			SheetClickedonDay=ApptDrawing.XPosToDay(e.X);
			if(!ApptDrawing.IsWeeklyView) {
				SheetClickedonDay=((int)AppointmentL.DateSelected.DayOfWeek)-1;
			}
			Graphics grfx=ContrApptSheet2.CreateGraphics();
			//if clicked on an appt-----------------------------------------------------------------------------------------------
			if(ContrApptSingle.ClickedAptNum!=0) {
				if(e.Button==MouseButtons.Left) {
					mouseIsDown = true;
				}
				int thisIndex=GetIndex(ContrApptSingle.ClickedAptNum);
				pinBoard.SelectedIndex=-1;
				//ContrApptSingle.PinBoardIsSelected=false;
				if(ContrApptSingle.SelectedAptNum!=-1//unselects previously selected unless it's the same appt
					&& ContrApptSingle.SelectedAptNum!=ContrApptSingle.ClickedAptNum) {
					int prevSel=GetIndex(ContrApptSingle.SelectedAptNum);
					//has to be done before refresh prev:
					ContrApptSingle.SelectedAptNum=ContrApptSingle.ClickedAptNum;
					if(prevSel!=-1) {
						ContrApptSingle3[prevSel].CreateShadow();
						if(ContrApptSingle3[prevSel].Shadow!=null) {
							grfx.DrawImage(ContrApptSingle3[prevSel].Shadow,ContrApptSingle3[prevSel].Location.X
								,ContrApptSingle3[prevSel].Location.Y);
						}
					}
				}
				//again, in case missed in loop above:
				ContrApptSingle.SelectedAptNum=ContrApptSingle.ClickedAptNum;
				ContrApptSingle3[thisIndex].CreateShadow();
				grfx.DrawImage(ContrApptSingle3[thisIndex].Shadow,ContrApptSingle3[thisIndex].Location.X
					,ContrApptSingle3[thisIndex].Location.Y);
				RefreshModuleDataPatient(PIn.Long(ContrApptSingle3[thisIndex].DataRoww["PatNum"].ToString()));
				RefreshModuleScreenPatient();
				OnPatientSelected(PatCur);
				//RefreshModulePatient(PIn.PInt(ContrApptSingle3[thisIndex].DataRoww["PatNum"].ToString()));
				if(e.Button==MouseButtons.Right) {
					//if(ApptDrawing.IsWeeklyView){
					//	menuWeeklyApt.Show(ContrApptSheet2,new Point(e.X,e.Y));
					//}
					//else{
					menuApt.Show(ContrApptSheet2,new Point(e.X,e.Y));
					//}
				}
				else {
					TempApptSingle=new ContrApptSingle();
					TempApptSingle.Visible=false;//otherwise I get a phantom appt while holding mouse down
					TempApptSingle.DataRoww=ContrApptSingle3[thisIndex].DataRoww;
					TempApptSingle.TableApptFields=ContrApptSingle3[thisIndex].TableApptFields;
					TempApptSingle.TablePatFields=ContrApptSingle3[thisIndex].TablePatFields;
					Controls.Add(TempApptSingle);
					TempApptSingle.Location=ApptSingleDrawing.SetLocation(TempApptSingle.DataRoww,0,ApptDrawing.VisOps.Count,0);
					TempApptSingle.Size=ApptSingleDrawing.SetSize(TempApptSingle.DataRoww);
					TempApptSingle.PatternShowing=ApptSingleDrawing.GetPatternShowing(TempApptSingle.DataRoww["Pattern"].ToString());
					TempApptSingle.BringToFront();
					//mouseOrigin is in ApptSheet coordinates
					mouseOrigin=e.Location;
					contOrigin=ContrApptSingle3[thisIndex].Location;
					TempApptSingle.CreateShadow();
					if(HitTestApptBottom(e.Location)) {
						ResizingAppt=true;
						ResizingOrigH=TempApptSingle.Height;
					}
					else {
						ResizingAppt=false;
					}
				}
			}
			//not clicked on appt---------------------------------------------------------------------------------------------------
			else {
				if(e.Button==MouseButtons.Right) {
					int clickedOnBlockCount=0;
					Schedule[] ListForType=Schedules.GetForType(SchedListPeriod,ScheduleType.Blockout,0);
					//List<ScheduleOp> listForSched;
					for(int i=0;i<ListForType.Length;i++) {
						if(ListForType[i].SchedDate.Date!=WeekStartDate.AddDays(SheetClickedonDay).Date) {
							continue;
						}
						if(ListForType[i].StartTime > sheetClickedOnTime
							|| ListForType[i].StopTime <= sheetClickedOnTime) {
							continue;
						}
						//listForSched=ScheduleOps.GetForSched(ListForType[i].ScheduleNum);
						for(int p=0;p<ListForType[i].Ops.Count;p++) {
							if(ListForType[i].Ops[p]==SheetClickedonOp) {
								clickedOnBlockCount++;
								break;//out of ops loop
							}
						}
					}
					if(clickedOnBlockCount>0) {
						menuBlockout.MenuItems[0].Enabled=true;//Edit
						menuBlockout.MenuItems[1].Enabled=true;//Cut
						menuBlockout.MenuItems[2].Enabled=true;//Clone
						menuBlockout.MenuItems[3].Enabled=false;//paste. Can't paste on top of an existing blockout
						menuBlockout.MenuItems[4].Enabled=true;//Delete
						if(clickedOnBlockCount>1) {
						  MsgBox.Show(this,"There are multiple blockouts in this slot.  You should try to delete or move one of them.");
						}
					}
					else {
						menuBlockout.MenuItems[0].Enabled=false;//edit
						menuBlockout.MenuItems[1].Enabled=false;//edit
						menuBlockout.MenuItems[2].Enabled=false;//copy
						if(BlockoutClipboard==null) {
							menuBlockout.MenuItems[3].Enabled=false;//paste
						}
						else {
							menuBlockout.MenuItems[3].Enabled=true;
						}
						menuBlockout.MenuItems[4].Enabled=false;//delete
					}
					menuBlockout.Show(ContrApptSheet2,new Point(e.X,e.Y));
				}
			}
			grfx.Dispose();
			pinBoard.Invalidate();
			//if(PinApptSingle.Visible){
			//	PinApptSingle.CreateShadow();
			//	PinApptSingle.Refresh();
			//}
			CreateAptShadowsOnMain();
		}
Esempio n. 4
0
		///<Summary>Sets selected and prepares for drag.</Summary>
		private void pinBoard_MouseDown(object sender,MouseEventArgs e) {
			if(pinBoard.SelectedIndex==-1) {
				return;
			}
			if(mouseIsDown) {//User right clicked while draging appt around.
				return;
			}
			if(e.Button==MouseButtons.Right) {
				ContextMenu cmen=new ContextMenu();
				MenuItem menuItemProv=new MenuItem(Lan.g(this,"Change Provider"));
				menuItemProv.Click+=new EventHandler(menuItemProv_Click);
				cmen.MenuItems.Add(menuItemProv);
				cmen.Show(pinBoard,e.Location);
				return;
			}
			if(CancelPinMouseDown) {//I'm worried that setting this to false in pinBoard_SelectedIndexChanged is not frequent enough,
				//because a mouse down could happen without the selected index changing.
				//But in that case, a popup would already have happened.
				//Worst case scenario is that user would have to try again.
				CancelPinMouseDown=false;
				return;
			}
			mouseIsDown = true;
			//ContrApptSingle.PinBoardIsSelected=true;
			TempApptSingle=new ContrApptSingle();
			TempApptSingle.DataRoww=pinBoard.SelectedAppt.DataRoww;
			TempApptSingle.TableApptFields=pinBoard.SelectedAppt.TableApptFields;
			TempApptSingle.TablePatFields=pinBoard.SelectedAppt.TablePatFields;
			TempApptSingle.Visible=false;
			Controls.Add(TempApptSingle);
			TempApptSingle.Location=ApptSingleDrawing.SetLocation(TempApptSingle.DataRoww,0,ApptDrawing.VisOps.Count,0);
			TempApptSingle.Size=ApptSingleDrawing.SetSize(TempApptSingle.DataRoww);
			TempApptSingle.PatternShowing=ApptSingleDrawing.GetPatternShowing(TempApptSingle.DataRoww["Pattern"].ToString());
			TempApptSingle.CreateShadow();
			TempApptSingle.BringToFront();
			ContrApptSingle.SelectedAptNum=-1;
			//RefreshModulePatient(PIn.PInt(PinApptSingle.DataRoww["PatNum"].ToString()));//already done
			//PinApptSingle.CreateShadow();
			//PinApptSingle.Refresh();
			CreateAptShadowsOnMain();//to clear previous selection
			ContrApptSheet2.DrawShadow();
			//mouseOrigin is in ContrAppt coordinates (essentially, the entire window)
			mouseOrigin.X=e.X+pinBoard.Location.X+panelCalendar.Location.X;
			//e.X+PinApptSingle.Location.X;
			mouseOrigin.Y=e.Y+pinBoard.SelectedAppt.Location.Y+pinBoard.Location.Y+panelCalendar.Location.Y;
			//e.Y+PinApptSingle.Location.Y;
			contOrigin=new Point(pinBoard.Location.X+panelCalendar.Location.X,
				pinBoard.SelectedAppt.Location.Y+pinBoard.Location.Y+panelCalendar.Location.Y);
			//PinApptSingle.Location;
		}
Esempio n. 5
0
		///<summary>Redraws screen based on data already gathered.  RefreshModuleDataPeriod will have already retrieved the data from the db.</summary>
		public void RefreshModuleScreenPeriod() {
			DateTime startDate;
			DateTime endDate;
			if(ApptDrawing.IsWeeklyView) {
				startDate=WeekStartDate;
				endDate=WeekEndDate;
			}
			else {
				startDate=AppointmentL.DateSelected;
				endDate=AppointmentL.DateSelected;
			}
			if(startDate.Year<1880 || endDate.Year<1880) {
				return;
			}
			Calendar2.SetSelectionRange(startDate,endDate);
			ApptDrawing.ProvBar=new int[ApptDrawing.VisProvs.Count][];
			for(int i=0;i<ApptDrawing.VisProvs.Count;i++) {
				ApptDrawing.ProvBar[i]=new int[24*ApptDrawing.RowsPerHr]; //[144]; or 24*6
			}
			if(ContrApptSingle3!=null) {//I think this is not needed.
				for(int i=0;i<ContrApptSingle3.Length;i++) {
					if(ContrApptSingle3[i]!=null) {
						ContrApptSingle3[i].Dispose();
					}
					ContrApptSingle3[i]=null;
				}
				ContrApptSingle3=null;
			}
			labelDate.Text=startDate.ToString("ddd");
			labelDate2.Text=startDate.ToString("-  MMM d");
			ContrApptSheet2.Controls.Clear();
			ContrApptSingle3=new ContrApptSingle[DS.Tables["Appointments"].Rows.Count];
			DataRow row;
			for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) {
				row=DS.Tables["Appointments"].Rows[i];
				ContrApptSingle3[i]=new ContrApptSingle();
				ContrApptSingle3[i].Visible=false;
				if(ContrApptSingle.SelectedAptNum.ToString()==row["AptNum"].ToString()) {//if this is the selected apt
					//if the selected patient was changed from another module, then deselect the apt.
					if(PatCur==null || PatCur.PatNum.ToString()!=row["PatNum"].ToString()) {
						ContrApptSingle.SelectedAptNum=-1;
					}
				}
				ContrApptSingle3[i].DataRoww=row;
				ContrApptSingle3[i].TableApptFields=DS.Tables["ApptFields"];
				ContrApptSingle3[i].TablePatFields=DS.Tables["PatFields"];
				ContrApptSingle3[i].PatternShowing=ApptSingleDrawing.GetPatternShowing(row["Pattern"].ToString());
				if(!ApptDrawing.IsWeeklyView) {
					ApptDrawing.ProvBarShading(row);
				}
				ContrApptSingle3[i].Location=ApptSingleDrawing.SetLocation(row,0,ApptDrawing.VisOps.Count,0);
				ContrApptSingle3[i].Size=ApptSingleDrawing.SetSize(row);
				ContrApptSheet2.Controls.Add(ContrApptSingle3[i]);
			}//end for
			//PinApptSingle.Refresh();
			pinBoard.Invalidate();
			ApptDrawing.SchedListPeriod=SchedListPeriod;
			ContrApptSheet2.CreateShadow();
			CreateAptShadowsOnMain();
			ContrApptSheet2.DrawShadow();
			List<LabCase> labCaseList=LabCases.GetForPeriod(startDate,endDate);
			FillLab(labCaseList);
			FillProduction();
			FillEmpSched();
			FillWaitingRoom();
			LayoutPanels();
		}
Esempio n. 6
0
        ///<summary>Tests to see if this appointment will create a double booking. Returns arrayList with no items in it if no double bookings for this appt.  But if double booking, then it returns an arrayList of adacodes which would be double booked.  You must supply the appointment being scheduled as well as a list of all appointments for that day.  The list can include the appointment being tested if user is moving it to a different time on the same day.  The ProcsForOne list of procedures needs to contain the procedures for the apt becauese procsMultApts won't necessarily, especially if it's a planned appt on the pinboard.</summary>
        public static ArrayList GetDoubleBookedCodes(Appointment apt, Appointment[] dayList, Procedure[] procsMultApts, Procedure[] procsForOne)
        {
            ArrayList retVal = new ArrayList();          //ADAcodes
            //figure out which provider we are testing for
            int provNum;

            if (apt.IsHygiene)
            {
                provNum = apt.ProvHyg;
            }
            else
            {
                provNum = apt.ProvNum;
            }
            //compute the starting row of this appt
            int convertToY = (int)(((double)apt.AptDateTime.Hour * (double)60
                                    / (double)PrefB.GetInt("AppointmentTimeIncrement")
                                    + (double)apt.AptDateTime.Minute
                                    / (double)PrefB.GetInt("AppointmentTimeIncrement")
                                    ) * (double)ContrApptSheet.Lh * ContrApptSheet.RowsPerIncr);
            int    startIndex = convertToY / ContrApptSheet.Lh;     //rounds down
            string pattern    = ContrApptSingle.GetPatternShowing(apt.Pattern);
            //keep track of which rows in the entire day would be occupied by provider time for this appt
            ArrayList aptProvTime = new ArrayList();

            for (int k = 0; k < pattern.Length; k++)
            {
                if (pattern.Substring(k, 1) == "X")
                {
                    aptProvTime.Add(startIndex + k);                  //even if it extends past midnight, we don't care
                }
            }
            //Now, loop through all the other appointments for the day, and see if any would overlap this one
            bool overlaps;

            Procedure[] procs;
            bool        doubleBooked = false;   //applies to all appts, not just one at a time.

            for (int i = 0; i < dayList.Length; i++)
            {
                if (dayList[i].AptNum == apt.AptNum)              //ignore current apt in its old location
                {
                    continue;
                }
                //ignore other providers
                if (dayList[i].IsHygiene && dayList[i].ProvHyg != provNum)
                {
                    continue;
                }
                if (!dayList[i].IsHygiene && dayList[i].ProvNum != provNum)
                {
                    continue;
                }
                if (dayList[i].AptStatus == ApptStatus.Broken)              //ignore broken appts
                {
                    continue;
                }
                //calculate starting row
                //this math is copied from another section of the program, so it's sloppy. Safer than trying to rewrite it:
                convertToY = (int)(((double)dayList[i].AptDateTime.Hour * (double)60
                                    / (double)PrefB.GetInt("AppointmentTimeIncrement")
                                    + (double)dayList[i].AptDateTime.Minute
                                    / (double)PrefB.GetInt("AppointmentTimeIncrement")
                                    ) * (double)ContrApptSheet.Lh * ContrApptSheet.RowsPerIncr);
                startIndex = convertToY / ContrApptSheet.Lh;            //rounds down
                pattern    = ContrApptSingle.GetPatternShowing(dayList[i].Pattern);
                //now compare it to apt
                overlaps = false;
                for (int k = 0; k < pattern.Length; k++)
                {
                    if (pattern.Substring(k, 1) == "X")
                    {
                        if (aptProvTime.Contains(startIndex + k))
                        {
                            overlaps     = true;
                            doubleBooked = true;
                        }
                    }
                }
                if (overlaps)
                {
                    //we need to add all ADACodes for this appt to retVal
                    procs = Procedures.GetProcsOneApt(dayList[i].AptNum, procsMultApts);
                    for (int j = 0; j < procs.Length; j++)
                    {
                        retVal.Add(procs[j].ADACode);
                    }
                }
            }
            //now, retVal contains all double booked procs except for this appt
            //need to all procs for this appt.
            if (doubleBooked)
            {
                for (int j = 0; j < procsForOne.Length; j++)
                {
                    retVal.Add(procsForOne[j].ADACode);
                }
            }
            return(retVal);
        }
Esempio n. 7
0
        ///<summary>Used by appt search function.  Returns the next available time for the appointment.  Starts searching on lastSlot, which can be tonight at midnight for the first search.  Then, each subsequent search will start at the time of the previous search plus the length of the appointment.  Provider array cannot be length 0.  Might return array of 0 if it goes more than 1 year into the future.</summary>
        public static DateTime[] GetSearchResults(Appointment apt, DateTime afterDate, int[] providers, int resultCount,
                                                  TimeSpan beforeTime, TimeSpan afterTime)
        {
            DateTime dayEvaluating = afterDate.AddDays(1);

            Appointment[] aptList;                     //list of appointments for one day
            ArrayList     ALresults = new ArrayList(); //result Date/Times
            TimeSpan      timeFound;
            int           hourFound;

            int[][]  provBar      = new int[providers.Length][];    //dim 1 is for each provider.  Dim 2is the 10min increment
            bool[][] provBarSched = new bool[providers.Length][];   //keeps track of the schedule of each provider. True means open, false is closed.
            int      aptProv;
            string   pattern;
            int      startIndex;
            int      provIndex;       //the index of a provider within providers

            Schedule[] schedDay;      //all schedule items for a given day.
            bool       provHandled;
            bool       aptIsMatch = false;

            //int afterIndex=0;//GetProvBarIndex(afterTime);
            //int beforeIndex=0;//GetProvBarIndex(beforeTime);
            while (ALresults.Count < resultCount &&      //stops when the specified number of results are retrieved
                   dayEvaluating < afterDate.AddYears(1))
            {
                for (int i = 0; i < providers.Length; i++)
                {
                    provBar[i]      = new int[24 * ContrApptSheet.RowsPerHr];           //[144]; or 24*6
                    provBarSched[i] = new bool[24 * ContrApptSheet.RowsPerHr];
                }
                //get appointments for one day
                aptList = Refresh(dayEvaluating);
                //fill provBar
                for (int i = 0; i < aptList.Length; i++)
                {
                    if (aptList[i].IsHygiene)
                    {
                        aptProv = aptList[i].ProvHyg;
                    }
                    else
                    {
                        aptProv = aptList[i].ProvNum;
                    }
                    provIndex = -1;
                    for (int p = 0; p < providers.Length; p++)
                    {
                        if (providers[p] == aptProv)
                        {
                            provIndex = p;
                            break;
                        }
                    }
                    if (provIndex == -1)
                    {
                        continue;
                    }
                    pattern    = ContrApptSingle.GetPatternShowing(aptList[i].Pattern);
                    startIndex = (int)(((double)aptList[i].AptDateTime.Hour * (double)60 / (double)PrefB.GetInt("AppointmentTimeIncrement")
                                        + (double)aptList[i].AptDateTime.Minute / (double)PrefB.GetInt("AppointmentTimeIncrement"))
                                       * (double)ContrApptSheet.Lh * ContrApptSheet.RowsPerIncr)
                                 / ContrApptSheet.Lh;              //rounds down
                    for (int k = 0; k < pattern.Length; k++)
                    {
                        if (pattern.Substring(k, 1) == "X")
                        {
                            provBar[provIndex][startIndex + k]++;
                        }
                    }
                }
                //for(int i=0;i<provBar[0].Length;i++){
                //	Debug.Write(provBar[0][i].ToString());
                //}
                //Debug.WriteLine("");
                //handle all schedules by setting element of provBarSched to true if provider schedule shows open.
                schedDay = Schedules.RefreshDay(dayEvaluating);
                for (int p = 0; p < providers.Length; p++)
                {
                    provHandled = false;
                    //schedule for prov
                    for (int i = 0; i < schedDay.Length; i++)
                    {
                        if (schedDay[i].SchedType != ScheduleType.Provider)
                        {
                            continue;
                        }
                        if (providers[p] != schedDay[i].ProvNum)
                        {
                            continue;
                        }
                        if (schedDay[i].Status == SchedStatus.Closed || schedDay[i].Status == SchedStatus.Holiday)
                        {
                            provHandled = true;                          //all elements remain false.
                            break;
                        }
                        SetProvBarSched(ref provBarSched[p], schedDay[i].StartTime, schedDay[i].StopTime);
                        provHandled = true;
                    }
                    if (provHandled)
                    {
                        continue;
                    }
                    //schedDefault for prov
                    for (int i = 0; i < SchedDefaults.List.Length; i++)
                    {
                        if (SchedDefaults.List[i].DayOfWeek != (int)dayEvaluating.DayOfWeek)
                        {
                            continue;
                        }
                        if (SchedDefaults.List[i].SchedType != ScheduleType.Provider)
                        {
                            continue;
                        }
                        if (providers[p] != SchedDefaults.List[i].ProvNum)
                        {
                            continue;
                        }
                        SetProvBarSched(ref provBarSched[p], SchedDefaults.List[i].StartTime, SchedDefaults.List[i].StopTime);
                        provHandled = true;
                    }
                    if (provHandled)
                    {
                        continue;
                    }
                    //schedule for practice
                    for (int i = 0; i < schedDay.Length; i++)
                    {
                        if (schedDay[i].SchedType != ScheduleType.Practice)
                        {
                            continue;
                        }
                        if (schedDay[i].Status == SchedStatus.Closed || schedDay[i].Status == SchedStatus.Holiday)
                        {
                            provHandled = true;                          //all elements remain false.
                            break;
                        }
                        SetProvBarSched(ref provBarSched[p], schedDay[i].StartTime, schedDay[i].StopTime);
                        provHandled = true;
                    }
                    if (provHandled)
                    {
                        continue;
                    }
                    //SchedDefault for practice
                    for (int i = 0; i < SchedDefaults.List.Length; i++)
                    {
                        if (SchedDefaults.List[i].DayOfWeek != (int)dayEvaluating.DayOfWeek)
                        {
                            continue;
                        }
                        if (SchedDefaults.List[i].SchedType != ScheduleType.Practice)
                        {
                            continue;
                        }
                        SetProvBarSched(ref provBarSched[p], SchedDefaults.List[i].StartTime, SchedDefaults.List[i].StopTime);
                    }
                }
                //step through day, one increment at a time, looking for a slot
                pattern   = ContrApptSingle.GetPatternShowing(apt.Pattern);
                timeFound = new TimeSpan(0);
                for (int i = 0; i < provBar[0].Length; i++)          //144 if using 10 minute increments
                {
                    for (int p = 0; p < providers.Length; p++)
                    {
                        //assume apt will be placed here
                        aptIsMatch = true;
                        //test all apt increments for prov closed. If any found, continue
                        for (int a = 0; a < pattern.Length; a++)
                        {
                            if (provBarSched[p].Length < i + a + 1 || !provBarSched[p][i + a])
                            {
                                aptIsMatch = false;
                                break;
                            }
                        }
                        if (!aptIsMatch)
                        {
                            continue;
                        }
                        //test all apt increments with an X for not scheduled. If scheduled, continue.
                        for (int a = 0; a < pattern.Length; a++)
                        {
                            if (pattern.Substring(a, 1) == "X" && (provBar[p].Length < i + a + 1 || provBar[p][i + a] > 0))
                            {
                                aptIsMatch = false;
                                break;
                            }
                        }
                        if (!aptIsMatch)
                        {
                            continue;
                        }
                        //convert to valid time
                        hourFound = (int)((double)(i) / 60 * PrefB.GetInt("AppointmentTimeIncrement"));
                        timeFound = new TimeSpan(
                            hourFound,
                            //minutes. eg. (13-(2*60/10))*10
                            (int)((i - ((double)hourFound * 60 / (double)PrefB.GetInt("AppointmentTimeIncrement")))
                                  * PrefB.GetInt("AppointmentTimeIncrement")),
                            0);
                        //make sure it's after the time restricted
                        //Debug.WriteLine(timeFound.ToString()+"  "+afterTime.ToString());
                        //apt.AptDateTime.TimeOfDay+"  "+afterTime.ToString());
                        if (afterTime != TimeSpan.Zero && timeFound < afterTime)
                        {
                            aptIsMatch = false;
                            continue;
                        }
                        if (beforeTime != TimeSpan.Zero && timeFound > beforeTime)
                        {
                            aptIsMatch = false;
                            continue;
                        }
                        //match found
                        ALresults.Add(dayEvaluating + timeFound);
                    }                    //for p
                    if (aptIsMatch)
                    {
                        break;
                    }
                }
                dayEvaluating = dayEvaluating.AddDays(1);              //move to the next day
            }
            DateTime[] retVal = new DateTime[ALresults.Count];
            ALresults.CopyTo(retVal);
            return(retVal);
        }