/* Matching */
-/* ZNeK: NOTE
- Exception dates give me a headache. I believe the test below is improper,
- we probably really need to calculate all recurrence ranges and then
- test whether exception dates are contained in any of the required ranges
- and remove those which were found.
-*/
- (BOOL)isWithinCalendarDateRange:(NGCalendarDateRange *)_range
firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir
+{
+ NSArray *ranges;
+
+ ranges = [self recurrenceRangesWithinCalendarDateRange:_range
+ firstInstanceCalendarDateRange:_fir];
+ return [ranges count] > 0;
+}
+
+- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r
+ firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir
{
iCalRecurrenceRule *rule;
iCalRecurrenceCalculator *calc;
- BOOL didMatch = NO;
- unsigned i, count;
+ NSMutableArray *ranges;
+ unsigned i, count, rCount;
- count = [self->rRules count];
+ ranges = [NSMutableArray array];
+ count = [self->rRules count];
for (i = 0; i < count; i++) {
+ NSArray *rs;
+
rule = [self->rRules objectAtIndex:i];
calc = [iCalRecurrenceCalculator recurrenceCalculatorForRecurrenceRule:rule
withFirstInstanceCalendarDateRange:_fir];
- if ([calc doesRecurrWithinCalendarDateRange:_range]) {
- didMatch = YES;
- break;
- }
+ rs = [calc recurrenceRangesWithinCalendarDateRange:_r];
+ [ranges addObjectsFromArray:rs];
}
- if (!didMatch)
- return NO;
-
+ if (![ranges count])
+ return nil;
+
/* test if any exceptions do match */
count = [self->exRules count];
for (i = 0; i < count; i++) {
-
+ NSArray *rs;
+
rule = [self->exRules objectAtIndex:i];
calc = [iCalRecurrenceCalculator recurrenceCalculatorForRecurrenceRule:rule
withFirstInstanceCalendarDateRange:_fir];
- if ([calc doesRecurrWithinCalendarDateRange:_range])
- return NO; /* exception does match, so _range is not a candidate */
+ rs = [calc recurrenceRangesWithinCalendarDateRange:_r];
+ [ranges removeObjectsInArray:rs];
}
+ if (![ranges count])
+ return nil;
+
/* exception dates are also possible */
- count = [self->exDates count];
+ rCount = [ranges count];
+ count = [self->exDates count];
for (i = 0; i < count; i++) {
- NSCalendarDate *exDate;
-
+ NSCalendarDate *exDate;
+ NGCalendarDateRange *r;
+ unsigned k;
+
exDate = [self->exDates objectAtIndex:i];
- /* ZNeK: is _this_ correct? */
- if ([exDate isEqualToDate:[_range startDate]])
- return NO;
+ for (k = 0; k < rCount; k++) {
+ r = [ranges objectAtIndex:(rCount - k) - 1];
+ if ([r containsDate:exDate]) {
+ [ranges removeObjectAtIndex:k];
+ }
+ }
}
- return YES;
+ return ranges;
}
+
/* this is the outmost bound possible, not necessarily the real last date */
- (NSCalendarDate *)lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange:(NGCalendarDateRange *)_r
{