Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Controls
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Composition
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    Partial Friend NotInheritable Class MASDatePickerCalendarView

#Region "View State"

        Private Sub MoveMonth(delta As Integer)
            _displayMonth = _displayMonth.AddMonths(delta)
            _pendingMonth = _displayMonth.Month
            ResetYearWindow()
            _onDisplayMonthChanged?.Invoke(_displayMonth)
            InvalidateVisual()
        End Sub

        Private Sub ToggleMonthYearSelector()
            If _calendarMode = CalendarMode.MonthYear Then
                _calendarMode = CalendarMode.Days
            Else
                _calendarMode = CalendarMode.MonthYear
                _pendingMonth = _displayMonth.Month
                ResetYearWindow()
            End If

            InvalidateVisual()
        End Sub

        Private Sub ResetYearWindow()
            Dim minYear As Integer = Math.Max(1, _displayMonth.Year - MonthYearWindowRadiusYears)
            Dim maxYear As Integer = Math.Min(9999, _displayMonth.Year + MonthYearWindowRadiusYears)
            Dim maxWindowStart As Integer = Math.Max(minYear, maxYear - 19)
            _yearWindowStart = Math.Max(minYear, Math.Min(maxWindowStart, _displayMonth.Year - 9))
        End Sub

        Private Sub MoveYearWindow(deltaYears As Integer)
            Dim minYear As Integer = Math.Max(1, _displayMonth.Year - MonthYearWindowRadiusYears)
            Dim maxYear As Integer = Math.Min(9999, _displayMonth.Year + MonthYearWindowRadiusYears)
            Dim maxWindowStart As Integer = Math.Max(minYear, maxYear - 19)
            _yearWindowStart = Math.Max(minYear, Math.Min(maxWindowStart, _yearWindowStart + deltaYears))
            InvalidateVisual()
        End Sub

        Private Sub ApplyMonthYear(yearValue As Integer,
                                   monthValue As Integer)
            yearValue = Math.Max(1, Math.Min(9999, yearValue))
            monthValue = Math.Max(1, Math.Min(12, monthValue))
            If Not IsMonthAllowed(yearValue, monthValue) Then Return

            _displayMonth = New Date(yearValue, monthValue, 1)
            _pendingMonth = _displayMonth.Month
            _calendarMode = CalendarMode.Days
            ResetYearWindow()
            _onDisplayMonthChanged?.Invoke(_displayMonth)
            InvalidateVisual()
        End Sub

        Private Sub MoveKeyboardDate(deltaDays As Integer)
            MoveKeyboardTo(ResolveKeyboardDate().AddDays(deltaDays))
        End Sub

        Private Sub MoveKeyboardTo(value As Date)
            Dim resolved As Date = value.Date
            If Not IsDateAllowed(resolved) Then resolved = ClampToRange(resolved)

            Dim previousDate As Nullable(Of Date) = _selectedDate
            _selectedDate = resolved
            _displayMonth = MASDatePicker.FirstOfMonth(resolved)
            StartCalendarSelectionMotion(previousDate, _selectedDate)
            _pendingMonth = _displayMonth.Month
            ResetYearWindow()
            _onDisplayMonthChanged?.Invoke(_displayMonth)
            InvalidateVisual()
        End Sub

        Private Function ResolveKeyboardDate() As Date
            If _selectedDate.HasValue Then Return _selectedDate.Value.Date
            Return _displayMonth
        End Function

#End Region

    End Class

End Namespace
