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

    ''' <summary>
    ''' Internal MAS-owned month calendar hosted by MASDatePicker's FloatRuntime popup.
    ''' It deliberately remains Friend so Nexamas UI does not expose a parallel Calendar
    ''' product API before a separate standalone Calendar stage is approved.
    ''' </summary>
    Partial Friend NotInheritable Class MASDatePickerCalendarView
        Inherits MASControlBase
        Implements IMASLayoutParticipant
        Implements IMASIntrinsicSizeContract

        Private Enum HitPart
            None = 0
            PreviousMonth = 1
            NextMonth = 2
            DayCell = 3
            MonthYearTitle = 4
            MonthChip = 5
            YearChip = 6
        End Enum

        Private Enum CalendarMode
            Days = 0
            MonthYear = 1
        End Enum

        Private Structure HitTarget
            Friend Part As HitPart
            Friend Index As Integer
            Friend Value As Date
        End Structure

        Private Const MonthYearWindowRadiusYears As Integer = 100
        Private Const MonthYearWindowPageSizeYears As Integer = 20

        Private Shared ReadOnly _contract As MASResolvedComponentContract =
            MASArchitectureRuntime.ResolveContractOrThrow(GetType(MASDatePickerCalendarView))

        Private ReadOnly _owner As MASDatePicker
        Private ReadOnly _onDateSelected As Action(Of Date)
        Private ReadOnly _onDisplayMonthChanged As Action(Of Date)
        Private ReadOnly _shadowPainter As New MASShadowPainter()
        Private ReadOnly _primitives As New MASVisualPrimitivesPainter()

        Private _selectedDate As Nullable(Of Date)
        Private _displayMonth As Date
        Private _minimumDate As Nullable(Of Date)
        Private _maximumDate As Nullable(Of Date)
        Private _hoverTarget As HitTarget
        Private _pressedTarget As HitTarget
        Private _calendarMode As CalendarMode = CalendarMode.Days
        Private _yearWindowStart As Integer
        Private _pendingMonth As Integer
        Private _lastDayCells(41) As SKRect
        Private _lastDayDates(41) As Date
        Private _lastPreviousRect As SKRect
        Private _lastNextRect As SKRect
        Private _lastTitleRect As SKRect
        Private _lastMonthCells(11) As SKRect
        Private _lastMonthValues(11) As Integer
        Private _lastYearCells(19) As SKRect
        Private _lastYearValues(19) As Integer
        Private _lastLayoutPlan As MASDatePickerCalendarLayoutPlan

        Friend Sub New(owner As MASDatePicker,
                       selectedDate As Nullable(Of Date),
                       displayMonth As Date,
                       minimumDate As Nullable(Of Date),
                       maximumDate As Nullable(Of Date),
                       onDateSelected As Action(Of Date),
                       onDisplayMonthChanged As Action(Of Date))
            MyBase.New()

            _owner = owner
            _selectedDate = NormalizeNullableDate(selectedDate)
            _displayMonth = MASDatePicker.FirstOfMonth(displayMonth)
            _minimumDate = NormalizeNullableDate(minimumDate)
            _maximumDate = NormalizeNullableDate(maximumDate)
            _pendingMonth = _displayMonth.Month
            ResetYearWindow()
            _onDateSelected = onDateSelected
            _onDisplayMonthChanged = onDisplayMonthChanged
        End Sub

    End Class

End Namespace
