Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Components.ListPopup
Imports Nexamas.UI.Controls
Imports Nexamas.UI.FloatRuntime
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 Public NotInheritable Class MASDatePicker
#Region "Date Value And Interaction State"

        Private Sub SetSelectedDateInternal(value As Nullable(Of Date),
                                            raiseChanged As Boolean)
            Dim normalized As Nullable(Of Date) = NormalizeNullableDate(value)
            If normalized.HasValue Then normalized = ClampToRange(normalized.Value)

            If NullableDatesEqual(_selectedDate, normalized) Then Return

            _selectedDate = normalized
            If _selectedDate.HasValue Then _displayMonth = FirstOfMonth(_selectedDate.Value)

            InvalidateLayoutSlotInternal()
            InvalidateVisual()

            If raiseChanged Then RaiseSelectedDateChangedSafe()
        End Sub

        Private Sub AdjustSelectedDate(deltaDays As Integer)
            Dim basis As Date = ResolveKeyboardDateForTrigger()
            SetSelectedDateInternal(ClampToRange(basis.AddDays(deltaDays)), True)
        End Sub

        Private Sub AdjustSelectedMonth(deltaMonths As Integer)
            Dim basis As Date = ResolveKeyboardDateForTrigger()
            SetSelectedDateInternal(ClampToRange(basis.AddMonths(deltaMonths)), True)
        End Sub

        Private Sub MoveSelectedDateToBoundary(preferMinimum As Boolean)
            Dim target As Date
            If preferMinimum AndAlso _minimumDate.HasValue Then
                target = _minimumDate.Value
            ElseIf (Not preferMinimum) AndAlso _maximumDate.HasValue Then
                target = _maximumDate.Value
            ElseIf _selectedDate.HasValue Then
                target = _selectedDate.Value
            Else
                target = DateTime.Today
            End If

            SetSelectedDateInternal(ClampToRange(target), True)
        End Sub

        Private Function ResolveKeyboardDateForTrigger() As Date
            If _selectedDate.HasValue Then Return _selectedDate.Value.Date
            Dim today As Date = DateTime.Today
            If IsDateAllowed(today) Then Return today
            If _minimumDate.HasValue Then Return _minimumDate.Value
            If _maximumDate.HasValue Then Return _maximumDate.Value
            Return today
        End Function

        Private Sub CloseCalendarIfOpenForPolicyChange()
            If _isCalendarOpen Then CloseCalendarSafe()
        End Sub

        Private Function ResolveInteractionState() As MASInteractionState
            If Not Me.Enabled Then Return MASInteractionState.Disabled
            If _pressed Then Return MASInteractionState.Pressed
            If _isCalendarOpen Then Return MASInteractionState.Focused
            If HasKeyboardFocus Then Return MASInteractionState.Focused
            If _hover Then Return MASInteractionState.Hovered
            Return MASInteractionState.Enabled
        End Function

        Private Sub ResetInputAll()
            _hover = False
            _pressed = False
        End Sub

#End Region

    End Class

End Namespace
