'========================================================
' File: MASTileBox.vb  (SSOT + Fixes + Fluent SDK API)
'========================================================
Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Composition
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Motion
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Scroll
Imports Nexamas.UI.SkiaScroll
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Values
Imports Nexamas.UI.Virtualization
Imports SkiaSharp


Namespace Nexamas.UI.Components

    Partial Public NotInheritable Class MASTileBox

        Public NotInheritable Class MASTileClickedEventArgs
            Inherits EventArgs

            Public ReadOnly Property Index As Integer

            Friend Sub New(i As Integer)
                Index = i
            End Sub
        End Class

        Public ReadOnly Property Items As IReadOnlyList(Of MASTileItem)
            Get
                If _itemsView Is Nothing Then
                    _itemsView = _items.AsReadOnly()
                End If

                Return _itemsView
            End Get
        End Property

        Public Function AddItem(item As MASTileItem) As MASTileBox

            If item Is Nothing Then
                Throw New ArgumentNullException(NameOf(item))
            End If

            PrepareItemBitmapSnapshot(item)
            _items.Add(item)

            MarkTileCollectionChanged()
            MarkFrameCacheDirty()
            InvalidateVisual()

            Return Me

        End Function

        Public Function AddItem(title As String,
                                subtitle As String,
                                bitmap As SKBitmap) As MASTileBox

            Return AddItem(New MASTileItem(title, subtitle, bitmap))

        End Function

        ''' <summary>
        ''' Adds a bitmap-backed tile and transfers bitmap disposal to the tile item when requested.
        ''' </summary>
        Public Function AddItem(title As String,
                                subtitle As String,
                                bitmap As SKBitmap,
                                takeOwnership As Boolean) As MASTileBox

            Return AddItem(New MASTileItem(title, subtitle, bitmap, takeOwnership))

        End Function

        ''' <summary>
        ''' Adds a bitmap-backed tile with an explicit bitmap disposer.
        ''' </summary>
        Public Function AddItem(title As String,
                                subtitle As String,
                                bitmap As SKBitmap,
                                bitmapDisposer As Action(Of SKBitmap)) As MASTileBox

            Return AddItem(New MASTileItem(title, subtitle, bitmap, bitmapDisposer))

        End Function

        Public Function AddItem(title As String,
                                subtitle As String,
                                iconId As Guid,
                                provider As Func(Of SKBitmap)) As MASTileBox

            If provider Is Nothing Then
                Throw New ArgumentNullException(NameOf(provider))
            End If

            Return AddItem(New MASTileItem(title, subtitle, iconId, provider))

        End Function

        ''' <summary>
        ''' Adds a provider-backed tile and transfers resolved provider-snapshot disposal
        ''' to the tile item when requested.
        ''' </summary>
        Public Function AddItem(title As String,
                                subtitle As String,
                                iconId As Guid,
                                provider As Func(Of SKBitmap),
                                takeOwnership As Boolean) As MASTileBox

            If provider Is Nothing Then
                Throw New ArgumentNullException(NameOf(provider))
            End If

            Return AddItem(New MASTileItem(title, subtitle, iconId, provider, takeOwnership))

        End Function

        ''' <summary>
        ''' Adds a provider-backed tile with an explicit disposer for resolved provider snapshots.
        ''' </summary>
        Public Function AddItem(title As String,
                                subtitle As String,
                                iconId As Guid,
                                provider As Func(Of SKBitmap),
                                bitmapDisposer As Action(Of SKBitmap)) As MASTileBox

            If provider Is Nothing Then
                Throw New ArgumentNullException(NameOf(provider))
            End If

            Return AddItem(New MASTileItem(title, subtitle, iconId, provider, bitmapDisposer))

        End Function

        Public Function AddItems(items As IEnumerable(Of MASTileItem)) As MASTileBox

            If items Is Nothing Then
                Throw New ArgumentNullException(NameOf(items))
            End If

            For Each item As MASTileItem In items
                If item IsNot Nothing Then
                    PrepareItemBitmapSnapshot(item)
                    _items.Add(item)
                End If
            Next

            MarkTileCollectionChanged()
            MarkFrameCacheDirty()
            InvalidateVisual()

            Return Me

        End Function

        Public Function ReplaceItems(items As IEnumerable(Of MASTileItem)) As MASTileBox

            If items Is Nothing Then
                Throw New ArgumentNullException(NameOf(items))
            End If

            ReleaseOwnedBitmapResourcesForItems(_items)
            _items.Clear()

            For Each item As MASTileItem In items
                If item IsNot Nothing Then
                    PrepareItemBitmapSnapshot(item)
                    _items.Add(item)
                End If
            Next

            MarkTileCollectionChanged()
            SetSelectionInternal(Guid.Empty, Nothing, raiseChanged:=False, invalidate:=False)

            _hoverIndex = -1
            _pressedIndex = -1

            ResetLayoutCache()
            MarkFrameCacheDirty()
            InvalidateVisual()

            Return Me

        End Function

        Public Function ClearItems() As MASTileBox

            ReleaseOwnedBitmapResourcesForItems(_items)
            _items.Clear()
            MarkTileCollectionChanged()

            SetSelectionInternal(Guid.Empty, Nothing, raiseChanged:=False, invalidate:=False)

            _hoverIndex = -1
            _pressedIndex = -1

            ResetLayoutCache()
            MarkFrameCacheDirty()
            InvalidateVisual()

            Return Me

        End Function

        Private Shared Sub PrepareItemBitmapSnapshot(item As MASTileItem)
            If item Is Nothing Then Return

            item.RefreshBitmapRenderSnapshot()
        End Sub

        Private Shared Sub ReleaseOwnedBitmapResourcesForItems(items As IEnumerable(Of MASTileItem))
            If items Is Nothing Then Return

            For Each item As MASTileItem In items
                If item Is Nothing Then Continue For

                Try
                    item.ReleaseOwnedBitmapResources()
                Catch masCaughtException As Exception
                    Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDisposeCleanup(masCaughtException)
                End Try
            Next
        End Sub

        Private Sub MarkTileCollectionChanged()
            StopSelectionMotion()

            If _itemCollectionRevision = Integer.MaxValue Then
                _itemCollectionRevision = 0
            Else
                _itemCollectionRevision += 1
            End If

            _lastVirtualizationPlan = Nothing
        End Sub

    End Class

End Namespace
