Option Strict On
Option Explicit On

Imports System
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Composition
Imports Nexamas.UI.Controls
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Official Nexamas UI premium split-surface visual component. It owns visual
    ''' left/content/right pane presentation, bounded divider resizing, collapsed pane
    ''' states, keyboard ratio movement, RTL-aware split geometry, and MAS surface /
    ''' typography routing. Dock engines, child-content hosting, shell routing,
    ''' persistence, native panel wrappers, and pointer-click outer focus rings remain
    ''' outside this control.
    ''' </summary>
    Partial Public NotInheritable Class MASSplitView
        Inherits MASControlBase
        Implements IMASLayoutParticipant
        Implements IMASIntrinsicSizeContract

#Region "Nested state"

        Private Enum SplitDividerSide
            None = 0
            Left = 1
            Right = 2
        End Enum

        Private Structure SplitViewGeometry
            Friend LeftPane As SKRect
            Friend LeftDivider As SKRect
            Friend ContentPane As SKRect
            Friend RightDivider As SKRect
            Friend RightPane As SKRect
        End Structure

#End Region


#Region "Fields"
        Private ReadOnly _primitives As New MASVisualPrimitivesPainter()
        Private _title As String = SplitViewTokens.DefaultTitle
        Private _leftPaneTitle As String = SplitViewTokens.DefaultLeftPaneTitle
        Private _contentPaneTitle As String = SplitViewTokens.DefaultContentPaneTitle
        Private _rightPaneTitle As String = SplitViewTokens.DefaultRightPaneTitle
        Private _leftPaneText As String = SplitViewTokens.DefaultLeftPaneText
        Private _contentPaneText As String = SplitViewTokens.DefaultContentPaneText
        Private _rightPaneText As String = SplitViewTokens.DefaultRightPaneText
        Private _leftPaneRatio As Single = SplitViewTokens.DefaultLeftRatio
        Private _rightPaneRatio As Single = SplitViewTokens.DefaultRightRatio
        Private _leftPaneCollapsed As Boolean
        Private _rightPaneCollapsed As Boolean
        Private _contentRect As SKRect = SKRect.Empty
        Private _bodyRect As SKRect = SKRect.Empty
        Private _leftDividerRect As SKRect = SKRect.Empty
        Private _rightDividerRect As SKRect = SKRect.Empty
        Private _hoverDivider As SplitDividerSide = SplitDividerSide.None
        Private _activeDivider As SplitDividerSide = SplitDividerSide.None
        Private _keyboardDivider As SplitDividerSide = SplitDividerSide.Left
        Private _dragStartPointerXPx As Single
        Private _dragStartLeftRatio As Single
        Private _dragStartRightRatio As Single
        Private _dragStartLeftCollapsed As Boolean
        Private _dragStartRightCollapsed As Boolean
        Private _dragStartBodyWidthPx As Single = 1.0F
        Private _dragStartIsRtl As Boolean
        Private _lastDpi As Single = 1.0F

#End Region


#Region "Constructor / Factory"

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

        Public Shared Function Create(Optional title As String = Nothing) As MASSplitView
            Dim control As New MASSplitView()
            control._title = MASSplitViewPolicy.NormalizeTitle(title)
            Return control
        End Function

#End Region


