Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports SkiaSharp

Namespace Nexamas.UI.Input

    Friend NotInheritable Class MASDoubleClickTracker(Of TKey)

        Private ReadOnly _comparer As IEqualityComparer(Of TKey)

        Private _lastKey As TKey = Nothing
        Private _hasLastKey As Boolean = False
        Private _lastTick As Integer = 0
        Private _lastPointPx As SKPoint = New SKPoint(Single.NaN, Single.NaN)

        Friend Sub New()
            Me.New(EqualityComparer(Of TKey).Default)
        End Sub

        Friend Sub New(comparer As IEqualityComparer(Of TKey))
            _comparer = If(comparer, EqualityComparer(Of TKey).Default)
        End Sub

        Friend Sub Reset()
            _lastKey = Nothing
            _hasLastKey = False
            _lastTick = 0
            _lastPointPx = New SKPoint(Single.NaN, Single.NaN)
        End Sub

        Friend Function IsDoubleClick(key As TKey, ptPx As SKPoint) As Boolean
            Dim nowTick As Integer = Nexamas.UI.Timing.MASInteractionClock.TickCount()
            Dim elapsed As Integer = nowTick - _lastTick

            Dim sameKey As Boolean =
                _hasLastKey AndAlso _comparer.Equals(_lastKey, key)

            Dim withinTime As Boolean =
                elapsed >= 0 AndAlso elapsed <= SystemInformation.DoubleClickTime

            Dim withinDistance As Boolean = False

            If Not Single.IsNaN(_lastPointPx.X) AndAlso
               Not Single.IsNaN(_lastPointPx.Y) Then

                Dim dx As Single = Math.Abs(ptPx.X - _lastPointPx.X)
                Dim dy As Single = Math.Abs(ptPx.Y - _lastPointPx.Y)

                Dim maxDx As Single = Math.Max(4.0F, CSng(SystemInformation.DoubleClickSize.Width))
                Dim maxDy As Single = Math.Max(4.0F, CSng(SystemInformation.DoubleClickSize.Height))

                withinDistance = dx <= maxDx AndAlso dy <= maxDy
            End If

            _lastKey = key
            _hasLastKey = True
            _lastTick = nowTick
            _lastPointPx = ptPx

            Return sameKey AndAlso withinTime AndAlso withinDistance
        End Function

    End Class

End Namespace