Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    Partial Public NotInheritable Class MASCalendarView

#Region "Input"

        Protected Overrides Sub OnMouseMove(ctx As MASThemeContext, ptPx As SKPoint)
            Dim previousHover As Boolean = _previousRect.Contains(ptPx.X, ptPx.Y)
            Dim nextHover As Boolean = _nextRect.Contains(ptPx.X, ptPx.Y)
            Dim cellHover As Integer = HitTestCell(ptPx)
            If previousHover = _hoverPrevious AndAlso nextHover = _hoverNext AndAlso cellHover = _hoverCellIndex Then Return
            _hoverPrevious = previousHover
            _hoverNext = nextHover
            _hoverCellIndex = cellHover
            InvalidateVisual()
        End Sub

        Protected Overrides Function OnMouseDown(ctx As MASThemeContext,
                                                 ptPx As SKPoint,
                                                 button As Integer) As Boolean
            If button <> CInt(MouseButtons.Left) Then Return False
            _pressedPrevious = _previousRect.Contains(ptPx.X, ptPx.Y)
            _pressedNext = _nextRect.Contains(ptPx.X, ptPx.Y)
            _pressedCellIndex = HitTestCell(ptPx)
            If _pressedPrevious OrElse _pressedNext OrElse _pressedCellIndex >= 0 Then
                InvalidateVisual()
                Return True
            End If
            Return _contentRect.Contains(ptPx.X, ptPx.Y)
        End Function

        Protected Overrides Function OnMouseUp(ctx As MASThemeContext,
                                               ptPx As SKPoint,
                                               button As Integer) As Boolean
            If button <> CInt(MouseButtons.Left) Then Return False
            Dim wasPrevious As Boolean = _pressedPrevious
            Dim wasNext As Boolean = _pressedNext
            Dim wasCell As Integer = _pressedCellIndex
            _pressedPrevious = False
            _pressedNext = False
            _pressedCellIndex = -1

            If wasPrevious AndAlso _previousRect.Contains(ptPx.X, ptPx.Y) Then
                MovePreviousMonth()
                InvalidateVisual()
                Return True
            End If

            If wasNext AndAlso _nextRect.Contains(ptPx.X, ptPx.Y) Then
                MoveNextMonth()
                InvalidateVisual()
                Return True
            End If

            If wasCell >= 0 AndAlso wasCell = HitTestCell(ptPx) AndAlso wasCell < _cells.Count Then
                Dim cell As CalendarDayCell = _cells(wasCell)
                If cell.Enabled Then
                    SelectedDate = cell.Value
                    InvalidateVisual()
                    Return True
                End If
            End If

            If wasPrevious OrElse wasNext OrElse wasCell >= 0 Then
                InvalidateVisual()
                Return True
            End If
            Return False
        End Function

        Protected Overrides Sub OnMouseLeave(ctx As MASThemeContext)
            ResetPointerState()
        End Sub

        Protected Overrides Sub OnMouseCancel(ctx As MASThemeContext)
            ResetPointerState()
        End Sub

        Protected Overrides Sub OnHostLostFocus(ctx As MASThemeContext)
            _pressedPrevious = False
            _pressedNext = False
            _pressedCellIndex = -1
            InvalidateVisual()
        End Sub

        Protected Overrides Function OnKeyDown(ctx As MASThemeContext,
                                               keyCode As Keys) As Boolean
            If Not Enabled Then Return False
            Dim selected As Date = If(_selectedDate.HasValue, _selectedDate.Value, DateTime.Today.Date)
            Dim isRtl As Boolean = MASCalendarViewPolicy.ResolveRightToLeft()
            Select Case keyCode
                Case Keys.Left
                    MoveKeyboardSelection(selected.AddDays(If(isRtl, 1, -1)))
                    Return True
                Case Keys.Right
                    MoveKeyboardSelection(selected.AddDays(If(isRtl, -1, 1)))
                    Return True
                Case Keys.Up
                    MoveKeyboardSelection(selected.AddDays(-7))
                    Return True
                Case Keys.Down
                    MoveKeyboardSelection(selected.AddDays(7))
                    Return True
                Case Keys.PageUp
                    SetDisplayMonthInternal(MASCalendarViewPolicy.AddMonthsSafe(_displayMonth, -1), True)
                    Return True
                Case Keys.PageDown
                    SetDisplayMonthInternal(MASCalendarViewPolicy.AddMonthsSafe(_displayMonth, 1), True)
                    Return True
                Case Keys.Home
                    MoveToday()
                    Return True
                Case Keys.Delete, Keys.Back
                    ClearDate()
                    Return True
            End Select
            Return False
        End Function

        Protected Overrides Function WantsKeyboardFocus() As Boolean
            Return MASCompositeContentFocusPolicy.CanReceiveKeyboardFocus(_contract, Visible, Enabled)
        End Function

        Protected Overrides Function WantsPointerFocus() As Boolean
            Return MASCompositeContentFocusPolicy.AllowsPointerFocusForCompositeContent(_contract, Visible, Enabled)
        End Function

#End Region

    End Class

End Namespace
