- (NSCalendarDate *)lastInstanceStartDate;
@end
+// #define HEAVY_DEBUG 1
+
@implementation iCalMonthlyRecurrenceCalculator
typedef BOOL NGMonthSet[12];
}
}
+#if HEAVY_DEBUG
+static NSString *dowEN[8] = {
+ @"SU", @"MO", @"TU", @"WE", @"TH", @"FR", @"SA", @"SU-"
+};
+#endif
+
static void NGMonthDaySet_fillWithByDayX(NGMonthDaySet *daySet,
unsigned dayMask,
unsigned firstDoWInMonth,
+ unsigned numberOfDaysInMonth,
int occurrence1)
{
// TODO: this is called 'X' because the API doesn't allow for full iCalendar
// functionality. The daymask must be a list of occurence+dow
register unsigned dayInMonth;
- register unsigned dow; /* current day of the week */
+ register int dow; /* current day of the week */
int occurrences[7] = { 0, 0, 0, 0, 0, 0, 0 } ;
NGMonthDaySet_clear(daySet);
- for (dayInMonth = 1, dow = firstDoWInMonth; dayInMonth <= 31; dayInMonth++) {
- // TODO: complete me
+ if (occurrence1 >= 0) {
+ for (dayInMonth = 1, dow = firstDoWInMonth; dayInMonth<=31; dayInMonth++) {
+ // TODO: complete me
+
+ if (dayMask & iCalDoWForNSDoW(dow)) {
+ if (occurrence1 == 0)
+ (*daySet)[dayInMonth] = YES;
+ else { /* occurrence1 > 0 */
+ occurrences[dow] = occurrences[dow] + 1;
+
+ if (occurrences[dow] == occurrence1)
+ (*daySet)[dayInMonth] = YES;
+ }
+ }
+
+ dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1);
+ }
+ }
+ else {
+ int lastDoWInMonthSet;
- if (dayMask & iCalDoWForNSDoW(dow)) {
- if (occurrence1 == 0)
- (*daySet)[dayInMonth] = YES;
- else {
+ /* get the last dow in the set (not necessarily the month!) */
+ for (dayInMonth = 1, dow = firstDoWInMonth;
+ dayInMonth < numberOfDaysInMonth;dayInMonth++)
+ dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1);
+ lastDoWInMonthSet = dow;
+
+#if HEAVY_DEBUG
+ NSLog(@"LAST DOW IN SET: %i / %@",
+ lastDoWInMonthSet, dowEN[lastDoWInMonthSet]);
+#endif
+ /* start at the end of the set */
+ for (dayInMonth = numberOfDaysInMonth, dow = lastDoWInMonthSet;
+ dayInMonth >= 1; dayInMonth--) {
+ // TODO: complete me
+
+#if HEAVY_DEBUG
+ NSLog(@" CHECK day-of-month %02i, "
+ @" dow=%i/%@ (first=%i/%@, last=%i/%@)",
+ dayInMonth,
+ dow, dowEN[dow],
+ firstDoWInMonth, dowEN[firstDoWInMonth],
+ lastDoWInMonthSet, dowEN[lastDoWInMonthSet]
+ );
+#endif
+
+ if (dayMask & iCalDoWForNSDoW(dow)) {
occurrences[dow] = occurrences[dow] + 1;
-
- if (occurrences[dow] == occurrence1)
+#if HEAVY_DEBUG
+ NSLog(@" MATCH %i/%@ count: %i occurences=%i",
+ dow, dowEN[dow], occurrences[dow], occurrence1);
+#endif
+
+ if (occurrences[dow] == -occurrence1) {
+#if HEAVY_DEBUG
+ NSLog(@" COUNT MATCH");
+#endif
(*daySet)[dayInMonth] = YES;
+ }
}
+
+ dow = (dow == 0 /* Sun */) ? 6 /* Sat */ : (dow - 1);
}
-
- dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1);
}
}
NGMonthDaySet_fillWithByDayX(&ruleset,
[self->rrule byDayMask],
firstDoWInMonth,
+ [cursor numberOfDaysInMonth],
[self->rrule byDayOccurence1]);
NGMonthDaySet_copyOrUnion(&monthDays, &ruleset, !didByFill);
didByFill = YES;