RhinoReminds/RhinoReminds/ReminderList.cs

118 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using S22.Xmpp;
namespace RhinoReminds
{
public class ReminderListUpdateEventArgs : EventArgs { }
public delegate void OnReminderListUpdateHandler(object sender, ReminderListUpdateEventArgs newReminder);
public class ReminderList
{
private int nextId = 0;
private readonly object saveLock = new object();
public SortedSet<Reminder> Reminders = new SortedSet<Reminder>(new CompareReminders());
public event OnReminderListUpdateHandler OnReminderListUpdate;
public ReminderList()
{
}
public Reminder CreateReminder(Jid inJid, DateTime time, string message)
{
Reminder result = new Reminder(nextId++, $"{inJid.Node}@{inJid.Domain}", time, message);
Console.WriteLine($"[Rhino/ReminderList] Created reminder {result}");
while (Reminders.Contains(result))
result.TweakTime();
Reminders.Add(result);
OnReminderListUpdate(this, new ReminderListUpdateEventArgs());
return result;
}
public Reminder GetNextReminder() {
if (Reminders.Count == 0)
return null;
return Reminders.Min;
}
public Reminder GetById(int targetId) {
return Reminders.First((Reminder nextReminder) => nextReminder.Id == targetId);
}
public void DeleteReminder(Reminder nextReminder) {
if (!Reminders.Remove(nextReminder))
throw new ApplicationException($"Error: Failed to remove the reminder {nextReminder} from the list!");
OnReminderListUpdate(this, new ReminderListUpdateEventArgs());
}
#region Persistence
public void Save(string filename)
{
// Make sure that the reminder thread doesn't try to save the reminders at the exact same time
// we receive a request for a new reminder
lock (saveLock)
{ // FUTURE: We could go lockless here with some work, but it's not worth it for the teensy chance & low overhead
XmlWriter xml = XmlWriter.Create(
filename,
new XmlWriterSettings() { Indent = true }
);
xml.WriteStartDocument();
xml.WriteStartElement("ReminderList");
xml.WriteElementString("NextId", nextId.ToString());
xml.WriteStartElement("Reminders");
foreach (Reminder nextReminder in Reminders)
nextReminder.WriteToXml(xml);
xml.WriteEndElement();
xml.WriteEndElement();
xml.WriteEndDocument();
xml.Close();
}
}
public static ReminderList FromXmlFile(string filepath)
{
XmlDocument xml = new XmlDocument();
xml.Load(filepath);
ReminderList result = new ReminderList() {
nextId = int.Parse(xml.GetElementsByTagName("NextId")[0].InnerText)
};
foreach (XmlNode reminderXML in xml.GetElementsByTagName("Reminders")[0].ChildNodes) {
Reminder nextReminder = Reminder.FromXml(reminderXML);
while (result.Reminders.Contains(nextReminder))
nextReminder.TweakTime();
result.Reminders.Add(nextReminder);
}
return result;
}
#endregion
public override string ToString()
{
string result = "Reminder list:";
foreach (Reminder nextReminder in Reminders)
Console.WriteLine($" - {nextReminder}");
return result;
}
}
}