package net.sabi.pester; import java.util.Comparator; import danger.app.Application; import danger.app.DataStore; import danger.app.Event; import danger.app.SettingsDB; import danger.app.SettingsDBException; import danger.internal.Date; import danger.util.StdActiveList; import danger.util.DEBUG; public class Alarms extends StdActiveList { // max # records in a datastore private static final int MAX_ALARM_COUNT = 50; private static Alarms sAlarmList = null; private static Listener sListener; private static SettingsDB sSettingsDB; private DataStore mDataStore; private Alarms() { mDataStore = DataStore.createDataStore("alarms", true /* auto sync */); byte[][] alarmsData = mDataStore.getRecords(); int i; for (i = 0 ; i < alarmsData.length ; ++i) { Alarm alarm = new Alarm(); alarm.fromByteArray(alarmsData[i]); alarm.setUID(mDataStore.getRecordUID(i)); insertItemSorted(alarm, alarm); alarm.resume(); } } public static Alarms getList() { if (sAlarmList == null) { Application.registerForEvent(sListener, Event.EVENT_TIME_CHANGED); sSettingsDB = new SettingsDB("settings", true /* auto sync */); sListener = new Listener(); sAlarmList = new Alarms(); } return sAlarmList; } public static void addAlarm(Alarm alarm) { sAlarmList.insertItemSorted(alarm, alarm); } public static void removeAlarm(Alarm alarm) { sAlarmList.removeItem(alarm); } // XXX handle EVENT_DATASTORE_RESTORED: note that in the event of // a hard reset, items may come back out of order, so we need to // implement an in-place sort, then insert the current alarm list. // Aiee. Also, what on earth happens when UIDs aren't synchronized? protected void onItemAdded(Object item, int index) { if (sAlarmList == null) // restoring from service return; Alarm alarm = (Alarm)item; DEBUG.p("adding: " + alarm + " next UID: " + mDataStore.getAutoSyncNextUID()); index = mDataStore.addRecord(alarm.toByteArray(), index); alarm.setUID(mDataStore.getRecordUID(index)); DEBUG.p("added UID " + alarm.getUID() + " @ " + index); } protected void onItemRemoved(Object item, int index) { Alarm alarm = (Alarm)item; // XXX make sure +/- UIDs are OK int uid = alarm.getUID(); if (uid == 0) return; DEBUG.p("removing; " + alarm + " UID " + uid); mDataStore.removeRecordByUID(uid); } public void onItemUpdated(Object item, int index) { if (sAlarmList == null) // restoring from service return; Alarm alarm = (Alarm)item; // XXX check that updating a + UID by a - one is OK mDataStore.setRecordDataByUID(alarm.getUID(), alarm.toByteArray(), true); DEBUG.p("updated: " + alarm + " UID " + alarm.getUID()); } private static String KEY_DEFAULT_ALARM = "default alarm"; public static Alarm getDefaultAlarm() { Alarm defaultAlarm = new Alarm(); try { defaultAlarm.fromByteArray(sSettingsDB.getBytes(KEY_DEFAULT_ALARM)); } catch (SettingsDBException e) { defaultAlarm = new Alarm(); defaultAlarm.setDate(new Date()); defaultAlarm.setPeriod(600, false); } return defaultAlarm; } public static void setDefaultAlarm(Alarm alarm) { sSettingsDB.setBytes(KEY_DEFAULT_ALARM, alarm.toByteArray()); } static class Listener extends danger.app.Listener implements danger.util.ActiveList.ForEach { public void receive(Object item) { ((Alarm)item).timeChanged(); } public boolean receiveEvent(Event e) { if (e.type == Event.EVENT_TIME_CHANGED) { Alarms.getList().forEach(this); return true; } return super.receiveEvent(e); } } }