Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Motion
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    Partial Public NotInheritable Class MASStatusBanner

#Region "Motion"

        Private _revealMotionRunner As MASMotionTimelineRunner
        Private _revealProgress As Single = 1.0F
        Private _hasRevealMotion As Boolean

        Private Sub StartStatusBannerRevealMotion()
            If _disposedLocal Then Return

            StopStatusBannerRevealMotion(resetReveal:=False)
            _revealProgress = 0.0F
            _hasRevealMotion = True

            Dim plan As MASMotionTransitionPlan = MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.PanelReveal, 0.0F, 1.0F)
            _revealMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASStatusBanner.PanelReveal",
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplyStatusBannerRevealMotionFrame,
                completed:=AddressOf CompleteStatusBannerRevealMotionFrame)
            _revealMotionRunner.Start()

            InvalidateVisual()
        End Sub

        Private Sub ApplyStatusBannerRevealMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _revealProgress = MASMotionSystem.ClampProgress(frame.EasedProgress)
            _hasRevealMotion = True
            InvalidateVisual()
        End Sub

        Private Sub CompleteStatusBannerRevealMotionFrame(frame As MASMotionFrame)
            StopStatusBannerRevealMotion(resetReveal:=True)
            InvalidateVisual()
        End Sub

        Private Sub StopStatusBannerRevealMotion(resetReveal As Boolean)
            If _revealMotionRunner IsNot Nothing Then
                _revealMotionRunner.Dispose()
                _revealMotionRunner = Nothing
            End If

            If resetReveal Then
                _revealProgress = 1.0F
                _hasRevealMotion = False
            End If
        End Sub

        Private Function ResolveStatusBannerRevealBounds(bounds As SKRect, dpi As Single) As SKRect
            If Not _hasRevealMotion Then Return bounds
            If bounds.Width <= 1.0F OrElse bounds.Height <= 1.0F Then Return bounds

            Dim progress As Single = MASMotionSystem.ClampProgress(_revealProgress)
            Dim safeDpi As Single = Math.Max(0.1F, dpi)
            Dim offsetY As Single = (1.0F - progress) * 4.0F * safeDpi
            Return New SKRect(bounds.Left, bounds.Top + offsetY, bounds.Right, bounds.Bottom + offsetY)
        End Function

        Private Function ApplyStatusBannerRevealAlpha(color As SKColor) As SKColor
            If Not _hasRevealMotion Then Return color
            Dim progress As Single = MASMotionSystem.ClampProgress(_revealProgress)
            Dim multiplier As Single = Math.Max(0.45F, progress)
            Dim alpha As Byte = CByte(Math.Max(0, Math.Min(255, CInt(Math.Round(CDbl(color.Alpha) * CDbl(multiplier))))))
            Return color.WithAlpha(alpha)
        End Function

#End Region

    End Class

End Namespace
