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

    ''' <summary>
    ''' Public Nexamas UI pagination control for business lists, search results,
    ''' reports, and data surfaces. It owns only the same-surface page navigation UI
    ''' and PageChanged notification; data loading, query projection, virtualization,
    ''' DataGrid/DataView integration, and persistence remain owned by the consumer
    ''' or by existing Nexamas UI data systems.
    ''' </summary>
    Partial Public NotInheritable Class MASPagination
        Inherits Nexamas.UI.Controls.MASControlBase
        Implements IMASLayoutParticipant
        Implements IMASIntrinsicSizeContract

#Region "Fields"

        Private Shared ReadOnly _contract As MASResolvedComponentContract =
            MASArchitectureRuntime.ResolveContractOrThrow(GetType(MASPagination))

        Private _currentPage As Integer = PaginationTokens.DefaultCurrentPage
        Private _totalPages As Integer = PaginationTokens.DefaultTotalPages
        Private _pageWindow As Integer = PaginationTokens.DefaultPageWindow
        Private _hoverNodeIndex As Integer = -1
        Private _pressedNodeIndex As Integer = -1
        Private _lastNodes() As PageNode = Array.Empty(Of PageNode)()
        Private _lastLayoutPlan As MASPaginationLayoutPlan
        Private _lastRenderedRtl As Boolean
        Private _selectionMotionRunner As MASMotionTimelineRunner
        Private _selectionMotionFromPage As Integer = -1
        Private _selectionMotionToPage As Integer = -1
        Private _selectionMotionProgress As Single = 1.0F
        Private _hasSelectionMotion As Boolean
        Private _disposedLocal As Boolean

#End Region

#Region "Constructor"

        Public Sub New()
            MyBase.New()
        End Sub

#End Region

#Region "Public API"

        Public Event PageChanged As EventHandler

        Public Shared Function Create(Optional currentPage As Integer = 1,
                                      Optional totalPages As Integer = 1) As MASPagination
            Dim control As New MASPagination()
            control.Configure(totalPages, currentPage)
            Return control
        End Function

        Public Property CurrentPage As Integer
            Get
                Return _currentPage
            End Get
            Set(value As Integer)
                SetCurrentPageInternal(value, True)
            End Set
        End Property

        Public Property TotalPages As Integer
            Get
                Return _totalPages
            End Get
            Set(value As Integer)
                SetTotalPagesInternal(value, True)
            End Set
        End Property

        Public Property PageWindow As Integer
            Get
                Return _pageWindow
            End Get
            Set(value As Integer)
                Dim normalized As Integer = NormalizePageWindow(value)
                If _pageWindow = normalized Then Return

                _pageWindow = normalized
                RequestSizeLayoutRefreshForSizeAffectingChange("MASPagination.PageWindow")
                InvalidateVisual()
            End Set
        End Property

        Public ReadOnly Property CanMovePrevious As Boolean
            Get
                Return _currentPage > 1
            End Get
        End Property

        Public ReadOnly Property CanMoveNext As Boolean
            Get
                Return _currentPage < _totalPages
            End Get
        End Property

        Public Function Configure(totalPages As Integer,
                                  Optional currentPage As Integer = 1) As MASPagination
            Dim normalizedTotal As Integer = NormalizeTotalPages(totalPages)
            Dim normalizedPage As Integer = NormalizeCurrentPage(currentPage, normalizedTotal)
            Dim changed As Boolean = (_totalPages <> normalizedTotal OrElse _currentPage <> normalizedPage)

            _totalPages = normalizedTotal
            _currentPage = normalizedPage
            ResetPointerState()

            RequestSizeLayoutRefreshForSizeAffectingChange("MASPagination.Configure")
            InvalidateVisual()
            If changed Then RaisePageChangedSafe()
            Return Me
        End Function

        Public Function MoveFirst() As MASPagination
            SetCurrentPageInternal(1, True)
            Return Me
        End Function

        Public Function MovePrevious() As MASPagination
            SetCurrentPageInternal(_currentPage - 1, True)
            Return Me
        End Function

        Public Function MoveNext() As MASPagination
            SetCurrentPageInternal(_currentPage + 1, True)
            Return Me
        End Function

        Public Function MoveLast() As MASPagination
            SetCurrentPageInternal(_totalPages, True)
            Return Me
        End Function

        Public Function WithPageWindow(pageWindow As Integer) As MASPagination
            Me.PageWindow = pageWindow
            Return Me
        End Function

        Public Shadows Function WithSize(sizeIntent As MASSize) As MASPagination
            MyBase.SetSize(sizeIntent)
            Return Me
        End Function

#End Region

    End Class

End Namespace
