Index: trunk/Cocoa/Pester/Source/PSAlarmSetController.m
===================================================================
--- trunk/Cocoa/Pester/Source/PSAlarmSetController.m	(revision 61)
+++ trunk/Cocoa/Pester/Source/PSAlarmSetController.m	(revision 102)
@@ -9,5 +9,7 @@
 #import "PSAlarmSetController.h"
 #import "PSAlarmAlertController.h"
+#import "PSCalendarController.h"
 #import "PSPowerManager.h"
+#import "PSTimeDateEditor.h"
 #import "NJRDateFormatter.h"
 #import "NJRFSObjectSelector.h"
@@ -71,31 +73,5 @@
     alarm = [[PSAlarm alloc] init];
     [[self window] center];
-    // XXX excessive retention of formatters?  check later...
-    [timeOfDay setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [NJRDateFormatter localizedTimeFormatIncludingSeconds: NO] allowNaturalLanguage: YES]];
-    [timeDate setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [NJRDateFormatter localizedDateFormatIncludingWeekday: NO] allowNaturalLanguage: YES]];
-    {
-        NSArray *dayNames = [defaults arrayForKey:
-            NSWeekDayNameArray];
-        NSArray *completions = [timeDateCompletions itemTitles];
-        NSEnumerator *e = [completions objectEnumerator];
-        NSString *title;
-        int itemIndex = 0;
-        NSRange matchingRange;
-        while ( (title = [e nextObject]) != nil) {
-            matchingRange = [title rangeOfString: @"ÇdayÈ"];
-            if (matchingRange.location != NSNotFound) {
-                NSMutableString *format = [title mutableCopy];
-                NSEnumerator *we = [dayNames objectEnumerator];
-                NSString *dayName;
-                [format deleteCharactersInRange: matchingRange];
-                [format insertString: @"%@" atIndex: matchingRange.location];
-                [timeDateCompletions removeItemAtIndex: itemIndex];
-                while ( (dayName = [we nextObject]) != nil) {
-                    [timeDateCompletions insertItemWithTitle: [NSString stringWithFormat: format, dayName] atIndex: itemIndex];
-                    itemIndex++;
-                }
-            } else itemIndex++;
-        }
-    }
+    [PSTimeDateEditor setUpTimeField: timeOfDay dateField: timeDate completions: timeDateCompletions];
     [editAlert setIntValue: [defaults boolForKey: PSAlertsEditing]];
     {
@@ -114,5 +90,4 @@
         [self _readAlerts: alerts];
     }
-    [timeDate setObjectValue: [NSDate date]];
     [self inAtChanged: nil]; // by convention, if sender is nil, we're initializing
     [self playSoundChanged: nil];
@@ -175,6 +150,4 @@
 }
 
-// XXX use OACalendar in popup like Palm Desktop?
-
 - (IBAction)updateDateDisplay:(id)sender;
 {
@@ -226,6 +199,10 @@
     [timeDate setEnabled: !isInterval];
     [timeDateCompletions setEnabled: !isInterval];
+    [timeCalendarButton setEnabled: !isInterval];
     if (sender != nil)
         [[self window] makeFirstResponder: isInterval ? (NSTextField *)timeInterval : timeOfDay];
+    if (!isInterval) { // need to do this every time the controls are enabled
+        [timeOfDay setNextKeyView: timeDate];
+    }
     // NSLog(@"UPDATING FROM inAtChanged");
     [self update: nil];
@@ -238,5 +215,28 @@
 }
 
+#pragma mark calendar
+
+- (IBAction)showCalendar:(NSButton *)sender;
+{
+    [PSCalendarController controllerWithDate: [NSCalendarDate dateForDay: [timeDate objectValue]] delegate: self];
+}
+
+- (void)calendarController:(PSCalendarController *)calendar didSetDate:(NSCalendarDate *)date;
+{
+    [timeDate setObjectValue: date];
+    [self update: self];
+}
+
+- (NSView *)calendarControllerLaunchingView:(PSCalendarController *)controller;
+{
+    return timeCalendarButton;
+}
+
 #pragma mark alert editing
+
+- (IBAction)toggleAlertEditor:(id)sender;
+{
+    [editAlert performClick: self];
+}
 
 - (IBAction)editAlertChanged:(id)sender;
@@ -293,5 +293,4 @@
 }
 
-
 - (IBAction)playSoundChanged:(id)sender;
 {
@@ -459,5 +458,5 @@
     [alarm setMessage: [messageField stringValue]];
     if (![alarm setTimer]) {
-        [self setStatus: [@"Unable to set alarm.  " stringByAppendingString: [alarm invalidMessage]]];
+        [self setStatus: [@"Unable to set alarm. " stringByAppendingString: [alarm invalidMessage]]];
         return;
     }
@@ -475,4 +474,14 @@
 }
 
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+{
+    if ([anItem action] == @selector(toggleAlertEditor:)) {
+        if ([NSApp keyWindow] != [self window])
+            return NO;
+        [(NSMenuItem *)anItem setState: [editAlert intValue] ? NSOnState : NSOffState];
+    }
+    return YES;
+}
+
 @end
 
