Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    Friend Partial NotInheritable Class MASAvatarOverflowFloatContent

#Region "Overflow content motion"

        Private _avatarOverflowContentRunner As MASMotionTimelineRunner
        Private _avatarOverflowContentRow As Integer = -1
        Private _avatarOverflowContentProgress As Single = 1.0F
        Private _hasAvatarOverflowContentMotion As Boolean

        Private Sub StartAvatarOverflowContentMotion(rowIndex As Integer)
            If rowIndex < 0 OrElse rowIndex >= _items.Count Then
                StopAvatarOverflowContentMotion(resetState:=True)
                Return
            End If

            StopAvatarOverflowContentMotion(resetState:=False)

            _avatarOverflowContentRow = rowIndex
            _avatarOverflowContentProgress = 0.0F
            _hasAvatarOverflowContentMotion = True

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

            _avatarOverflowContentRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASAvatarOverflowFloatContent.RowPulse",
                plan:=plan,
                requestFrame:=AddressOf RequestInvalidate,
                applyFrame:=AddressOf ApplyAvatarOverflowContentMotionFrame,
                completed:=AddressOf CompleteAvatarOverflowContentMotionFrame)
            _avatarOverflowContentRunner.Start()

            RequestInvalidate()
        End Sub

        Private Sub ApplyAvatarOverflowContentMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _avatarOverflowContentProgress = MASMotionSystem.ClampProgress(frame.EasedProgress)
            _hasAvatarOverflowContentMotion = True
            RequestInvalidate()
        End Sub

        Private Sub CompleteAvatarOverflowContentMotionFrame(frame As MASMotionFrame)
            StopAvatarOverflowContentMotion(resetState:=True)
            RequestInvalidate()
        End Sub

        Private Sub StopAvatarOverflowContentMotion(resetState As Boolean)
            If _avatarOverflowContentRunner IsNot Nothing Then
                _avatarOverflowContentRunner.Dispose()
                _avatarOverflowContentRunner = Nothing
            End If

            If resetState Then
                _avatarOverflowContentRow = -1
                _avatarOverflowContentProgress = 1.0F
                _hasAvatarOverflowContentMotion = False
            End If
        End Sub

        Private Sub DrawAvatarOverflowContentMotionOverlay(canvas As SKCanvas,
                                                           ctx As MASThemeContext,
                                                           dpi As Single)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If Not _hasAvatarOverflowContentMotion Then Return
            If _avatarOverflowContentRow < 0 OrElse _avatarOverflowContentRow >= _items.Count Then Return
            If _rowsAreaPx.IsEmpty OrElse _rowsAreaPx.Width <= 1.0F OrElse _rowsAreaPx.Height <= 1.0F Then Return

            Dim rowHeight As Single = Math.Max(1.0F, AvatarTokens.OverflowPopupRowHeightDip * dpi)
            Dim visibleIndex As Integer = _avatarOverflowContentRow - _scrollOffset
            If visibleIndex < 0 Then Return

            Dim rowTop As Single = _rowsAreaPx.Top + (CSng(visibleIndex) * rowHeight)
            Dim rowBottom As Single = rowTop + rowHeight
            If rowBottom < _rowsAreaPx.Top OrElse rowTop > _rowsAreaPx.Bottom Then Return

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

            Dim inset As Single = (2.0F + progress * 3.0F) * dpi
            Dim overlayRect As SKRect = PixelSnap.SnapRectHalf(New SKRect(
                _rowsAreaPx.Left + inset,
                Math.Max(_rowsAreaPx.Top, rowTop + inset),
                _rowsAreaPx.Right - inset,
                Math.Min(_rowsAreaPx.Bottom, rowBottom - inset)))
            If overlayRect.Width <= 1.0F OrElse overlayRect.Height <= 1.0F Then Return

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

            Dim radius As Single = Math.Max(4.0F * dpi, Math.Min(overlayRect.Height * 0.38F, AvatarTokens.OverflowPopupRowRadiusDip * dpi))

            Using paint As New SKPaint With {
                .IsAntialias = True,
                .IsDither = True,
                .Style = SKPaintStyle.Fill,
                .Color = MASAvatarIdentityPolicy.ResolveAccentColor(ctx).WithAlpha(alpha),
                .BlendMode = SKBlendMode.SrcOver
            }
                canvas.DrawRoundRect(overlayRect, radius, radius, paint)
            End Using
        End Sub

#End Region

    End Class

End Namespace
