]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/iCalRepeatableEntityObject.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1178 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SOPE / NGCards / iCalRepeatableEntityObject.m
1 /*
2   Copyright (C) 2004-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #import <Foundation/NSArray.h>
23 #import <Foundation/NSCalendarDate.h>
24 #import <Foundation/NSEnumerator.h>
25 #import <Foundation/NSString.h>
26
27 #import <NGExtensions/NGCalendarDateRange.h>
28
29 #import "iCalRecurrenceRule.h"
30 #import "iCalRecurrenceCalculator.h"
31 #import "iCalRepeatableEntityObject.h"
32
33 @implementation iCalRepeatableEntityObject
34
35 - (Class) classForTag: (NSString *) classTag
36 {
37   Class tagClass;
38
39   if ([classTag isEqualToString: @"RRULE"])
40     tagClass = [iCalRecurrenceRule class];
41   else
42     tagClass = [super classForTag: classTag];
43
44   return tagClass;
45 }
46
47 /* Accessors */
48
49 - (void) removeAllRecurrenceRules
50 {
51   [children removeObjectsInArray: [self childrenWithTag: @"rrule"]];
52 }
53
54 - (void) addToRecurrenceRules: (id) _rrule
55 {
56   [self addChild: _rrule];
57 }
58
59 - (void) setRecurrenceRules: (NSArray *) _rrules
60 {
61   [children removeObjectsInArray: [self childrenWithTag: @"rrule"]];
62   [self addChildren: _rrules];
63 }
64
65 - (BOOL) hasRecurrenceRules
66 {
67   return ([[self childrenWithTag: @"rrule"] count] > 0);
68 }
69
70 - (NSArray *) recurrenceRules
71 {
72   return [self childrenWithTag: @"rrule"];
73 }
74
75 - (void) removeAllExceptionRules
76 {
77   [children removeObjectsInArray: [self childrenWithTag: @"exrule"]];
78 }
79
80 - (void) addToExceptionRules: (id) _rrule
81 {
82   [self addChild: _rrule];
83 }
84
85 - (void) setExceptionRules: (NSArray *) _rrules
86 {
87   [children removeObjectsInArray: [self childrenWithTag: @"exrule"]];
88   [self addChildren: _rrules];
89 }
90
91 - (BOOL) hasExceptionRules
92 {
93   return ([[self childrenWithTag: @"exrule"] count] > 0);
94 }
95
96 - (NSArray *) exceptionRules
97 {
98   return [self childrenWithTag: @"exrule"];
99 }
100
101 - (void) removeAllExceptionDates
102 {
103   [children removeObjectsInArray: [self childrenWithTag: @"exdate"]];
104 }
105
106 - (void) addToExceptionDates: (id) _rdate
107 {
108   [self addChild: _rdate];
109 }
110
111 - (void) setExceptionDates: (NSArray *) _rdates
112 {
113   [children removeObjectsInArray: [self childrenWithTag: @"exdate"]];
114   [self addChildren: _rdates];
115 }
116
117 - (BOOL) hasExceptionDates
118 {
119   return ([[self childrenWithTag: @"exdate"] count] > 0);
120 }
121
122 - (NSArray *) exceptionDates
123 {
124   return [self childrenWithTag: @"exdate"];
125 }
126
127 /* Convenience */
128
129 - (BOOL) isRecurrent
130 {
131   return [self hasRecurrenceRules];
132 }
133
134 /* Matching */
135
136 - (BOOL) isWithinCalendarDateRange: (NGCalendarDateRange *) _range
137     firstInstanceCalendarDateRange: (NGCalendarDateRange *) _fir
138 {
139   NSArray *ranges;
140   
141   ranges = [self recurrenceRangesWithinCalendarDateRange:_range
142                  firstInstanceCalendarDateRange:_fir];
143   return [ranges count] > 0;
144 }
145
146 - (NSArray *) recurrenceRangesWithinCalendarDateRange: (NGCalendarDateRange *)_r
147                        firstInstanceCalendarDateRange: (NGCalendarDateRange *)_fir
148 {
149   return [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: _r
150                                    firstInstanceCalendarDateRange: _fir
151                                    recurrenceRules: [self recurrenceRules]
152                                    exceptionRules: [self exceptionRules]
153                                    exceptionDates: [self exceptionDates]];
154 }
155
156
157 /* this is the outmost bound possible, not necessarily the real last date */
158 -    (NSCalendarDate *)
159 lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange: (NGCalendarDateRange *)_r
160 {
161   NSCalendarDate *date;
162   NSEnumerator *rRules;
163   iCalRecurrenceRule *rule;
164   iCalRecurrenceCalculator *calc;
165   NSCalendarDate *rdate;
166
167   date  = nil;
168
169   rRules = [[self recurrenceRules] objectEnumerator];
170   rule = [rRules nextObject];
171   while (rule && ![rule isInfinite] & !date)
172     {
173       calc = [iCalRecurrenceCalculator
174                recurrenceCalculatorForRecurrenceRule: rule
175                withFirstInstanceCalendarDateRange: _r];
176       rdate = [[calc lastInstanceCalendarDateRange] startDate];
177       if (!date
178           || ([date compare: rdate] == NSOrderedAscending))
179         date = rdate;
180       else
181         rule = [rRules nextObject];
182     }
183
184   return date;
185 }
186
187 @end