Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Composition
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Motion
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    Partial Public NotInheritable Class MASPagination

#Region "View State"

        Private Sub SetTotalPagesInternal(value As Integer,
                                          raiseChanged As Boolean)
            Dim normalizedTotal As Integer = NormalizeTotalPages(value)
            Dim normalizedPage As Integer = NormalizeCurrentPage(_currentPage, normalizedTotal)
            Dim changed As Boolean = (_totalPages <> normalizedTotal OrElse _currentPage <> normalizedPage)
            If Not changed Then Return

            _totalPages = normalizedTotal
            _currentPage = normalizedPage
            StopSelectionMotion()
            ResetPointerState()
            RequestSizeLayoutRefreshForSizeAffectingChange("MASPagination.TotalPages")
            InvalidateVisual()
            If raiseChanged Then RaisePageChangedSafe()
        End Sub

        Private Sub SetCurrentPageInternal(value As Integer,
                                           raiseChanged As Boolean)
            Dim normalized As Integer = NormalizeCurrentPage(value, _totalPages)
            If _currentPage = normalized Then Return

            Dim previous As Integer = _currentPage
            _currentPage = normalized
            StartSelectionMotion(previous, normalized)
            ResetPointerState()
            InvalidateVisual()
            If raiseChanged Then RaisePageChangedSafe()
        End Sub

        Private Sub StartSelectionMotion(previousPage As Integer,
                                         nextPage As Integer)
            StopSelectionMotion()

            If previousPage < 1 OrElse nextPage < 1 OrElse previousPage = nextPage Then
                _hasSelectionMotion = False
                _selectionMotionProgress = 1.0F
                Return
            End If

            _selectionMotionFromPage = previousPage
            _selectionMotionToPage = nextPage
            _selectionMotionProgress = 0.0F
            _hasSelectionMotion = True

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

            _selectionMotionRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASPagination.PageIndicator",
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplySelectionMotionFrame,
                completed:=AddressOf CompleteSelectionMotionFrame)
            _selectionMotionRunner.Start()
        End Sub

        Private Sub ApplySelectionMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            _selectionMotionProgress = MASMotionSystem.ClampProgress(frame.Value)
            InvalidateVisual()
        End Sub

        Private Sub CompleteSelectionMotionFrame(frame As MASMotionFrame)
            _selectionMotionProgress = 1.0F
            _hasSelectionMotion = False
            _selectionMotionRunner = Nothing
            InvalidateVisual()
        End Sub

        Private Sub StopSelectionMotion()
            If _selectionMotionRunner IsNot Nothing Then
                _selectionMotionRunner.Dispose()
                _selectionMotionRunner = Nothing
            End If

            _hasSelectionMotion = False
            _selectionMotionProgress = 1.0F
        End Sub

        Private Function IsSelectionMotionActive() As Boolean
            Return _hasSelectionMotion AndAlso _selectionMotionRunner IsNot Nothing AndAlso _selectionMotionRunner.IsRunning
        End Function

        Private Sub ResetPointerState()
            _hoverNodeIndex = -1
            _pressedNodeIndex = -1
        End Sub

        Private Shared Function NormalizeTotalPages(value As Integer) As Integer
            Return MASPaginationNavigationPolicy.NormalizeTotalPages(value)
        End Function

        Private Shared Function NormalizeCurrentPage(value As Integer,
                                                     totalPages As Integer) As Integer
            Return MASPaginationNavigationPolicy.NormalizeCurrentPage(value, totalPages)
        End Function

        Private Shared Function NormalizePageWindow(value As Integer) As Integer
            Return MASPaginationNavigationPolicy.NormalizePageWindow(value)
        End Function

        Private Shared Function ResolveRightToLeft() As Boolean
            Return MASPaginationNavigationPolicy.ResolveRightToLeft()
        End Function

        Private Shared Function ResolvePreviousText(isRtl As Boolean) As String
            Return MASPaginationNavigationPolicy.ResolvePreviousText(isRtl)
        End Function

        Private Shared Function ResolveNextText(isRtl As Boolean) As String
            Return MASPaginationNavigationPolicy.ResolveNextText(isRtl)
        End Function

#End Region

    End Class

End Namespace
