]> err.no Git - sope/blobdiff - sope-ical/NGiCal/iCalRecurrenceCalculator.m
moved cluster subclasses to own files
[sope] / sope-ical / NGiCal / iCalRecurrenceCalculator.m
index b141038b9421c89f7b9caa2f9aa3e156f9043891..9d2febd729be97dc54fb69c474ddc40add207943 100644 (file)
@@ -1,22 +1,22 @@
 /*
- Copyright (C) 2004-2005 SKYRIX Software AG
- This file is part of SOPE.
- SOPE is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
- SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with SOPE; see the file COPYING.  If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
 Copyright (C) 2004-2005 SKYRIX Software AG
+  
 This file is part of SOPE.
+  
 SOPE is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the
 Free Software Foundation; either version 2, or (at your option) any
 later version.
+  
 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.
+  
 You should have received a copy of the GNU Lesser General Public
 License along with SOPE; see the file COPYING.  If not, write to the
 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.
 */
 
 #include "iCalRecurrenceCalculator.h"
 
 /* class cluster */
 
-@interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator
-{
-}
-@end
-
-@interface iCalWeeklyRecurrenceCalculator : iCalRecurrenceCalculator
-{
-}
-@end
-
-@interface iCalMonthlyRecurrenceCalculator : iCalRecurrenceCalculator
-{
-}
-@end
-
-@interface iCalYearlyRecurrenceCalculator : iCalRecurrenceCalculator
-{
-}
-@end
 
 /* Private */
 
@@ -77,10 +58,10 @@ static Class yearlyCalcClass  = Nil;
   NSCalendarDateClass     = [NSCalendarDate class];
   iCalRecurrenceRuleClass = [iCalRecurrenceRule class];
 
-  dailyCalcClass   = [iCalDailyRecurrenceCalculator   class];
-  weeklyCalcClass  = [iCalWeeklyRecurrenceCalculator  class];
-  monthlyCalcClass = [iCalMonthlyRecurrenceCalculator class];
-  yearlyCalcClass  = [iCalYearlyRecurrenceCalculator  class];
+  dailyCalcClass   = NSClassFromString(@"iCalDailyRecurrenceCalculator");
+  weeklyCalcClass  = NSClassFromString(@"iCalWeeklyRecurrenceCalculator");
+  monthlyCalcClass = NSClassFromString(@"iCalMonthlyRecurrenceCalculator");
+  yearlyCalcClass  = NSClassFromString(@"iCalYearlyRecurrenceCalculator");
 }
 
 /* factory */
@@ -309,376 +290,3 @@ static Class yearlyCalcClass  = Nil;
 }
 
 @end /* iCalRecurrenceCalculator */
