Index: trunk/hiptop/pester/net/sabi/pester/Alarm.java
===================================================================
--- trunk/hiptop/pester/net/sabi/pester/Alarm.java	(revision 242)
+++ trunk/hiptop/pester/net/sabi/pester/Alarm.java	(revision 243)
@@ -7,7 +7,10 @@
 import danger.app.Application;
 import danger.internal.Date;
+import danger.util.LocaleUtils;
 import danger.util.StdActiveList;
 import danger.util.StdActiveObject;
 import danger.util.DEBUG;
+import danger.util.format.DateFormat;
+import danger.util.format.StringFormat;
 
 public class Alarm extends StdActiveObject {
@@ -51,6 +54,4 @@
 	mType = repeating ? TYPE_PERIODIC_REPEATING : TYPE_PERIODIC;
 	mPeriod = period;
-	mDate = new Date();
-	mDate.addSeconds(period);
     }
     public void setDate(Date date) {
@@ -99,4 +100,21 @@
     }
 
+    void resume() {
+	mState = STATE_SCHEDULED;
+	int period = mDate.getDangerTimeGMT() - new Date().getDangerTimeGMT();
+	if (period < 0) period = 0;
+	mAlarm.resetWake(period);
+	DEBUG.p("resetWake: " + description() + " - " + period + "s left");
+	update();
+    }
+
+    void schedule() {
+	if (getUsesPeriod()) {
+	    mDate = new Date();
+	    mDate.addSeconds(mPeriod);
+	}
+	resume();
+    }
+
     void dismiss() {
 	if (getRepeating())
@@ -111,18 +129,40 @@
     }
 
-    void schedule() {
-	mState = STATE_SCHEDULED;
-	DEBUG.p("schedule alarm: " + mMessage);
+    public String description() {
+	StringBuffer sb = new StringBuffer();
+	switch (mState) {
+	case STATE_INVALID: sb.append("invalid "); break;
+	case STATE_EDITING: sb.append("editing "); break;
+	case STATE_SCHEDULED: sb.append("scheduled "); break;
+	}
 	switch (mType) {
 	case TYPE_PERIODIC:
-	    DEBUG.p(" - periodic: " + mPeriod); break;
+	    sb.append("periodic (").append(mPeriod).append("s) "); break;
 	case TYPE_PERIODIC_REPEATING:
-	    DEBUG.p(" - periodic repeating: " + mPeriod); break;
+	    sb.append("repeating periodic (").append(mPeriod).append("s) ");
+	    break;
 	case TYPE_DATE:
-	    DEBUG.p(" - date: " + mDate); break;
+	    sb.append("date (").append(getDateTimeString()).append(") "); break;
 	}
-	mAlarm.resetWake(mPeriod);
+	sb.append("alarm: ");
+	sb.append('"').append(mMessage).append('"');
+	return sb.toString();
     }
-    
+
+    protected static String dateTimeString(Date date) {
+	if (date == null)
+	    return null;
+	String layout = LocaleUtils.getDateTimePattern();
+	String timeFormat = LocaleUtils.getMediumTimeFormat();
+	String dateFormat = LocaleUtils.getShortDateFormat();
+	return StringFormat.withFormat(layout,
+				       DateFormat.withFormat(timeFormat, date),
+				       DateFormat.withFormat(dateFormat, date));
+    }
+
+    public String getDateTimeString() {
+	return dateTimeString(mDate);
+    }
+   
     public String toString() {
 	return mMessage;
Index: trunk/hiptop/pester/net/sabi/pester/AlarmListView.java
===================================================================
--- trunk/hiptop/pester/net/sabi/pester/AlarmListView.java	(revision 242)
+++ trunk/hiptop/pester/net/sabi/pester/AlarmListView.java	(revision 243)
@@ -124,4 +124,5 @@
 	Date date = sDateEditor.getDate();
 	date.setTime(sTimeEditor.getDate().getTime());
+	date.setSeconds(0);
 	return date;
     }
@@ -153,14 +154,15 @@
 		sEditingAlarm.setDate(editingDate());
 	    }
+	    // schedule before adding so the tooltip is correct
+	    sEditingAlarm.schedule();
 	    if (sEditingAlarm != sFocusedAlarm) { // new alarm
 		sAlarmList.addItem(sEditingAlarm);
 		setFocusedItem(sEditingAlarm);
 		sFocusedAlarm = sEditingAlarm;
-	    } else {
-		sEditingAlarm.update();
-	    }
+	    }
+	    return true;
 	case EVENT_CANCEL_ALARM:
-	    if (sEditingAlarm == sFocusedAlarm)
-		sEditingAlarm.schedule();
+	    if (sEditingAlarm == sFocusedAlarm) // existing alarm
+		sEditingAlarm.resume();
 	    sEditingAlarm = null;
 	    return true;
@@ -200,5 +202,4 @@
 
     protected void itemActivated(Object item) {
-	// XXX deschedule alarm
 	editAlarm(sFocusedAlarm, false);
     }
@@ -223,6 +224,6 @@
 	if (item == null) // this is dumb, why do we get asked for a tooltip?
 	    return null;
-	// XXX only set a tooltip if the message is truncated
-	return ((Alarm)item).getMessage();
+	// XXX need "in XXX minutes" too
+	return ((Alarm)item).getDateTimeString();
     }
 }
Index: trunk/hiptop/pester/net/sabi/pester/Pester.java
===================================================================
--- trunk/hiptop/pester/net/sabi/pester/Pester.java	(revision 242)
+++ trunk/hiptop/pester/net/sabi/pester/Pester.java	(revision 243)
@@ -23,4 +23,5 @@
 	    Alarm alarm = (Alarm)e.argument;
 	    AlertWindow alert = getAlert(ID_ALARM_ALERT, this);
+	    alert.setTitle(alert.getTitle() + ": " + alarm.getDateTimeString());
 	    alert.setMessage(alarm.getMessage());
 	    // alert.setMessageFormatDate(alarm.getDate());
