Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Controls

    Partial Public NotInheritable Class MASNotificationPanel

#Region "Motion"

        Private _mutationMotionRunner As MASMotionTimelineRunner
        Private _mutationProgress As Single = 1.0F
        Private _hasMutationMotion As Boolean

        Private Sub StartNotificationPanelMutationMotion(tokenId As MASMotionTokenId)
            If _disposedLocal Then Return

            StopNotificationPanelMutationMotion(resetMutation:=False)
            _mutationProgress = 0.0F
            _hasMutationMotion = True

            Dim plan As MASMotionTransitionPlan = MASMotionSystem.CreateTransitionPlan(tokenId, 0.0F, 1.0F)
            _mutationMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASNotificationPanel." & tokenId.ToString(),
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplyNotificationPanelMutationMotionFrame,
                completed:=AddressOf CompleteNotificationPanelMutationMotionFrame)
            _mutationMotionRunner.Start()

            InvalidateVisual()
        End Sub

        Private Sub ApplyNotificationPanelMutationMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _mutationProgress = MASMotionSystem.ClampProgress(frame.EasedProgress)
            _hasMutationMotion = True
            InvalidateVisual()
        End Sub

        Private Sub CompleteNotificationPanelMutationMotionFrame(frame As MASMotionFrame)
            StopNotificationPanelMutationMotion(resetMutation:=True)
            InvalidateVisual()
        End Sub

        Private Sub StopNotificationPanelMutationMotion(resetMutation As Boolean)
            If _mutationMotionRunner IsNot Nothing Then
                _mutationMotionRunner.Dispose()
                _mutationMotionRunner = Nothing
            End If

            If resetMutation Then
                _mutationProgress = 1.0F
                _hasMutationMotion = False
            End If
        End Sub

        Private Function ResolveNotificationPanelMutationRowRect(rect As SKRect,
                                                                  dpi As Single,
                                                                  rowIndex As Integer) As SKRect
            If Not _hasMutationMotion Then Return rect
            If rect.Width <= 1.0F OrElse rect.Height <= 1.0F Then Return rect

            Dim progress As Single = MASMotionSystem.ClampProgress(_mutationProgress)
            Dim wave As Single = CSng(Math.Sin(CDbl(progress) * Math.PI))
            If wave <= 0.0001F Then Return rect

            Dim safeDpi As Single = PixelSnap.SafeDpi(dpi)
            Dim rowDelay As Single = Math.Min(1.0F, Math.Max(0.0F, CSng(rowIndex) * 0.08F))
            Dim localWave As Single = Math.Max(0.0F, wave - rowDelay)
            Dim offsetX As Single = (1.0F - progress) * 3.0F * safeDpi
            Dim scale As Single = 1.0F + (0.012F * localWave)
            Dim cx As Single = rect.MidX + offsetX
            Dim cy As Single = rect.MidY
            Dim halfWidth As Single = rect.Width * scale * 0.5F
            Dim halfHeight As Single = rect.Height * scale * 0.5F
            Return New SKRect(cx - halfWidth, cy - halfHeight, cx + halfWidth, cy + halfHeight)
        End Function

        Private Function ResolveNotificationPanelMutationAlphaBoost(rowIndex As Integer) As Integer
            If Not _hasMutationMotion Then Return 0
            Dim progress As Single = MASMotionSystem.ClampProgress(_mutationProgress)
            Dim wave As Single = CSng(Math.Sin(CDbl(progress) * Math.PI))
            Dim rowDelay As Single = Math.Min(1.0F, Math.Max(0.0F, CSng(rowIndex) * 0.08F))
            Dim localWave As Single = Math.Max(0.0F, wave - rowDelay)
            Return Math.Max(0, CInt(Math.Round(14.0R * CDbl(localWave))))
        End Function

#End Region

    End Class

End Namespace
