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.Components

    Partial Public NotInheritable Class MASSplitView

#Region "Panel motion"

        Private _paneMotionRunner As MASMotionTimelineRunner
        Private _paneMotionSide As SplitDividerSide = SplitDividerSide.None
        Private _paneMotionProgress As Single = 1.0F
        Private _hasPaneMotion As Boolean

        Private Sub StartPaneRevealMotion(side As SplitDividerSide)
            If side = SplitDividerSide.None Then Return

            StopPaneRevealMotion(reset:=False)

            _paneMotionSide = side
            _paneMotionProgress = 0.0F
            _hasPaneMotion = True

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

            _paneMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASSplitView.PaneReveal",
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplyPaneRevealMotionFrame,
                completed:=AddressOf CompletePaneRevealMotionFrame)
            _paneMotionRunner.Start()
            InvalidateVisual()
        End Sub

        Private Sub ApplyPaneRevealMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _paneMotionProgress = MASMotionSystem.ClampProgress(frame.Value)
            _hasPaneMotion = True
            InvalidateVisual()
        End Sub

        Private Sub CompletePaneRevealMotionFrame(frame As MASMotionFrame)
            _paneMotionProgress = 1.0F
            _paneMotionSide = SplitDividerSide.None
            _hasPaneMotion = False
            _paneMotionRunner = Nothing
            InvalidateVisual()
        End Sub

        Private Sub StopPaneRevealMotion(reset As Boolean)
            If _paneMotionRunner IsNot Nothing Then
                _paneMotionRunner.Dispose()
                _paneMotionRunner = Nothing
            End If

            If reset Then
                _paneMotionProgress = 1.0F
                _paneMotionSide = SplitDividerSide.None
                _hasPaneMotion = False
            End If
        End Sub

        Private Function IsPaneRevealMotionActive() As Boolean
            Return _hasPaneMotion AndAlso _paneMotionRunner IsNot Nothing AndAlso _paneMotionRunner.IsRunning AndAlso _paneMotionSide <> SplitDividerSide.None
        End Function

        Private Sub DrawPaneRevealMotionOverlay(canvas As SKCanvas,
                                                geometry As SplitViewGeometry,
                                                dpi As Single,
                                                accent As SKColor)
            If canvas Is Nothing OrElse Not IsPaneRevealMotionActive() Then Return

            Dim target As SKRect = SKRect.Empty
            If _paneMotionSide = SplitDividerSide.Left Then
                target = geometry.LeftPane
            ElseIf _paneMotionSide = SplitDividerSide.Right Then
                target = geometry.RightPane
            End If

            If target.Width <= 1.0F OrElse target.Height <= 1.0F Then Return

            Dim fade As Single = 1.0F - MASMotionSystem.ClampProgress(_paneMotionProgress)
            If fade <= 0.001F Then Return

            Dim alpha As Integer = CInt(Math.Round(50.0R * CDbl(fade)))
            If alpha < 0 Then alpha = 0
            If alpha > 96 Then alpha = 96

            Dim snapped As SKRect = PixelSnap.SnapRect(target, dpi)
            Using fill As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = accent.WithAlpha(CByte(alpha))}
                canvas.DrawRoundRect(snapped, SplitViewTokens.PaneRadiusDip * dpi, SplitViewTokens.PaneRadiusDip * dpi, fill)
            End Using
        End Sub

#End Region

#Region "Dispose"

        Protected Overrides Sub Dispose(disposing As Boolean)
            StopPaneRevealMotion(reset:=True)
            MyBase.Dispose(disposing)
        End Sub

#End Region

    End Class

End Namespace
