Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
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 master/detail visual surface. It owns master
    ''' item presentation, detail preview presentation, selection, keyboard movement,
    ''' RTL-aware split geometry, and MAS surface/typography routing. Data binding,
    ''' routing, storage, providers, inspector services, wrappers, adapters, bridges,
    ''' and pointer-click outer focus rings remain outside this control.
    ''' </summary>
    Partial Public NotInheritable Class MASMasterDetailView
        Inherits MASControlBase
        Implements IMASLayoutParticipant
        Implements IMASIntrinsicSizeContract
#Region "Fields"
        Private ReadOnly _primitives As New MASVisualPrimitivesPainter()
        Private ReadOnly _items As New List(Of MasterDetailItemState)()
        Private ReadOnly _hits As New List(Of MasterDetailItemHit)()
        Private _title As String = MasterDetailViewTokens.DefaultTitle
        Private _selectedIndex As Integer = -1
        Private _hoverIndex As Integer = -1
        Private _pressedIndex As Integer = -1
        Private _topIndex As Integer
        Private _lastVisibleCount As Integer = MasterDetailViewTokens.MaxVisibleItems
        Private _contentRect As SKRect = SKRect.Empty
        Private _masterRect As SKRect = SKRect.Empty
        Private _detailRect As SKRect = SKRect.Empty
        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 MASMasterDetailView
            Dim control As New MASMasterDetailView()
            control._title = MASMasterDetailViewPolicy.NormalizeTitle(title)
            Return control
        End Function

#End Region

#Region "Public API"

        Public Event MasterDetailChanged As EventHandler
        Public Event SelectedItemChanged As EventHandler

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

        Public ReadOnly Property ItemCount As Integer
            Get
                Return _items.Count
            End Get
        End Property

        Public ReadOnly Property SelectedIndex As Integer
            Get
                Return _selectedIndex
            End Get
        End Property

        Public ReadOnly Property SelectedItemKey As String
            Get
                If _selectedIndex < 0 OrElse _selectedIndex >= _items.Count Then Return String.Empty
                Return _items(_selectedIndex).Key
            End Get
        End Property

        Public ReadOnly Property SummaryText As String
            Get
                Return MASMasterDetailViewPolicy.BuildSummary(ItemCount, _selectedIndex)
            End Get
        End Property

        Public Function GetItemKeys() As IReadOnlyList(Of String)
            Dim keys As New List(Of String)()
            For Each item As MasterDetailItemState In _items
                keys.Add(item.Key)
            Next
            Return New ReadOnlyCollection(Of String)(keys)
        End Function

        Public Function AddItem(itemKey As String,
                                title As String,
                                Optional subtitle As String = Nothing,
                                Optional detailTitle As String = Nothing,
                                Optional detailText As String = Nothing,
                                Optional badgeText As String = Nothing) As MASMasterDetailView
            ClearMasterDetailSourceLinkForManualMutation()
            ClearMasterDetailStatusState("MASMasterDetailView.AddItem")
            If _items.Count >= MasterDetailViewTokens.MaxItems Then Return Me
            Dim normalizedKey As String = MASMasterDetailViewPolicy.NormalizeKey(itemKey, "item", _items.Count + 1)
            If FindItemIndex(normalizedKey) >= 0 Then Return Me
            _items.Add(New MasterDetailItemState(normalizedKey,
                                                 MASMasterDetailViewPolicy.NormalizeItemTitle(title),
                                                 MASMasterDetailViewPolicy.NormalizeSubtitle(subtitle),
                                                 MASMasterDetailViewPolicy.NormalizeDetailTitle(detailTitle, title),
                                                 MASMasterDetailViewPolicy.NormalizeDetailText(detailText),
                                                 MASMasterDetailViewPolicy.NormalizeBadgeText(badgeText)))
            If _selectedIndex < 0 Then _selectedIndex = 0
            StopSelectionMotion() : RequestSizeLayoutRefreshForSizeAffectingChange("MASMasterDetailView.AddItem")
            InvalidateVisual()
            RaiseMasterDetailChangedSafe()
            Return Me
        End Function

        Public Function ClearItems() As MASMasterDetailView
            ClearMasterDetailSourceLinkForManualMutation()
            _items.Clear()
            _hits.Clear()
            _selectedIndex = -1
            _hoverIndex = -1
            _pressedIndex = -1
            _topIndex = 0
            StopSelectionMotion() : SetMasterDetailEmptyState(MasterDetailViewTokens.EmptyMasterText, "MASMasterDetailView.ClearItems")
            RequestSizeLayoutRefreshForSizeAffectingChange("MASMasterDetailView.ClearItems")
            InvalidateVisual()
            RaiseMasterDetailChangedSafe()
            Return Me
        End Function

        Public Function SelectItem(itemKey As String) As Boolean
            Dim index As Integer = FindItemIndex(itemKey)
            If index < 0 Then Return False
            SetSelectedIndex(index, True)
            Return True
        End Function

        Public Function MovePrevious() As MASMasterDetailView
            MoveBy(-1)
            Return Me
        End Function

        Public Function MoveNext() As MASMasterDetailView
            MoveBy(1)
            Return Me
        End Function

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

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

#End Region

    End Class

End Namespace
