Option Strict On
Option Explicit On

Imports Nexamas.UI.Motion
Imports Nexamas.UI.FloatRuntime

Namespace Nexamas.UI.Components.DropDownMenu

    Friend Partial NotInheritable Class DropDownMenuFloatContent

#Region "Motion"

        Private _contentMotionRunner As MASMotionTimelineRunner

        Private Sub StartDropDownInteractionMotion(oldHoverPath As Integer(),
                                                   oldOpenPath As Integer())
            If _disposed OrElse _closed Then Return
            If PathsEqual(oldHoverPath, _m.HoverPath) AndAlso PathsEqual(oldOpenPath, _m.OpenPath) Then Return

            Dim level As Integer = -1
            Dim rowIndex As Integer = -1
            If Not TryResolveContentMotionTarget(level, rowIndex) Then
                StopDropDownContentMotion(resetState:=True)
                Return
            End If

            StopDropDownContentMotion(resetState:=False)

            _m.ContentMotionLevel = level
            _m.ContentMotionRowIndex = rowIndex
            _m.ContentMotionProgress = 0.0F
            _m.HasContentMotion = True

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

            _contentMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="DropDownMenuFloatContent.ItemPulse",
                plan:=plan,
                requestFrame:=AddressOf RequestDropDownContentFrame,
                applyFrame:=AddressOf ApplyDropDownContentMotionFrame,
                completed:=AddressOf CompleteDropDownContentMotionFrame)
            _contentMotionRunner.Start()

            RequestDropDownContentFrame()
        End Sub

        Private Function TryResolveContentMotionTarget(ByRef level As Integer,
                                                       ByRef rowIndex As Integer) As Boolean
            level = -1
            rowIndex = -1

            If _m.HoverPath IsNot Nothing Then
                For i As Integer = _m.HoverPath.Count - 1 To 0 Step -1
                    Dim value As Integer = _m.HoverPath(i)
                    If value >= 0 Then
                        level = i
                        rowIndex = value
                        Return True
                    End If
                Next
            End If

            If _m.OpenPath IsNot Nothing Then
                For i As Integer = _m.OpenPath.Count - 1 To 0 Step -1
                    Dim value As Integer = _m.OpenPath(i)
                    If value >= 0 Then
                        level = i
                        rowIndex = value
                        Return True
                    End If
                Next
            End If

            Return False
        End Function

        Private Sub ApplyDropDownContentMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _m.ContentMotionProgress = MASMotionSystem.ClampProgress(frame.EasedProgress)
            _m.HasContentMotion = True
            RequestDropDownContentFrame()
        End Sub

        Private Sub CompleteDropDownContentMotionFrame(frame As MASMotionFrame)
            _m.ContentMotionProgress = 1.0F
            _m.HasContentMotion = False
            _m.ContentMotionLevel = -1
            _m.ContentMotionRowIndex = -1
            _contentMotionRunner = Nothing
            RequestDropDownContentFrame()
        End Sub

        Private Sub StopDropDownContentMotion(resetState As Boolean)
            If _contentMotionRunner IsNot Nothing Then
                _contentMotionRunner.Dispose()
                _contentMotionRunner = Nothing
            End If

            If resetState Then
                _m.HasContentMotion = False
                _m.ContentMotionProgress = 1.0F
                _m.ContentMotionLevel = -1
                _m.ContentMotionRowIndex = -1
            End If
        End Sub

        Private Sub RequestDropDownContentFrame()
            Dim session As IMASFloatSession = _session
            If session Is Nothing Then Return

            Try
                session.RequestInvalidate()
            Catch masCaughtException1 As System.Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowRecoverable(masCaughtException1)
            End Try
        End Sub

#End Region

    End Class

End Namespace
