calculate method

void calculate()

Calculates the displayable event placements and overflow counts for the week.

Implementation

void calculate() {
  rows.clear();
  _calculatedOverflowCounts.clear();

  final weekEnd = weekStart.add(Duration(days: days));
  final weekEvents = events
      .where((event) => event.occursInRange(weekStart, weekEnd))
      .toList();
  weekEvents.sort((a, b) {
    int dateComp = a.startDate.compareTo(b.startDate);
    if (dateComp != 0) return dateComp;
    return b
        .getDaysSpanned(weekStart, weekEnd)
        .compareTo(a.getDaysSpanned(weekStart, weekEnd));
  });

  final int maxDisplayableBarRows = (maxEvents > 0) ? maxEvents - 1 : 0;

  for (final event in weekEvents) {
    int eventStartDayInWeek = 0;
    if (event.startDate.isAfter(weekStart)) {
      eventStartDayInWeek = event.startDate.difference(weekStart).inDays;
    }
    eventStartDayInWeek = eventStartDayInWeek.clamp(0, days - 1);

    int eventSpanInWeek = event.getDaysSpanned(weekStart, weekEnd);
    if (eventStartDayInWeek + eventSpanInWeek > days) {
      eventSpanInWeek = days - eventStartDayInWeek;
    }
    if (eventSpanInWeek <= 0) continue;

    for (int r = 0; r < maxDisplayableBarRows; r++) {
      while (rows.length <= r) {
        rows.add(List<EventPlacement?>.filled(days, null, growable: false));
      }

      bool canPlaceInThisRow = true;
      for (int d = 0; d < eventSpanInWeek; d++) {
        if (eventStartDayInWeek + d < days &&
            rows[r][eventStartDayInWeek + d] != null) {
          canPlaceInThisRow = false;
          break;
        }
      }

      if (canPlaceInThisRow) {
        final placement = EventPlacement(
            event: event,
            dayIdx: eventStartDayInWeek,
            span: eventSpanInWeek,
            rowIdx: r);
        for (int d = 0; d < eventSpanInWeek; d++) {
          if (eventStartDayInWeek + d < days) {
            rows[r][eventStartDayInWeek + d] = placement;
          }
        }
        break;
      }
    }
  }

  for (int dayIdx = 0; dayIdx < days; dayIdx++) {
    final currentDay = weekStart.add(Duration(days: dayIdx));
    final actualTotalForDay = events
        .where((e) => e.occursInRange(
            currentDay, currentDay.add(const Duration(days: 1))))
        .length;

    Set<String> distinctEventIdsInDisplaySlots = {};
    for (int r = 0; r < rows.length; r++) {
      if (dayIdx < rows[r].length) {
        // Ensure dayIdx is within bounds of the row
        final placement = rows[r][dayIdx];
        if (placement != null) {
          distinctEventIdsInDisplaySlots
              .add(placement.event.id); // Use event.id
        }
      }
    }
    int numBarsDisplayed = distinctEventIdsInDisplaySlots.length;

    if (maxEvents == 0 && actualTotalForDay > 0) {
      _calculatedOverflowCounts[dayIdx] = actualTotalForDay;
    } else if (actualTotalForDay > numBarsDisplayed && maxEvents > 0) {
      _calculatedOverflowCounts[dayIdx] =
          actualTotalForDay - numBarsDisplayed;
    } else {
      _calculatedOverflowCounts[dayIdx] = 0;
    }
    if ((_calculatedOverflowCounts[dayIdx] ?? 0) < 0) {
      _calculatedOverflowCounts[dayIdx] = 0;
    }
  }
}