Пример #1
0
        private void Initialize(SchedulesOnDay schedules, MyObservableList <BaseViewItemHomeworkExamGrade> events, MyObservableList <ViewItemHoliday> holidays)
        {
            List <ScheduleItem> schedulesCopied;

            if (schedules == null)
            {
                // Different semester case, so no schedules
                schedulesCopied = new List <ScheduleItem>();
            }
            else
            {
                schedulesCopied = schedules.Where(i => i.EndTime.TimeOfDay > i.StartTime.TimeOfDay).Select(i => new ScheduleItem(this, i)).ToList();
            }

            List <EventItem> eventsCopied = new List <EventItem>();
            List <BaseViewItemHomeworkExam> allDayEvents = new List <ViewItems.BaseViewItems.BaseViewItemHomeworkExam>();

            foreach (var e in events.OfType <BaseViewItemHomeworkExam>())
            {
                if (e.IsDuringDay())
                {
                    eventsCopied.Add(new EventItem(this, e));
                }
                else
                {
                    allDayEvents.Add(e);
                }
            }
            AllDayItems = allDayEvents;

            Holidays    = holidays.ToList();
            HasHolidays = Holidays.Any();
            _cachedHolidayAndAllDayItems = null;

            var schedulesFinal = schedulesCopied.ToArray();
            var eventsFinal    = eventsCopied.ToList();

            ScheduleItems = schedulesFinal;

            // Handle schedule collisions
            while (schedulesCopied.Count > 0)
            {
                var collidingSchedules = new List <ScheduleItem>()
                {
                    schedulesCopied[0]
                };
                schedulesCopied.RemoveAt(0);
                AddColliding(schedulesCopied, collidingSchedules);

                if (collidingSchedules.Count > 1)
                {
                    for (int i = 0; i < collidingSchedules.Count; i++)
                    {
                        collidingSchedules[i].Column       = i;
                        collidingSchedules[i].NumOfColumns = collidingSchedules.Count;
                    }
                }
            }

            // Handle event collisions
            while (eventsCopied.Count > 0)
            {
                var collidingEvents = new List <EventItem>()
                {
                    eventsCopied[0]
                };
                eventsCopied.RemoveAt(0);
                AddColliding(eventsCopied, collidingEvents);

                List <ScheduleItem> scheduleCollisionsWithEvent = new List <ScheduleItem>();

                // If there's a colliding schedule, we collapse
                bool doesCollideWithSchedule = false;
                foreach (var e in collidingEvents)
                {
                    foreach (var s in schedulesFinal)
                    {
                        if (s.CollidesWith(e))
                        {
                            doesCollideWithSchedule = true;
                            scheduleCollisionsWithEvent.Add(s);
                        }
                    }
                }

                if (doesCollideWithSchedule)
                {
                    var firstEvent = collidingEvents[0];
                    firstEvent.IsCollapsedMode = true;
                    foreach (var e in collidingEvents.Skip(1))
                    {
                        firstEvent.AddAdditionalItem(e);
                        eventsFinal.Remove(e);
                    }

                    foreach (var s in scheduleCollisionsWithEvent)
                    {
                        if (firstEvent.AdditionalItems != null)
                        {
                            s.LeftOffset = _spacingWithAdditionalItems;
                        }
                        else
                        {
                            // LeftOffset might have been previously assigned, so make sure we're assigning higher value
                            if (_spacingWhenNoAdditionalItems > s.LeftOffset)
                            {
                                s.LeftOffset = _spacingWhenNoAdditionalItems;
                            }
                        }
                    }
                }
                else if (collidingEvents.Count == 1)
                {
                    // Nothing
                }
                else if (collidingEvents.Count == 2)
                {
                    // Exactly two items
                    collidingEvents[0].NumOfColumns = 2;
                    collidingEvents[1].NumOfColumns = 2;
                    collidingEvents[1].Column       = 1;
                }
                else
                {
                    // More than two items
                    EventItem prev       = null;
                    bool      isLeftSide = true;

                    while (collidingEvents.Count > 0)
                    {
                        var curr = collidingEvents[0];
                        curr.NumOfColumns = 2;
                        collidingEvents.RemoveAt(0);

                        if (prev != null)
                        {
                            if (!isLeftSide)
                            {
                                curr.Column = 1;
                            }

                            // Find out if any items collide with the prev item, and therefore need to become mini-items with the curr item
                            while (collidingEvents.Count > 0)
                            {
                                var next = collidingEvents[0];
                                if (prev.CollidesWith(next))
                                {
                                    collidingEvents.RemoveAt(0);
                                    curr.AddAdditionalItem(next);
                                    eventsFinal.Remove(next);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }

                        // Prev becomes curr
                        prev = curr;

                        // And we switch the side
                        isLeftSide = !isLeftSide;
                    }
                }
            }

            EventItems = eventsFinal.ToArray();

            if (ScheduleItems.Any() || EventItems.Any())
            {
                var min = ScheduleItems.OfType <BaseScheduleItem>().Concat(EventItems.OfType <BaseScheduleItem>()).Min(i => i.StartTime);
                if (min.Minutes == 59 && min.Hours != 23)
                {
                    // So that a task that's due before class (1 min before) doesn't cause an entire hour to be rendered, we adjust 0:59 to the next hour
                    // Note that we exclude incrementing 23:59 since that would make it the next day
                    min = min.Add(TimeSpan.FromMinutes(1));
                }
                StartTime = new TimeSpan(min.Hours, 0, 0);
                EndTime   = new TimeSpan(ScheduleItems.OfType <BaseScheduleItem>().Concat(EventItems.OfType <BaseScheduleItem>()).Max(i => i.EndTime).Hours, 0, 0);
                if (EndTime < StartTime)
                {
                    EndTime = StartTime.Add(TimeSpan.FromHours(1));
                }
            }

            CalculateOffsets();
        }