/// <summary>
        /// Gets if an alert is already being shown.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private static bool IsOpen(Reminder item)
        {
            bool found = false;

            foreach (Toast each in ToastManager.OpenToasts)
            {
                each.Dispatcher.Invoke(() =>
                {
                    if ((each.Tag as Reminder).ID == item.ID && (each.Tag as Reminder).ReminderType == item.ReminderType)
                    {
                        found = true;
                    }
                });

                if (found)
                {
                    return(found);
                }
            }

            return(found);
        }
 public AlertEventArgs(Reminder reminder, bool open)
 {
     _reminder = reminder;
     _open     = open;
 }
        /// <summary>
        /// Show an alert based on a reminder.
        /// </summary>
        /// <param name="reminder"></param>
        private static void DisplayAlert(Reminder reminder)
        {
            if (!IsOpen(reminder) && !IsQueued(reminder))
            {
                //Thread alertThread = new Thread(() =>
                //{
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    Toast alert;
                    string sound = Settings.AlertSound;

                    if (reminder.ReminderType == ReminderType.Appointment)
                    {
                        Appointment appt = AppointmentDatabase.GetAppointment(reminder.ID);

                        string timeString = "";                        // reminder.StartTime.ToShortDateString();

                        //timeString += " » ";

                        if (appt.AllDay)
                        {
                            if ((reminder.EventStartDate.Value - reminder.EventEndDate.Value).TotalDays > 1)
                            {
                                timeString = reminder.EventStartDate.Value.Date.ToShortDateString() + " - "
                                             + reminder.EventEndDate.Value.Date.ToShortDateString();
                            }
                            else
                            {
                                timeString = reminder.EventStartDate.Value.Date.ToShortDateString();
                            }

                            timeString += " » All Day";
                        }
                        else
                        {
                            if ((reminder.EventStartDate.Value.Date != reminder.EventEndDate.Value.Date))
                            {
                                timeString = reminder.EventStartDate.Value.ToShortDateString() + " "
                                             + RandomFunctions.FormatTime(reminder.EventStartDate.Value.TimeOfDay)
                                             + " - " + reminder.EventEndDate.Value.ToShortDateString() + " "
                                             + RandomFunctions.FormatTime(reminder.EventEndDate.Value.TimeOfDay);
                            }
                            else
                            {
                                timeString  = reminder.EventStartDate.Value.Date.ToShortDateString();
                                timeString += " » " +
                                              RandomFunctions.FormatTime(appt.StartDate.TimeOfDay) + " - "
                                              + RandomFunctions.FormatTime(appt.EndDate.TimeOfDay);
                            }
                        }

                        alert = new Toast(
                            !string.IsNullOrEmpty(appt.Subject) ? appt.Subject : "(No subject)",
                            appt.Location,
                            timeString,
                            new BitmapImage(new Uri("pack://*****:*****@"Resources/Media/" + sound, UriKind.Relative),
                            ToastDuration.Long,
                            Settings.UnmuteSpeakers);
                    }
                    else
                    {
                        UserTask task = TaskDatabase.GetTask(reminder.ID);
                        alert         = new Toast(
                            !string.IsNullOrEmpty(task.Subject) ? task.Subject : "(No subject)",
                            task.Priority.ToString(),
                            task.DueDate.HasValue ? task.DueDate.Value.ToShortDateString() : "No due date",
                            new BitmapImage(new Uri("pack://*****:*****@"Resources/Media/" + sound, UriKind.Relative),
                            ToastDuration.Long,
                            Settings.UnmuteSpeakers);
                    }

                    alert.Tag     = reminder;
                    alert.Closed += alert_Closed;
                    alert.Open();
                });
                //});

                //alertThread.SetApartmentState(ApartmentState.STA);
                //alertThread.IsBackground = true;
                //alertThread.Start();
            }
        }
        /// <summary>
        /// Remove a queued item.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="type"></param>
        public static void RemoveItem(string id, DateTime?date, ReminderType type)
        {
            bool found = false;

            foreach (Toast each in ToastManager.OpenToasts)
            {
                each.Dispatcher.Invoke(() =>
                {
                    Reminder _r = each.Tag as Reminder;

                    if (_r.ID == id && _r.ReminderType == type && _r.EventStartDate == date)
                    {
                        (each as Window).Close();
                        found = true;
                    }
                });

                if (found)
                {
                    return;
                }
            }

            Toast[] queued = new Toast[ToastManager.QueuedToasts.Count];
            ToastManager.QueuedToasts.CopyTo(queued, 0);

            foreach (Toast each in queued)
            {
                each.Dispatcher.Invoke(() =>
                {
                    Reminder _r = each.Tag as Reminder;

                    if (_r.ID == id && _r.ReminderType == type && _r.EventStartDate == date)
                    {
                        RemoveToast(each);
                        found = true;
                    }
                });

                if (found)
                {
                    return;
                }
            }

            if (_queue == null)
            {
                return;
            }

            Reminder[] rQueued = new Reminder[_queue.Count];
            _queue.CopyTo(rQueued, 0);

            foreach (Reminder each in rQueued)
            {
                if (each.ID == id && each.ReminderType == type && each.EventStartDate == date)
                {
                    RemoveReminder(each);
                    return;
                }
            }
        }
        /// <summary>
        /// Gets all Tasks that are enabled and have reminders set within one day.
        /// </summary>
        /// <returns></returns>
        private static Reminder[] ActiveTasks()
        {
            XmlDocument db       = TaskDatabase.Database.Doc;
            XmlNodeList elements = db.GetElementsByTagName(TaskDatabase.TaskTag);
            int         count    = elements.Count;

            if (count > 0)
            {
                DateTime now = DateTime.Now;

                Reminder[] reminders  = new Reminder[count];
                int        actualsize = 0;

                for (int i = 0; i < count; i++)
                {
                    XmlNode current = elements[i];
                    XmlAttributeCollection attribs = current.Attributes;

                    bool isReminderEnabled      = FormatHelpers.ParseBool(attribs[TaskDatabase.IsReminderEnabledAttribute].Value);
                    UserTask.StatusPhase status = (UserTask.StatusPhase) int.Parse(attribs[TaskDatabase.StatusAttribute].Value);

                    if (isReminderEnabled && status != UserTask.StatusPhase.Completed)
                    {
                        DateTime taskReminder = FormatHelpers.ParseDateTime(attribs[TaskDatabase.ReminderAttribute].Value);

                        // We only want to queue one day's worth of tasks.
                        if (taskReminder < now.AddDays(1))                        //taskReminder >= now &&
                        {
                            Reminder r = new Reminder();
                            r.ReminderType = ReminderType.Task;
                            r.ID           = attribs[XmlDatabase.IdAttribute].Value;

                            if (current.ParentNode.Name != "nodate")
                            {
                                r.EventEndDate = FormatHelpers.SplitDateString(current.ParentNode.Name);
                            }

                            if (attribs[TaskDatabase.StartDateAttribute].Value == "")
                            {
                                r.EventStartDate = null;
                            }
                            else
                            {
                                r.EventStartDate = FormatHelpers.ParseShortDateTime(attribs[TaskDatabase.StartDateAttribute].Value);
                            }

                            r.AlertStartTime = taskReminder;

                            reminders[actualsize++] = r;
                        }
                    }
                }

                // Trim array to size.
                Array.Resize(ref reminders, actualsize);

                return(reminders);
            }

            return(new Reminder[0]);
        }
        /// <summary>
        /// Gets all Appointments that are enabled and have reminders set within one day.
        /// </summary>
        /// <returns></returns>
        private static Reminder[] ActiveAppointments()
        {
            XmlDocument db       = AppointmentDatabase.Database.Doc;
            XmlNodeList elements = db.GetElementsByTagName(AppointmentDatabase.AppointmentTag);
            int         count    = elements.Count;

            if (count > 0)
            {
                DateTime now = DateTime.Now;

                Reminder[] reminders  = new Reminder[count];
                int        actualsize = 0;

                for (int i = 0; i < count; i++)
                {
                    XmlNode current = elements[i];
                    XmlAttributeCollection attribs  = current.Attributes;
                    XmlAttribute           repeatId = attribs[AppointmentDatabase.RepeatIdAttribute];
                    TimeSpan reminder;
                    XmlNode  baseRecurring = null;

                    if (repeatId != null)
                    {
                        // Get the recurring event this appointment is based off of.
                        baseRecurring = AppointmentDatabase.Database.Doc.GetElementById(repeatId.Value);
                        reminder      = TimeSpan.Parse(AppointmentDatabase.GetAttribute(AppointmentDatabase.ReminderAttribute, attribs, baseRecurring.Attributes, AppointmentDatabase.ReminderAttributeDefault));
                    }
                    else
                    {
                        reminder = TimeSpan.Parse(attribs.GetValue(AppointmentDatabase.ReminderAttribute, AppointmentDatabase.ReminderAttributeDefault));
                    }

                    if (reminder != TimeSpan.FromSeconds(-1))
                    {
                        if (current.ParentNode.ParentNode.Name != AppointmentDatabase.RecurringAppointmentTag)
                        {
                            // This is a standard (non-recurring) appointment
                            DateTime start;
                            DateTime end;

                            bool allday;

                            if (repeatId != null)
                            {
                                start  = FormatHelpers.ParseDateTime(AppointmentDatabase.GetAttribute(AppointmentDatabase.StartDateAttribute, attribs, baseRecurring.Attributes, null));
                                end    = FormatHelpers.ParseDateTime(AppointmentDatabase.GetAttribute(AppointmentDatabase.EndDateAttribute, attribs, baseRecurring.Attributes, null));
                                allday = FormatHelpers.ParseBool(AppointmentDatabase.GetAttribute(AppointmentDatabase.AllDayAttribute, attribs, baseRecurring.Attributes, AppointmentDatabase.AllDayAttributeDefault));
                            }
                            else
                            {
                                start  = FormatHelpers.ParseDateTime(attribs[AppointmentDatabase.StartDateAttribute].Value);
                                end    = FormatHelpers.ParseDateTime(attribs[AppointmentDatabase.EndDateAttribute].Value);
                                allday = FormatHelpers.ParseBool(attribs.GetValue(AppointmentDatabase.AllDayAttribute, AppointmentDatabase.AllDayAttributeDefault));
                            }

                            if (allday)
                            {
                                start = start.Date;
                                end   = end.Date;
                            }

                            DateTime ring;

                            try { ring = start - reminder; }
                            catch { ring = start; }

                            // We only want to queue up to one day's worth of appointments.
                            if (ring < now.AddDays(1))
                            {
                                Reminder r = new Reminder();
                                r.ReminderType   = ReminderType.Appointment;
                                r.ID             = attribs[XmlDatabase.IdAttribute].Value;
                                r.EventStartDate = start;
                                r.EventEndDate   = end;
                                r.AlertStartTime = ring;
                                r.AlertEndTime   = end;

                                reminders[actualsize++] = r;
                            }
                        }
                        else
                        {
                            // This is a recurring appointment
                            DateTime start = FormatHelpers.ParseDateTime(attribs[AppointmentDatabase.StartDateAttribute].Value);
                            DateTime end   = FormatHelpers.ParseDateTime(attribs[AppointmentDatabase.EndDateAttribute].Value);

                            bool allday = FormatHelpers.ParseBool(attribs.GetValue(AppointmentDatabase.AllDayAttribute, AppointmentDatabase.AllDayAttributeDefault));

                            Appointment appt = new Appointment(false);
                            appt.ID        = attribs[XmlDatabase.IdAttribute].Value;
                            appt.StartDate = start;
                            appt.EndDate   = end;
                            appt.AllDay    = allday;
                            appt.Reminder  = reminder;

                            appt.IsRepeating = true;

                            Recurrence recurrence = new Recurrence();

                            recurrence.Type     = (RepeatType)int.Parse(attribs[AppointmentDatabase.RepeatTypeAttribute].Value);
                            recurrence.Day      = attribs[AppointmentDatabase.RepeatDayAttribute].Value;
                            recurrence.Week     = int.Parse(attribs[AppointmentDatabase.RepeatWeekAttribute].Value);
                            recurrence.Month    = int.Parse(attribs[AppointmentDatabase.RepeatMonthAttribute].Value);
                            recurrence.Year     = int.Parse(attribs[AppointmentDatabase.RepeatYearAttribute].Value);
                            recurrence.End      = (RepeatEnd)int.Parse(attribs[AppointmentDatabase.RepeatEndAttribute].Value);
                            recurrence.EndDate  = FormatHelpers.ParseShortDateTime(attribs[AppointmentDatabase.RepeatEndDateAttribute].Value);
                            recurrence.EndCount = int.Parse(attribs[AppointmentDatabase.RepeatEndCountAttribute].Value);

                            appt.Recurrence = recurrence;

                            if (attribs[AppointmentDatabase.RepeatIdAttribute] != null)
                            {
                                appt.RepeatID = attribs[AppointmentDatabase.RepeatIdAttribute].Value;
                            }

                            DateTime d = now.Add((allday ? TimeSpan.Zero : start.TimeOfDay) - reminder);

                            bool add = false;

                            if (appt.OccursOnDate(d))
                            {
                                add = true;
                                appt.RepresentingDate = d.Date;
                            }
                            else if (appt.OccursOnDate(d.AddDays(1)))
                            {
                                add = true;
                                appt.RepresentingDate = d.AddDays(1).Date;
                            }

                            if (add)
                            {
                                // Check to see if there is another event on this date.
                                Appointment[] events = AppointmentDatabase.GetAppointments(appt.RepresentingDate, false);

                                if (events != null)
                                {
                                    foreach (Appointment each in events)
                                    {
                                        if (each.RepeatID == appt.ID)
                                        {
                                            each.RepresentingDate = appt.RepresentingDate;
                                            appt = each;
                                            break;
                                        }
                                    }
                                }

                                if (appt.Reminder == TimeSpan.FromSeconds(-1))
                                {
                                    continue;
                                }

                                Reminder r = new Reminder();
                                r.ReminderType   = ReminderType.Appointment;
                                r.ID             = appt.ID;
                                r.EventStartDate = appt.RepresentingDate.Add(appt.StartDate.TimeOfDay);
                                r.EventEndDate   = appt.RepresentingDate.Add(appt.EndDate - appt.StartDate);
                                r.AlertStartTime = appt.AllDay ? appt.RepresentingDate.Subtract(appt.Reminder) : appt.RepresentingDate.Add(appt.StartDate.TimeOfDay).Subtract(appt.Reminder);

                                // TODO: 11Mar2014 Check to make sure this works.
                                r.AlertEndTime          = appt.AllDay ? appt.RepresentingDate.AddDays(1) : appt.RepresentingDate.Add(appt.EndDate.TimeOfDay);
                                reminders[actualsize++] = r;
                            }
                        }
                    }
                }

                // Trim array to size.
                Array.Resize(ref reminders, actualsize);

                return(reminders);
            }

            return(new Reminder[0]);
        }