#Region "Public API"

        Public Event SplitViewChanged As EventHandler

        Public Property Title As String
            Get
                Return _title
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizeTitle(value)
                If String.Equals(_title, normalized, StringComparison.Ordinal) Then Return
                _title = normalized
                RequestSizeLayoutRefreshForSizeAffectingChange("MASSplitView.Title")
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property LeftPaneTitle As String
            Get
                Return _leftPaneTitle
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneTitle(value, SplitViewTokens.DefaultLeftPaneTitle)
                If String.Equals(_leftPaneTitle, normalized, StringComparison.Ordinal) Then Return
                _leftPaneTitle = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property ContentPaneTitle As String
            Get
                Return _contentPaneTitle
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneTitle(value, SplitViewTokens.DefaultContentPaneTitle)
                If String.Equals(_contentPaneTitle, normalized, StringComparison.Ordinal) Then Return
                _contentPaneTitle = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property RightPaneTitle As String
            Get
                Return _rightPaneTitle
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneTitle(value, SplitViewTokens.DefaultRightPaneTitle)
                If String.Equals(_rightPaneTitle, normalized, StringComparison.Ordinal) Then Return
                _rightPaneTitle = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property LeftPaneText As String
            Get
                Return _leftPaneText
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneText(value, SplitViewTokens.DefaultLeftPaneText)
                If String.Equals(_leftPaneText, normalized, StringComparison.Ordinal) Then Return
                _leftPaneText = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property ContentPaneText As String
            Get
                Return _contentPaneText
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneText(value, SplitViewTokens.DefaultContentPaneText)
                If String.Equals(_contentPaneText, normalized, StringComparison.Ordinal) Then Return
                _contentPaneText = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property RightPaneText As String
            Get
                Return _rightPaneText
            End Get
            Set(value As String)
                Dim normalized As String = MASSplitViewPolicy.NormalizePaneText(value, SplitViewTokens.DefaultRightPaneText)
                If String.Equals(_rightPaneText, normalized, StringComparison.Ordinal) Then Return
                _rightPaneText = normalized
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property LeftPaneRatio As Single
            Get
                Return _leftPaneRatio
            End Get
            Set(value As Single)
                Dim oldLeft As Single = _leftPaneRatio
                Dim oldRight As Single = _rightPaneRatio
                _leftPaneRatio = MASSplitViewPolicy.ClampRatio(value)
                MASSplitViewPolicy.NormalizeSideRatios(_leftPaneRatio, _rightPaneRatio)
                If Math.Abs(oldLeft - _leftPaneRatio) < 0.001F AndAlso Math.Abs(oldRight - _rightPaneRatio) < 0.001F Then Return
                _leftPaneCollapsed = False
                StartPaneRevealMotion(SplitDividerSide.Left) : RequestSizeLayoutRefreshForSizeAffectingChange("MASSplitView.LeftPaneRatio")
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property RightPaneRatio As Single
            Get
                Return _rightPaneRatio
            End Get
            Set(value As Single)
                Dim oldLeft As Single = _leftPaneRatio
                Dim oldRight As Single = _rightPaneRatio
                _rightPaneRatio = MASSplitViewPolicy.ClampRatio(value)
                MASSplitViewPolicy.NormalizeSideRatios(_leftPaneRatio, _rightPaneRatio)
                If Math.Abs(oldLeft - _leftPaneRatio) < 0.001F AndAlso Math.Abs(oldRight - _rightPaneRatio) < 0.001F Then Return
                _rightPaneCollapsed = False
                StartPaneRevealMotion(SplitDividerSide.Right) : RequestSizeLayoutRefreshForSizeAffectingChange("MASSplitView.RightPaneRatio")
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property IsLeftPaneCollapsed As Boolean
            Get
                Return _leftPaneCollapsed
            End Get
            Set(value As Boolean)
                If _leftPaneCollapsed = value Then Return
                _leftPaneCollapsed = value
                StartPaneRevealMotion(SplitDividerSide.Left) : RequestSizeLayoutRefreshForSizeAffectingChange("MASSplitView.IsLeftPaneCollapsed")
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public Property IsRightPaneCollapsed As Boolean
            Get
                Return _rightPaneCollapsed
            End Get
            Set(value As Boolean)
                If _rightPaneCollapsed = value Then Return
                _rightPaneCollapsed = value
                StartPaneRevealMotion(SplitDividerSide.Right) : RequestSizeLayoutRefreshForSizeAffectingChange("MASSplitView.IsRightPaneCollapsed")
                InvalidateVisual()
                RaiseSplitViewChangedSafe()
            End Set
        End Property

        Public ReadOnly Property SummaryText As String
            Get
                Return MASSplitViewPolicy.BuildSummary(_leftPaneCollapsed, _rightPaneCollapsed, _leftPaneRatio, _rightPaneRatio)
            End Get
        End Property

        Public Function SetPaneTexts(leftText As String,
                                     contentText As String,
                                     rightText As String) As MASSplitView
            LeftPaneText = leftText
            ContentPaneText = contentText
            RightPaneText = rightText
            Return Me
        End Function

        Public Function CollapseLeft(Optional collapsed As Boolean = True) As MASSplitView
            IsLeftPaneCollapsed = collapsed
            Return Me
        End Function

        Public Function CollapseRight(Optional collapsed As Boolean = True) As MASSplitView
            IsRightPaneCollapsed = collapsed
            Return Me
        End Function

        Public Function ExpandAll() As MASSplitView
            IsLeftPaneCollapsed = False
            IsRightPaneCollapsed = False
            Return Me
        End Function

        Public Function WithTitle(value As String) As MASSplitView
            Title = value
            Return Me
        End Function

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

#End Region

    End Class

End Namespace