-
-
-@implementation iCalDailyRecurrenceCalculator
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
-  NSMutableArray *ranges;
-  NSCalendarDate *firStart;
-  long           i, jnFirst, jnStart, jnEnd, startEndCount;
-  unsigned       interval;
-
-  firStart = [self->firstRange startDate];
-  jnFirst  = [firStart julianNumber];
-  jnEnd    = [[_r endDate] julianNumber];
-  
-  if (jnFirst > jnEnd)
-    return nil;
-  
-  jnStart  = [[_r startDate] julianNumber];
-  interval = [self->rrule repeatInterval];
-  
-  /* if rule is bound, check the bounds */
-  if (![self->rrule isInfinite]) {
-    NSCalendarDate *until;
-    long           jnRuleLast;
-    
-    until = [self->rrule untilDate];
-    if (until) {
-      if ([until compare:[_r startDate]] == NSOrderedAscending)
-        return nil;
-      jnRuleLast = [until julianNumber];
-    }
-    else {
-      jnRuleLast = (interval * [self->rrule repeatCount])
-      + jnFirst;
-      if (jnRuleLast < jnStart)
-        return nil;
-    }
-    /* jnStart < jnRuleLast < jnEnd ? */
-    if (jnEnd > jnRuleLast)
-      jnEnd = jnRuleLast;
-  }
-
-  startEndCount = (jnEnd - jnStart) + 1;
-  ranges        = [NSMutableArray arrayWithCapacity:startEndCount];
-  for (i = 0 ; i < startEndCount; i++) {
-    long jnCurrent;
-    
-    jnCurrent = jnStart + i;
-    if (jnCurrent >= jnFirst) {
-      long jnTest;
-      
-      jnTest = jnCurrent - jnFirst;
-      if ((jnTest % interval) == 0) {
-        NSCalendarDate      *start, *end;
-        NGCalendarDateRange *r;
-      
-        start = [NSCalendarDate dateForJulianNumber:jnCurrent];
-        [start setTimeZone:[firStart timeZone]];
-        start = [start hour:  [firStart hourOfDay]
-                       minute:[firStart minuteOfHour]
-                       second:[firStart secondOfMinute]];
-        end   = [start addTimeInterval:[self->firstRange duration]];
-        r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
-                                     endDate:end];
-        if ([_r containsDateRange:r])
-          [ranges addObject:r];
-      }
-    }
-  }
-  return ranges;
-}
-
-- (NSCalendarDate *)lastInstanceStartDate {
-  if ([self->rrule repeatCount] > 0) {
-    long           jnFirst, jnRuleLast;
-    NSCalendarDate *firStart, *until;
-
-    firStart   = [self->firstRange startDate];
-    jnFirst    = [firStart julianNumber];
-    jnRuleLast = ([self->rrule repeatInterval] *
-                  [self->rrule repeatCount]) +
-                  jnFirst;
-    until      = [NSCalendarDate dateForJulianNumber:jnRuleLast];
-    until      = [until hour:  [firStart hourOfDay]
-                        minute:[firStart minuteOfHour]
-                        second:[firStart secondOfMinute]];
-    return until;
-  }
-  return [super lastInstanceStartDate];
-}
-
-@end /* iCalDailyRecurrenceCalculator */
-
-
-/*
-   TODO: If BYDAY is specified, lastInstanceStartDate and recurrences will
-         differ significantly!
-*/
-@implementation iCalWeeklyRecurrenceCalculator
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
-  NSMutableArray *ranges;
-  NSCalendarDate *firStart;
-  long           i, jnFirst, jnStart, jnEnd, startEndCount;
-  unsigned       interval, byDayMask;
-
-  firStart = [self->firstRange startDate];
-  jnFirst  = [firStart julianNumber];
-  jnEnd    = [[_r endDate] julianNumber];
-  
-  if (jnFirst > jnEnd)
-    return nil;
-  
-  jnStart  = [[_r startDate] julianNumber];
-  interval = [self->rrule repeatInterval];
-  
-  /* if rule is bound, check the bounds */
-  if (![self->rrule isInfinite]) {
-    NSCalendarDate *until;
-    long           jnRuleLast;
-    
-    until = [self->rrule untilDate];
-    if (until) {
-      if ([until compare:[_r startDate]] == NSOrderedAscending)
-        return nil;
-      jnRuleLast = [until julianNumber];
-    }
-    else {
-      jnRuleLast = (interval * [self->rrule repeatCount] * 7)
-      + jnFirst;
-      if (jnRuleLast < jnStart)
-        return nil;
-    }
-    /* jnStart < jnRuleLast < jnEnd ? */
-    if (jnEnd > jnRuleLast)
-      jnEnd = jnRuleLast;
-  }
-  
-  startEndCount = (jnEnd - jnStart) + 1;
-  ranges        = [NSMutableArray arrayWithCapacity:startEndCount];
-  byDayMask     = [self->rrule byDayMask];
-  if (!byDayMask) {
-    for (i = 0 ; i < startEndCount; i++) {
-      long jnCurrent;
-      
-      jnCurrent = jnStart + i;
-      if (jnCurrent >= jnFirst) {
-        long jnDiff;
-        
-        jnDiff = jnCurrent - jnFirst; /* difference in days */
-        if ((jnDiff % (interval * 7)) == 0) {
-          NSCalendarDate      *start, *end;
-          NGCalendarDateRange *r;
-          
-          start = [NSCalendarDate dateForJulianNumber:jnCurrent];
-          [start setTimeZone:[firStart timeZone]];
-          start = [start hour:  [firStart hourOfDay]
-                         minute:[firStart minuteOfHour]
-                         second:[firStart secondOfMinute]];
-          end   = [start addTimeInterval:[self->firstRange duration]];
-          r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
-                                       endDate:end];
-          if ([_r containsDateRange:r])
-            [ranges addObject:r];
-        }
-      }
-    }
-  }
-  else {
-    long jnFirstWeekStart, weekStartOffset;
-
-    /* calculate jnFirst's week start - this depends on our setting of week
-       start */
-    weekStartOffset = [self offsetFromSundayForJulianNumber:jnFirst] -
-                      [self offsetFromSundayForCurrentWeekStart];
-
-    jnFirstWeekStart = jnFirst - weekStartOffset;
-
-    for (i = 0 ; i < startEndCount; i++) {
-      long jnCurrent;
-
-      jnCurrent = jnStart + i;
-      if (jnCurrent >= jnFirst) {
-        long jnDiff;
-        
-        /* we need to calculate a difference in weeks */
-        jnDiff = (jnCurrent - jnFirstWeekStart) % 7;
-        if ((jnDiff % interval) == 0) {
-          BOOL isRecurrence = NO;
-            
-          if (jnCurrent == jnFirst) {
-            isRecurrence = YES;
-          }
-          else {
-            iCalWeekDay weekDay;
-
-            weekDay = [self weekDayForJulianNumber:jnCurrent];
-            isRecurrence = (weekDay & [self->rrule byDayMask]) ? YES : NO;
-          }
-          if (isRecurrence) {
-            NSCalendarDate      *start, *end;
-            NGCalendarDateRange *r;
-                
-            start = [NSCalendarDate dateForJulianNumber:jnCurrent];
-            [start setTimeZone:[firStart timeZone]];
-            start = [start hour:  [firStart hourOfDay]
-                           minute:[firStart minuteOfHour]
-                           second:[firStart secondOfMinute]];
-            end   = [start addTimeInterval:[self->firstRange duration]];
-            r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
-                                         endDate:end];
-            if ([_r containsDateRange:r])
-              [ranges addObject:r];
-          }
-        }
-      }
-    }
-  }
-  return ranges;
-}
-
-- (NSCalendarDate *)lastInstanceStartDate {
-  if ([self->rrule repeatCount] > 0) {
-    long           jnFirst, jnRuleLast;
-    NSCalendarDate *firStart, *until;
-    
-    firStart   = [self->firstRange startDate];
-    jnFirst    = [firStart julianNumber];
-    jnRuleLast = ([self->rrule repeatInterval] *
-                  [self->rrule repeatCount] * 7) +
-                  jnFirst;
-    until      = [NSCalendarDate dateForJulianNumber:jnRuleLast];
-    until      = [until hour:  [firStart hourOfDay]
-                        minute:[firStart minuteOfHour]
-                        second:[firStart secondOfMinute]];
-    return until;
-  }
-  return [super lastInstanceStartDate];
-}
-
-@end /* iCalWeeklyRecurrenceCalculator */
-
-@implementation iCalMonthlyRecurrenceCalculator
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
-  NSMutableArray *ranges;
-  NSCalendarDate *firStart, *rStart, *rEnd, *until;
-  unsigned       i, count, interval;
-  int            diff;
-
-  firStart = [self->firstRange startDate];
-  rStart   = [_r startDate];
-  rEnd     = [_r endDate];
-  interval = [self->rrule repeatInterval];
-  until    = [self lastInstanceStartDate];
-
-  if (until) {
-    if ([until compare:rStart] == NSOrderedAscending)
-      return nil;
-    if ([until compare:rEnd] == NSOrderedDescending)
-      rEnd = until;
-  }
-
-  diff   = [firStart monthsBetweenDate:rStart];
-  if ((diff != 0) && [rStart compare:firStart] == NSOrderedAscending)
-    diff = -diff;
-
-  count  = [rStart monthsBetweenDate:rEnd] + 1;
-  ranges = [NSMutableArray arrayWithCapacity:count];
-  for (i = 0 ; i < count; i++) {
-    int test;
-    
-    test = diff + i;
-    if ((test >= 0) && (test % interval) == 0) {
-      NSCalendarDate      *start, *end;
-      NGCalendarDateRange *r;
-      
-      start = [firStart dateByAddingYears:0
-                        months:diff + i
-                        days:0];
-      [start setTimeZone:[firStart timeZone]];
-      end   = [start addTimeInterval:[self->firstRange duration]];
-      r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
-                                   endDate:end];
-      if ([_r containsDateRange:r])
-        [ranges addObject:r];
-    }
-  }
-  return ranges;
-}
-
-- (NSCalendarDate *)lastInstanceStartDate {
-  if ([self->rrule repeatCount] > 0) {
-    NSCalendarDate *until;
-    unsigned       months, interval;
-
-    interval = [self->rrule repeatInterval];
-    months   = [self->rrule repeatCount] * interval;
-    until    = [[self->firstRange startDate] dateByAddingYears:0
-                                             months:months
-                                             days:0];
-    return until;
-  }
-  return [super lastInstanceStartDate];
-}
-
-@end /* iCalMonthlyRecurrenceCalculator */
-
-@implementation iCalYearlyRecurrenceCalculator
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
-  NSMutableArray *ranges;
-  NSCalendarDate *firStart, *rStart, *rEnd, *until;
-  unsigned       i, count, interval;
-  int            diff;
-  
-  firStart = [self->firstRange startDate];
-  rStart   = [_r startDate];
-  rEnd     = [_r endDate];
-  interval = [self->rrule repeatInterval];
-  until    = [self lastInstanceStartDate];
-  
-  if (until) {
-    if ([until compare:rStart] == NSOrderedAscending)
-      return nil;
-    if ([until compare:rEnd] == NSOrderedDescending)
-      rEnd = until;
-  }
-  
-  diff   = [firStart yearsBetweenDate:rStart];
-  if ((diff != 0) && [rStart compare:firStart] == NSOrderedAscending)
-    diff = -diff;
-
-  count  = [rStart yearsBetweenDate:rEnd] + 1;
-  ranges = [NSMutableArray arrayWithCapacity:count];
-  for (i = 0 ; i < count; i++) {
-    int test;
-
-    test = diff + i;
-    if ((test >= 0) && (test % interval) == 0) {
-      NSCalendarDate      *start, *end;
-      NGCalendarDateRange *r;
-      
-      start = [firStart dateByAddingYears:diff + i
-                        months:0
-                        days:0];
-      [start setTimeZone:[firStart timeZone]];
-      end   = [start addTimeInterval:[self->firstRange duration]];
-      r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
-                                   endDate:end];
-      if ([_r containsDateRange:r])
-        [ranges addObject:r];
-    }
-  }
-  return ranges;
-}
-
-- (NSCalendarDate *)lastInstanceStartDate {
-  if ([self->rrule repeatCount] > 0) {
-    NSCalendarDate *until;
-    unsigned       years, interval;
-    
-    interval = [self->rrule repeatInterval];
-    years    = [self->rrule repeatCount] * interval;
-    until    = [[self->firstRange startDate] dateByAddingYears:years
-                                             months:0
-                                             days:0];
-    return until;
-  }
-  return [super lastInstanceStartDate];
-}
-
-@end /* iCalYearlyRecurrenceCalculator */