Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Motion
Imports SkiaSharp
Imports Nexamas.UI.General

Namespace Nexamas.UI.Components

    Friend Partial NotInheritable Class MASTimePickerClockView

#Region "Time value motion"

        Private _timeValueMotionRunner As MASMotionTimelineRunner
        Private _timeValueMotionProgress As Single = 1.0F
        Private _hasTimeValueMotion As Boolean

        Private Sub StartTimeValueMotion(previousTime As TimeSpan,
                                         nextTime As TimeSpan)
            If previousTime = nextTime Then Return

            StopTimeValueMotion(resetState:=False)
            _timeValueMotionProgress = 0.0F
            _hasTimeValueMotion = True

            Dim plan As MASMotionTransitionPlan = MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.ValueChange, 0.0F, 1.0F)
            If Not plan.ShouldAnimate Then
                CompleteTimeValueMotionFrame(Nothing)
                Return
            End If

            _timeValueMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASTimePickerClockView.ValueChange",
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplyTimeValueMotionFrame,
                completed:=AddressOf CompleteTimeValueMotionFrame)
            _timeValueMotionRunner.Start()

            InvalidateVisual()
        End Sub

        Private Sub ApplyTimeValueMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _timeValueMotionProgress = MASMotionSystem.ClampProgress(frame.EasedProgress)
            _hasTimeValueMotion = True
            InvalidateVisual()
        End Sub

        Private Sub CompleteTimeValueMotionFrame(frame As MASMotionFrame)
            StopTimeValueMotion(resetState:=True)
            InvalidateVisual()
        End Sub

        Private Sub StopTimeValueMotion(resetState As Boolean)
            If _timeValueMotionRunner IsNot Nothing Then
                _timeValueMotionRunner.Dispose()
                _timeValueMotionRunner = Nothing
            End If

            If resetState Then
                _timeValueMotionProgress = 1.0F
                _hasTimeValueMotion = False
            End If
        End Sub

        Private Sub DrawTimeValueMotionPulse(canvas As SKCanvas,
                                             display As SKRect,
                                             radius As Single,
                                             dpi As Single,
                                             brandPrimary As SKColor)
            If canvas Is Nothing OrElse Not _hasTimeValueMotion Then Return
            If display.Width <= 1.0F OrElse display.Height <= 1.0F Then Return

            Dim progress As Single = MASMotionSystem.ClampProgress(_timeValueMotionProgress)
            If progress >= 1.0F Then Return

            Dim strength As Single = 1.0F - progress
            Dim alpha As Byte = CByte(Math.Max(0, Math.Min(255, CInt(Math.Round(54.0R * CDbl(strength))))))
            If alpha <= 0 Then Return

            Dim pulse As SKRect = PixelSnap.SnapRectHalf(New SKRect(display.Left + (3.0F * dpi), display.Top + (3.0F * dpi), display.Right - (3.0F * dpi), display.Bottom - (3.0F * dpi)))
            If pulse.Width <= 1.0F OrElse pulse.Height <= 1.0F Then Return

            Using paint As New SKPaint With {
                .IsAntialias = True,
                .IsDither = True,
                .Style = SKPaintStyle.Fill,
                .Color = brandPrimary.WithAlpha(alpha),
                .BlendMode = SKBlendMode.SrcOver
            }
                canvas.DrawRoundRect(pulse, Math.Max(4.0F * dpi, radius - (3.0F * dpi)), Math.Max(4.0F * dpi, radius - (3.0F * dpi)), paint)
            End Using
        End Sub

#End Region

#Region "Dispose"

        Protected Overrides Sub Dispose(disposing As Boolean)
            StopTimeValueMotion(resetState:=True)
            MyBase.Dispose(disposing)
        End Sub

#End Region

    End Class

End Namespace
