source: trunk/Cocoa/Pester/Source/PSAlarm.m @ 26

Last change on this file since 26 was 26, checked in by Nicholas Riley, 18 years ago

Pester 1.0b1

File size: 7.3 KB
Line 
1//
2//  PSAlarm.m
3//  Pester
4//
5//  Created by Nicholas Riley on Wed Oct 09 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSAlarm.h"
10
11NSString * const PSAlarmTimerSetNotification = @"PSAlarmTimerSetNotification";
12NSString * const PSAlarmTimerExpiredNotification = @"PSAlarmTimerExpiredNotification";
13
14@implementation PSAlarm
15
16- (void)dealloc;
17{
18    // NSLog(@"DEALLOC %@", self);
19    alarmType = PSAlarmInvalid;
20    [alarmDate release]; alarmDate = nil;
21    [alarmMessage release]; alarmMessage = nil;
22    [invalidMessage release]; invalidMessage = nil;
23    [timer release]; timer = nil;
24    [super dealloc];
25}
26
27- (void)_setAlarmDate:(NSCalendarDate *)aDate;
28{
29    if (alarmDate != aDate) {
30        [alarmDate release];
31        alarmDate = nil;
32        alarmDate = [aDate retain];
33    }
34}
35
36- (void)_invalidate:(NSString *)aMessage;
37{
38    alarmType = PSAlarmInvalid;
39    if (aMessage != invalidMessage) {
40        [invalidMessage release];
41        invalidMessage = nil;
42        [self _setAlarmDate: nil];
43        alarmInterval = 0;
44        invalidMessage = [aMessage retain];
45    }
46}
47
48- (void)_validateForType:(PSAlarmType)type;
49{
50    [invalidMessage release];
51    invalidMessage = nil;
52    alarmType = type;
53}
54
55- (void)_setDateFromInterval;
56{
57    [alarmDate release]; alarmDate = nil;
58    alarmDate = [NSCalendarDate dateWithTimeIntervalSinceNow: alarmInterval];
59    [alarmDate retain];
60    [self _validateForType: PSAlarmInterval];
61}
62
63- (void)setInterval:(NSTimeInterval)anInterval;
64{
65    alarmInterval = anInterval;
66    if (alarmInterval <= 0) {
67        [self _invalidate: @"Please specify an alarm interval."]; return;
68    }
69    [self _setDateFromInterval];
70}
71
72- (void)_setIntervalFromDate;
73{
74    alarmInterval = [alarmDate timeIntervalSinceNow];
75    if (alarmInterval <= 0) {
76        [self _invalidate: @"Please specify an alarm time in the future."];
77        return;
78    }
79    [self _validateForType: PSAlarmDate];
80}
81
82- (void)setForDateAtTime:(NSCalendarDate *)dateTime;
83{
84    [self _setAlarmDate: dateTime];
85    [self _setIntervalFromDate];
86}
87
88- (void)setForDate:(NSDate *)date atTime:(NSDate *)time;
89{
90    NSCalendarDate *calTime, *calDate;
91    if (time == nil && date == nil) {
92        [self _invalidate: @"Please specify an alarm date and time."]; return;
93    }
94    if (time == nil) {
95        [self _invalidate: @"Please specify an alarm time."]; return;
96    }
97    if (date == nil) {
98        [self _invalidate: @"Please specify an alarm date."]; return;
99    }
100    // XXX if calTime's date is different from the default date, complain
101    calTime = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [time timeIntervalSinceReferenceDate]];
102    calDate = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [date timeIntervalSinceReferenceDate]];
103    if (calTime == nil || calDate == nil) {
104        [self _invalidate: @"Please specify a reasonable date and time."];
105    }
106    [self setForDateAtTime:
107        [[[NSCalendarDate alloc] initWithYear: [calDate yearOfCommonEra]
108                                        month: [calDate monthOfYear]
109                                          day: [calDate dayOfMonth]
110                                         hour: [calTime hourOfDay]
111                                       minute: [calTime minuteOfHour]
112                                       second: [calTime secondOfMinute]
113                                     timeZone: nil] autorelease]];
114}
115
116- (BOOL)isValid;
117{
118    if (alarmType == PSAlarmDate) [self _setIntervalFromDate];
119    return (alarmType != PSAlarmInvalid);
120}
121
122- (void)setMessage:(NSString *)aMessage;
123{
124    if (aMessage != alarmMessage) {
125        [alarmMessage release];
126        alarmMessage = nil;
127        alarmMessage = [aMessage retain];
128    }
129}
130
131- (NSString *)message;
132{
133    if (alarmMessage == nil || [alarmMessage isEqualToString: @""])
134        return @"Alarm!";
135    return alarmMessage;   
136}
137
138- (NSString *)invalidMessage;
139{
140    if (invalidMessage == nil) return @"";
141    return invalidMessage;
142}
143
144- (NSDate *)date;
145{
146    if (alarmType == PSAlarmInterval) [self _setDateFromInterval];
147    return alarmDate;
148}
149
150- (NSTimeInterval)interval;
151{
152    if (alarmType == PSAlarmSet) return [timer timeInterval]; // XXX counts down?
153    if (alarmType == PSAlarmDate) [self _setIntervalFromDate];
154    return alarmInterval;
155}
156
157- (BOOL)setTimer;
158{
159    switch (alarmType) {
160        case PSAlarmDate: if (![self isValid]) return NO;
161        case PSAlarmInterval:
162            timer = [NSTimer scheduledTimerWithTimeInterval: alarmInterval
163                                                     target: self
164                                                   selector: @selector(_timerExpired:)
165                                                   userInfo: nil
166                                                    repeats: NO];
167            if (timer != nil) {
168                alarmType = PSAlarmSet;
169                [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmTimerSetNotification object: self];
170                return YES;
171            }
172        default:
173            return NO;
174    }
175}
176
177- (void)cancel;
178{
179    [timer release]; timer = nil;
180}
181
182- (void)_timerExpired:(NSTimer *)aTimer;
183{
184    [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmTimerExpiredNotification object: self];
185    timer = nil;
186    [timer release];
187}
188
189- (NSString *)_alarmTypeString;
190{
191    switch (alarmType) {
192        case PSAlarmDate: return @"PSAlarmDate";
193        case PSAlarmInterval: return @"PSAlarmInterval";
194        case PSAlarmSet: return @"PSAlarmSet";
195        case PSAlarmInvalid: return @"PSAlarmInvalid";
196        default: return [NSString stringWithFormat: @"<unknown: %u>", alarmType];
197    }
198}
199
200- (NSComparisonResult)compare:(PSAlarm *)otherAlarm;
201{
202    return [[self date] compare: [otherAlarm date]];
203}
204
205- (NSString *)description;
206{
207    return [NSString stringWithFormat: @"%@: type %@ date %@ interval %.1f%@",
208        [super description], [self _alarmTypeString], alarmDate, alarmInterval,
209        (alarmType == PSAlarmInvalid ?
210         [NSString stringWithFormat: @"\ninvalid message: %@", invalidMessage]
211        : (alarmType == PSAlarmSet ?
212           [NSString stringWithFormat: @"\ntimer: %@", timer] : @""))];
213}
214
215- (void)encodeWithCoder:(NSCoder *)coder;
216{
217    if (![self isValid]) return;
218    [coder encodeValueOfObjCType: @encode(PSAlarmType) at: &alarmType];
219    switch (alarmType) {
220        case PSAlarmDate:
221        case PSAlarmSet:
222            [coder encodeObject: alarmDate];
223            break;
224        case PSAlarmInterval:
225            [coder encodeValueOfObjCType: @encode(NSTimeInterval) at: &alarmInterval];
226            break;
227        default:
228            break;
229    }
230    [coder encodeObject: alarmMessage];
231    return;
232}
233
234- (id)initWithCoder:(NSCoder *)coder;
235{
236    if ( (self = [super init]) != nil) {
237        [coder decodeValueOfObjCType: @encode(PSAlarmType) at: &alarmType];
238        switch (alarmType) {
239            case PSAlarmDate:
240            case PSAlarmSet:
241                [self _setAlarmDate: [coder decodeObject]];
242                break;
243            case PSAlarmInterval:
244                [coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &alarmInterval];
245                break;
246            default:
247                break;
248        }
249        [self setMessage: [coder decodeObject]];
250        if (alarmType == PSAlarmSet) {
251            alarmType = PSAlarmDate;
252            [self setTimer];
253        }
254    }
255    return self;
256}
257
258@end
Note: See TracBrowser for help on using the repository browser.