Files
Wino-Mail/Wino.Core.Domain/Models/Calendar/CalendarRangeResolver.cs
Burak Kaan Köse 51fef043ee Range thing.
2026-03-21 00:58:01 +01:00

104 lines
4.1 KiB
C#

using System;
using System.Linq;
using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Models.Calendar;
public static class CalendarRangeResolver
{
public static VisibleDateRange Resolve(CalendarDisplayRequest request, CalendarSettings settings, DateOnly today)
{
var startDate = GetStartDate(request.DisplayType, request.AnchorDate, settings);
var endDate = GetEndDate(request.DisplayType, request.AnchorDate, startDate, settings);
var dayCount = endDate.DayNumber - startDate.DayNumber + 1;
var dates = Enumerable.Range(0, dayCount)
.Select(offset => startDate.AddDays(offset))
.ToArray();
return new VisibleDateRange(
request.DisplayType,
request.AnchorDate,
startDate,
endDate,
request.AnchorDate,
dayCount,
today >= startDate && today <= endDate,
startDate.Year == endDate.Year && startDate.Month == endDate.Month,
dates);
}
public static VisibleDateRange ChangeDisplayType(VisibleDateRange currentRange, CalendarDisplayType targetDisplayType, CalendarSettings settings, DateOnly today)
{
if (currentRange.DisplayType == targetDisplayType)
{
return currentRange;
}
var anchorDate = currentRange.AnchorDate;
if (currentRange.DisplayType == CalendarDisplayType.Month)
{
anchorDate = currentRange.Contains(today) ? today : currentRange.StartDate;
}
return Resolve(new CalendarDisplayRequest(targetDisplayType, anchorDate), settings, today);
}
public static VisibleDateRange Navigate(VisibleDateRange currentRange, int direction, CalendarSettings settings, DateOnly today)
{
if (direction == 0)
{
return currentRange;
}
var normalizedDirection = Math.Sign(direction);
var anchorDate = currentRange.DisplayType switch
{
CalendarDisplayType.Day => currentRange.AnchorDate.AddDays(normalizedDirection),
CalendarDisplayType.Week => currentRange.AnchorDate.AddDays(7 * normalizedDirection),
CalendarDisplayType.WorkWeek => currentRange.AnchorDate.AddDays(7 * normalizedDirection),
CalendarDisplayType.Month => currentRange.AnchorDate.AddMonths(normalizedDirection),
_ => currentRange.AnchorDate
};
return Resolve(new CalendarDisplayRequest(currentRange.DisplayType, anchorDate), settings, today);
}
private static DateOnly GetStartDate(CalendarDisplayType displayType, DateOnly anchorDate, CalendarSettings settings)
{
return displayType switch
{
CalendarDisplayType.Day => anchorDate,
CalendarDisplayType.Week => GetStartOfWeek(anchorDate, settings.FirstDayOfWeek),
CalendarDisplayType.WorkWeek => GetStartOfWorkWeek(anchorDate, settings),
CalendarDisplayType.Month => new DateOnly(anchorDate.Year, anchorDate.Month, 1),
_ => anchorDate
};
}
private static DateOnly GetEndDate(CalendarDisplayType displayType, DateOnly anchorDate, DateOnly startDate, CalendarSettings settings)
{
return displayType switch
{
CalendarDisplayType.Day => anchorDate,
CalendarDisplayType.Week => startDate.AddDays(6),
CalendarDisplayType.WorkWeek => startDate.AddDays(settings.WorkWeekDayCount - 1),
CalendarDisplayType.Month => new DateOnly(anchorDate.Year, anchorDate.Month, DateTime.DaysInMonth(anchorDate.Year, anchorDate.Month)),
_ => anchorDate
};
}
private static DateOnly GetStartOfWeek(DateOnly date, DayOfWeek firstDayOfWeek)
{
var offset = ((int)date.DayOfWeek - (int)firstDayOfWeek + 7) % 7;
return date.AddDays(-offset);
}
private static DateOnly GetStartOfWorkWeek(DateOnly anchorDate, CalendarSettings settings)
{
var startOfWeek = GetStartOfWeek(anchorDate, settings.FirstDayOfWeek);
var offsetToWorkWeekStart = settings.GetWeekOffset(settings.WorkWeekStart);
return startOfWeek.AddDays(offsetToWorkWeekStart);
}
}