private static async Task <IEnumerable <TileNotificationContentAndData> > GenerateTileNotificationContentsAsync(AccountDataItem account)
        {
            DateTime today            = DateTime.Today;
            var      scheduleTileData = await ScheduleTileDataHelper.LoadAsync(account, today, DAYS_INCLUDING_TODAY);

            return(GenerateTileNotificationContents(scheduleTileData));
        }
        private static IEnumerable <TileNotificationContentAndData> GenerateTileNotificationContents(ScheduleTileDataHelper scheduleTileData)
        {
            // If no semester
            if (!scheduleTileData.HasSemester)
            {
                yield return(new TileNotificationContentAndData()
                {
                    Content = CreateBasicTileNotificationContent(PowerPlannerResources.GetString("String_NoSemester"))
                });

                yield break;
            }

            bool            createdContent = false;
            DateTime        now            = DateTime.Now.AddSeconds(30); // Use now as 30 secs in advance to prevent scheduling notifications that already passed
            List <DateTime> previousTimes  = new List <DateTime>();

            foreach (var dayData in scheduleTileData.GetDataForAllDays())
            {
                // If nothing on this day
                if (!dayData.Schedules.Any() && !dayData.Holidays.Any())
                {
                    // Add that we skipped this day, and continue to next
                    previousTimes.Add(dayData.Date);
                    continue;
                }

                // Handle previously skipped days
                if (previousTimes.Count > 0)
                {
                    foreach (var dateSkipped in previousTimes)
                    {
                        XmlDocument xmlForSkipped;

                        if (dayData.Holidays.Any())
                        {
                            xmlForSkipped = GenerateHolidayTileNotification(dayData.Holidays, TileHelper.ToFriendlyDate(dayData.Date, dateSkipped), dayData.Date);
                        }
                        else
                        {
                            xmlForSkipped = GenerateTileNotification(dayData.Schedules, TileHelper.ToFriendlyDate(dayData.Date, dateSkipped), dayData.Date, dateSkipped);
                        }

                        yield return(new TileNotificationContentAndData()
                        {
                            Content = xmlForSkipped,
                            DeliveryTime = dateSkipped,
                            ExpirationTime = dateSkipped.AddDays(1)
                        });

                        createdContent = true;
                    }

                    previousTimes.Clear();
                }

                // First one starts displaying exactly at the start of the day
                DateTime deliveryTime = dayData.Date;

                if (dayData.Holidays.Any())
                {
                    XmlDocument xml = GenerateHolidayTileNotification(dayData.Holidays, "Today", dayData.Date);

                    var expirationTime = dayData.Date.AddHours(15); // Switches at 3 PM
                    if (expirationTime > now)
                    {
                        yield return(new TileNotificationContentAndData()
                        {
                            Content = xml,
                            DeliveryTime = deliveryTime,
                            ExpirationTime = expirationTime
                        });

                        createdContent = true;
                    }

                    // We always add this, so that the next day's content will start appearing after the last item
                    previousTimes.Add(expirationTime);
                }
                else
                {
                    var schedulesOnDate = dayData.Schedules.ToList();
                    while (schedulesOnDate.Count > 0)
                    {
                        DateTime expirationTime = dayData.Date.Add(schedulesOnDate.First().EndTime.TimeOfDay);

                        // If it hasn't expired yet
                        if (expirationTime > now)
                        {
                            XmlDocument xml = GenerateTileNotification(schedulesOnDate, "Today", dayData.Date, dayData.Date);

                            // If the class is 10 mins or longer, we'll switch it 5 mins before the class ends, so that user can see their next class
                            if ((schedulesOnDate.First().EndTime.TimeOfDay - schedulesOnDate.First().StartTime.TimeOfDay).TotalMinutes >= 10)
                            {
                                expirationTime = expirationTime.AddMinutes(-5);
                            }

                            yield return(new TileNotificationContentAndData()
                            {
                                Content = xml,
                                DeliveryTime = deliveryTime,
                                ExpirationTime = expirationTime
                            });

                            createdContent = true;
                        }

                        deliveryTime = expirationTime;

                        schedulesOnDate.RemoveAt(0);
                    }

                    // We always add this, so that the next day's content will start appearing after the last item
                    previousTimes.Add(deliveryTime);
                }
            }

            if (!createdContent)
            {
                yield return(new TileNotificationContentAndData()
                {
                    Content = CreateBasicTileNotificationContent(PowerPlannerResources.GetString("String_NoClassesThisWeek"))
                });
            }
        }
            private async System.Threading.Tasks.Task InitializeDataAsync()
            {
                List <object> items = null;

                _now = DateTime.Now;
                bool hasAccount  = false;
                bool hasSemester = false;
                List <ViewItemSchedule> schedulesToday = new List <ViewItemSchedule>();

                try
                {
                    await System.Threading.Tasks.Task.Run(async delegate
                    {
                        var account = await AccountsManager.GetLastLogin();

                        if (account != null)
                        {
                            _localAccountId = account.LocalAccountId;
                            hasAccount      = true;

                            const int DAYS_INCLUDING_TODAY = 7;
                            var scheduleTileData           = await ScheduleTileDataHelper.LoadAsync(account, _now.Date, DAYS_INCLUDING_TODAY);

                            if (scheduleTileData.HasSemester)
                            {
                                hasSemester = true;

                                items = new List <object>();

                                foreach (var dayData in scheduleTileData.GetDataForAllDays())
                                {
                                    if (dayData.Holidays.Any())
                                    {
                                        // If we already displayed these holidays, skip subsequent duplicate days
                                        if (items.Count >= dayData.Holidays.Length && items.TakeLast(dayData.Holidays.Length).SequenceEqual(dayData.Holidays))
                                        {
                                            // Skip
                                        }
                                        else
                                        {
                                            // If not today
                                            if (!dayData.IsToday)
                                            {
                                                // We add the date header only for non-today
                                                items.Add(dayData.Date);
                                            }

                                            items.AddRange(dayData.Holidays);
                                        }
                                    }

                                    else if (dayData.Schedules.Any())
                                    {
                                        // If not today
                                        if (!dayData.IsToday)
                                        {
                                            // If there's currently no items
                                            if (items.Count == 0)
                                            {
                                                // Add the text saying no class today!
                                                items.Add(PowerPlannerResources.GetString("String_NoClassToday"));
                                            }

                                            // We add the date header only for non-today
                                            items.Add(dayData.Date);
                                        }

                                        // If today
                                        if (dayData.IsToday)
                                        {
                                            foreach (var s in dayData.Schedules)
                                            {
                                                if (s.EndTime.TimeOfDay > _now.TimeOfDay)
                                                {
                                                    items.Add(s);
                                                    schedulesToday.Add(s);
                                                }
                                            }

                                            if (items.Count == 0)
                                            {
                                                items.Add(PowerPlannerResources.GetString("String_NoMoreClasses"));
                                            }
                                        }
                                        else
                                        {
                                            items.AddRange(dayData.Schedules);
                                        }
                                    }
                                }
                            }
                        }
                    });

                    if (items == null || items.Count == 0)
                    {
                        if (hasSemester)
                        {
                            items = new List <object>()
                            {
                                PowerPlannerResources.GetString("String_NoClassesThisWeek")
                            };
                        }
                        else if (hasAccount)
                        {
                            items = new List <object>()
                            {
                                PowerPlannerResources.GetString("String_NoSemester")
                            };
                        }
                        else
                        {
                            items = new List <object>()
                            {
                                PowerPlannerResources.GetString("String_NoAccount")
                            };
                        }
                    }

                    _items = items;
                }
                catch (Exception ex)
                {
                    TelemetryExtension.Current?.TrackException(ex);
                }

                // Schedule next
                try
                {
                    DateTime nextChangeTime = _now.Date.AddDays(1);
                    if (schedulesToday.Count > 0)
                    {
                        nextChangeTime = _now.Date.Add(schedulesToday.First().EndTime.TimeOfDay);
                    }

                    AlarmManagerHelper.Schedule(
                        context: _context,
                        receiverType: typeof(UpdateWidgetScheduleReceiver),
                        wakeTime: nextChangeTime);
                }
                catch (Exception ex)
                {
                    TelemetryExtension.Current?.TrackException(ex);
                }
            }