/// <summary>
        /// Handles the appoinment overlaps badly.
        /// </summary>
        /// <param name="day">The day.</param>
        private static void handleOverlaps(DayWithHourRegion day)
        {
            //TODO: work out overlaps through a better process
            if (day.Appointments.Count > 0)
            {
                for (int j = 0; j < day.Appointments.Count; j++)
                {
                    AppointmentWithHourRegion app = day.Appointments[j] as AppointmentWithHourRegion;

                    //if we have overlaps, things get nasty
                    if (app.HasOverlaps)
                    {
                        foreach (AppointmentWithHourRegion overlapApp in app.OverlappingAppointments)
                        {
                            //if another appointment overlaps
                            if (!overlapApp.Bounds.IsEmpty &&
                                overlapApp.Bounds.IntersectsWith(new Rectangle(app.Bounds.X,
                                                                               app.Bounds.Y,
                                                                               app.Bounds.Width,
                                                                               app.Bounds.Height))
                                )
                            {
                                //if the app width is bigger, trim it
                                if (app.Bounds.Width >= overlapApp.Bounds.Width)
                                {
                                    //if current app x starts after the other app x
                                    if (app.Bounds.X >= overlapApp.Bounds.X)
                                    {
                                        app.Bounds = new Rectangle(
                                            app.Bounds.X + app.Bounds.Width / 4,
                                            app.Bounds.Y,
                                            app.Bounds.Width - app.Bounds.Width / 4,
                                            app.Bounds.Height);
                                    }
                                    else
                                    {
                                        app.Bounds = new Rectangle(
                                            app.Bounds.X,
                                            app.Bounds.Y,
                                            app.Bounds.Width - app.Bounds.Width / 4,
                                            app.Bounds.Height);
                                    }
                                }
                            }


                            if (app.Bounds.X + app.Bounds.Width > day.Bounds.X + day.Bounds.Width)
                            {
                                Rectangle rect = app.Bounds;
                                rect.Width = day.Bounds.X + day.Bounds.Width - app.Bounds.X;
                                app.Bounds = rect;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Calculate the appointment bounds. This works out the size and
        /// shape that the appointments will take up on the screen,
        /// and handles any other calculations such as overlaps. This method
        /// is called from OnPaint only when the property BoundsValidAppointment
        /// is set to false (this property is set to false in cases such as
        /// when the control has been resized or the appointment list has
        /// changed).
        /// </summary>
        protected override void CalculateAppointmentBounds(Graphics graphics)
        {
            //int appSeparator = 3;
            //recalculate the appointments
            foreach (DayWithHourRegion day in this.DayRegions)
            {
                //clear day and hour appointment regions
                day.Appointments.Clear();
                foreach (HourRegion hour in day.Hours)
                {
                    hour.Appointments.Clear();
                }

                //TODO: cater for overlapping multiple timeslots
                foreach (Appointment app in Appointments)
                {
                    if (app.DateStart.Year == day.Date.Year && app.DateStart.DayOfYear == day.Date.DayOfYear)
                    {
                        AppointmentWithHourRegion appRegion = new AppointmentWithHourRegion(app);
                        day.Appointments.Add(appRegion);
                        foreach (HourRegion hour in day.Hours)
                        {
                            if (app.DateStart.Hour == hour.Hour) // && app.DateStart.Hour <= hour.Hour)
                            {
                                hour.Appointments.Add(appRegion);
                            }
                        }
                    }
                }
                foreach (AppointmentWithHourRegion appt1 in day.Appointments)
                {
                    foreach (AppointmentWithHourRegion appt2 in day.Appointments)
                    {
                        if (appt1 != appt2
                            &&
                            appt1.Appointment.DateEnd != appt2.Appointment.DateStart
                            &&
                            appt1.Appointment.DateStart != appt2.Appointment.DateEnd
                            &&
                            (
                                appt2.Appointment.DateStart == appt1.Appointment.DateStart
                                ||
                                appt2.Appointment.DateEnd == appt1.Appointment.DateEnd
                                ||
                                (appt2.Appointment.DateStart < appt1.Appointment.DateEnd &&
                                 appt2.Appointment.DateStart > appt1.Appointment.DateStart)
                                ||
                                (appt2.Appointment.DateEnd < appt1.Appointment.DateEnd &&
                                 appt2.Appointment.DateEnd > appt1.Appointment.DateStart)
                                ||
                                (appt1.Appointment.DateEnd < appt2.Appointment.DateEnd &&
                                 appt1.Appointment.DateEnd > appt2.Appointment.DateStart)

                            )
                            )
                        {
                            appt1.HasOverlaps = true;
                            appt2.HasOverlaps = true;
                            if (!appt1.OverlappingAppointments.Contains(appt2))
                            {
                                appt1.OverlappingAppointments.Add(appt2);
                            }
                            if (!appt2.OverlappingAppointments.Contains(appt1))
                            {
                                appt2.OverlappingAppointments.Add(appt1);
                            }
                        }
                    }
                }
                //roughly work out appt bounds and starting slot
                for (int i = 0; i < day.Hours.Count; i++)
                {
                    HourRegion hour  = day.Hours[i];
                    int        apptY = hour.Bounds.Y;
                    if (hour.Appointments.Count > 0)
                    {
                        int hourX = hour.Bounds.X;

                        int apptX = hourX;
                        for (int j = 0; j < hour.Appointments.Count; j++)
                        {
                            AppointmentWithHourRegion app = hour.Appointments[j];

                            //work out starting slot
                            int startMinute = app.Appointment.DateStart.Minute;
                            if (startMinute >= 0 && startMinute < 15)
                            {
                                app.StartingSlot = 0;
                            }
                            else if (startMinute >= 15 && startMinute < 30)
                            {
                                app.StartingSlot = 1;
                            }
                            else if (startMinute >= 30 && startMinute < 45)
                            {
                                app.StartingSlot = 2;
                            }
                            else if (startMinute >= 45 && startMinute < 60)
                            {
                                app.StartingSlot = 3;
                            }

                            //work out duration and therefore height
                            TimeSpan span           = app.Appointment.DateEnd.Subtract(app.Appointment.DateStart);
                            int      tempApptHeight = ((span.Hours * 60 + span.Minutes) / 15) * hour.Bounds00.Height;
                            int      tempApptY      = apptY + (app.StartingSlot * hour.Bounds00.Height);

                            int apptWidth = hour.Bounds.Width;

                            //if we have overlaps, things get nasty
                            if (app.HasOverlaps)
                            {
                                int hourAppWidth = apptWidth / hour.Appointments.Count;
                                apptWidth = hourAppWidth;
                            }
                            app.Bounds = new Rectangle(apptX, tempApptY, apptWidth, tempApptHeight);

                            //set the bounds
                            apptX += apptWidth;
                        }
                    }
                }

                //go over again a few times to resolve overlaps
                for (int i = 0; i < 5; i++)
                {
                    handleOverlaps(day);
                }
            }
            BoundsValidAppointment = true;
        }