]> err.no Git - sope/blob - sope-ical/NGiCal/iCalDailyRecurrenceCalculator.m
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1201 e4a50df8-12e2-0310-a44c...
[sope] / sope-ical / NGiCal / iCalDailyRecurrenceCalculator.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 #include "iCalRecurrenceCalculator.h"
23
24 @interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator
25 @end
26
27 #include <NGExtensions/NGCalendarDateRange.h>
28 #include "iCalRecurrenceRule.h"
29 #include "NSCalendarDate+ICal.h"
30 #include "common.h"
31
32 @interface iCalRecurrenceCalculator(PrivateAPI)
33 - (NSCalendarDate *)lastInstanceStartDate;
34 @end
35
36 @implementation iCalDailyRecurrenceCalculator
37
38 - (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r{
39   NSMutableArray *ranges;
40   NSCalendarDate *firStart;
41   long           i, jnFirst, jnStart, jnEnd, startEndCount;
42   unsigned       interval;
43
44   firStart = [self->firstRange startDate];
45   jnFirst  = [firStart julianNumber];
46   jnEnd    = [[_r endDate] julianNumber];
47   
48   if (jnFirst > jnEnd)
49     return nil;
50   
51   jnStart  = [[_r startDate] julianNumber];
52   interval = [self->rrule repeatInterval];
53   
54   /* if rule is bound, check the bounds */
55   if (![self->rrule isInfinite]) {
56     NSCalendarDate *until;
57     long           jnRuleLast;
58     
59     until = [self->rrule untilDate];
60     if (until) {
61       if ([until compare:[_r startDate]] == NSOrderedAscending)
62         return nil;
63       jnRuleLast = [until julianNumber];
64     }
65     else {
66       jnRuleLast = (interval * [self->rrule repeatCount])
67       + jnFirst;
68       if (jnRuleLast < jnStart)
69         return nil;
70     }
71     /* jnStart < jnRuleLast < jnEnd ? */
72     if (jnEnd > jnRuleLast)
73       jnEnd = jnRuleLast;
74   }
75
76   startEndCount = (jnEnd - jnStart) + 1;
77   ranges        = [NSMutableArray arrayWithCapacity:startEndCount];
78   for (i = 0 ; i < startEndCount; i++) {
79     long jnCurrent;
80     
81     jnCurrent = jnStart + i;
82     if (jnCurrent >= jnFirst) {
83       long jnTest;
84       
85       jnTest = jnCurrent - jnFirst;
86       if ((jnTest % interval) == 0) {
87         NSCalendarDate      *start, *end;
88         NGCalendarDateRange *r;
89       
90         start = [NSCalendarDate dateForJulianNumber:jnCurrent];
91         [start setTimeZone:[firStart timeZone]];
92         start = [start hour:  [firStart hourOfDay]
93                        minute:[firStart minuteOfHour]
94                        second:[firStart secondOfMinute]];
95         end   = [start addTimeInterval:[self->firstRange duration]];
96         r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
97                                      endDate:end];
98         if ([_r containsDateRange:r])
99           [ranges addObject:r];
100       }
101     }
102   }
103   return ranges;
104 }
105
106 - (NSCalendarDate *)lastInstanceStartDate {
107   if ([self->rrule repeatCount] > 0) {
108     long           jnFirst, jnRuleLast;
109     NSCalendarDate *firStart, *until;
110
111     firStart   = [self->firstRange startDate];
112     jnFirst    = [firStart julianNumber];
113     jnRuleLast = ([self->rrule repeatInterval] *
114                   [self->rrule repeatCount]) +
115                   jnFirst;
116     until      = [NSCalendarDate dateForJulianNumber:jnRuleLast];
117     until      = [until hour:  [firStart hourOfDay]
118                         minute:[firStart minuteOfHour]
119                         second:[firStart secondOfMinute]];
120     return until;
121   }
122   return [super lastInstanceStartDate];
123 }
124
125 @end /* iCalDailyRecurrenceCalculator */