import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; import '../../../../api/webuntis/queries/getHolidays/getHolidaysResponse.dart'; import '../../../../extensions/date_time.dart'; import '../data/calendar_layout.dart'; import '../data/lesson_period_schedule.dart'; import '../data/webuntis_time.dart'; import 'time_region_tile.dart'; class SpecialRegionsBuilder { final GetHolidaysResponse holidays; final LessonPeriodSchedule schedule; final ColorScheme colorScheme; final Color disabledColor; SpecialRegionsBuilder({ required this.holidays, required this.schedule, required this.colorScheme, required this.disabledColor, }); List build() { final lastMonday = DateTime.now().subtract(const Duration(days: 14)).nextWeekday(DateTime.monday); final holidayRegions = _buildHolidayRegions().toList(); bool isInHoliday(DateTime time) => holidayRegions.any((region) => region.startTime.isSameDay(time)); final breakRegions = schedule.periods.where((p) => p.isBreak).map((p) { final start = lastMonday.copyWith(hour: p.start.hour, minute: p.start.minute); return _breakRegion(start, p.duration); }).where((region) => !isInHoliday(region.startTime)); return [ ...holidayRegions, ...breakRegions, ]; } Iterable _buildHolidayRegions() => holidays.result.expand((holiday) { final startDay = WebuntisTime.parse(holiday.startDate, 0); final dayCount = WebuntisTime.parse(holiday.endDate, 0).difference(startDay).inDays; final days = List.generate(dayCount, (i) => startDay.add(Duration(days: i))); final gridStartHour = kCalendarStartHour.floor(); final gridStartMinute = ((kCalendarStartHour - gridStartHour) * 60).round(); final gridEndHour = kCalendarEndHour.floor(); final gridEndMinute = ((kCalendarEndHour - gridEndHour) * 60).round(); return days.map((day) => TimeRegion( startTime: day.copyWith(hour: gridStartHour, minute: gridStartMinute), endTime: day.copyWith(hour: gridEndHour, minute: gridEndMinute), text: '$kTimeRegionHolidayPrefix${holiday.name}', color: disabledColor.withAlpha(50), iconData: Icons.holiday_village_outlined, )); }); TimeRegion _breakRegion(DateTime start, Duration duration) => TimeRegion( startTime: start, endTime: start.add(duration), recurrenceRule: 'FREQ=DAILY;INTERVAL=1', text: kTimeRegionCenterIcon, color: colorScheme.primary.withAlpha(50), iconData: Icons.restaurant, ); }