Option Strict On
Option Explicit On

Imports System
Imports System.Windows.Forms
Imports SkiaSharp

Namespace Nexamas.UI.TextInput

    ''' <summary>
    ''' Owns pointer-selection gesture state for MAS text-input controls.
    ''' </summary>
    ''' <remarks>
    ''' This class does not mutate text. It tracks hover, press, drag-selection,
    ''' double-click memory, and cancellation state. The owning control remains
    ''' responsible for translating hit-test points into text indexes and applying
    ''' those indexes through MASTextInputController.
    ''' </remarks>
    Friend NotInheritable Class MASTextInputSelectionController

#Region "Fields"

        Private _lastClickTick As Integer
        Private _lastClickIndex As Integer = -1
        Private _lastClickPoint As SKPoint

#End Region

#Region "Properties"

        Friend Property Hover As Boolean
        Friend Property Pressed As Boolean
        Friend Property DragSelecting As Boolean

#End Region

#Region "Pointer state"

        Friend Function SetHover(value As Boolean) As Boolean
            If Hover = value Then Return False
            Hover = value
            Return True
        End Function

        Friend Function ClearHoverAndPressIfIdle() As Boolean
            Dim changed As Boolean = False

            If Hover Then
                Hover = False
                changed = True
            End If

            If Not DragSelecting AndAlso Pressed Then
                Pressed = False
                changed = True
            End If

            Return changed
        End Function

        Friend Sub BeginTextSelectionGesture()
            ' Text inputs are edit surfaces rather than command buttons. Selection
            ' gestures must not apply a pressed surface wash over the text layer.
            Pressed = False
            DragSelecting = True
        End Sub

        Friend Function EndPointerGesture() As Boolean
            Dim wasPressed As Boolean = Pressed OrElse DragSelecting
            Pressed = False
            DragSelecting = False
            Return wasPressed
        End Function

        Friend Function CancelPointerState() As Boolean
            Dim changed As Boolean = False

            If Hover Then
                Hover = False
                changed = True
            End If

            If Pressed Then
                Pressed = False
                changed = True
            End If

            If DragSelecting Then
                DragSelecting = False
                changed = True
            End If

            Return changed
        End Function

        Friend Sub ClearFocusGestureState()
            Pressed = False
            DragSelecting = False
        End Sub

#End Region

#Region "Double-click tracking"

        Friend Function IsDoubleClick(pointPx As SKPoint,
                                      textIndex As Integer) As Boolean
            Dim nowTick As Integer = Nexamas.UI.Timing.MASInteractionClock.TickCount()
            Dim dt As Integer = nowTick - _lastClickTick
            If dt < 0 Then dt = Integer.MaxValue

            Dim dx As Single = pointPx.X - _lastClickPoint.X
            Dim dy As Single = pointPx.Y - _lastClickPoint.Y
            Dim dist2 As Single = (dx * dx) + (dy * dy)

            Return _lastClickIndex >= 0 AndAlso
                   dt <= SystemInformation.DoubleClickTime AndAlso
                   dist2 <= 36.0F AndAlso
                   Math.Abs(textIndex - _lastClickIndex) <= 1
        End Function

        Friend Sub RememberClick(pointPx As SKPoint,
                                 textIndex As Integer)
            _lastClickTick = Nexamas.UI.Timing.MASInteractionClock.TickCount()
            _lastClickIndex = textIndex
            _lastClickPoint = pointPx
        End Sub

#End Region

    End Class

End Namespace
