Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Controls
Imports Nexamas.UI.FloatRuntime
Imports Nexamas.UI.Host

Namespace Nexamas.UI.Application

    ''' <summary>
    ''' Beginner-facing service facade for one MASApplicationWindow.
    ''' It reuses the existing RootHost-backed service implementations and does not create parallel runtimes.
    ''' </summary>
    Public NotInheritable Class MASApplicationWindowServices
        Implements IDisposable

        Private ReadOnly _rootHost As MASSkiaRootHost
        Private ReadOnly _dialogs As MASApplicationWindowDialogs
        Private ReadOnly _contextMenus As MASApplicationWindowContextMenus
        Private ReadOnly _fileExplorerService As MASFileExplorerService
        Private ReadOnly _filePickerService As MASFilePickerService
        Private ReadOnly _fileExplorer As MASApplicationWindowFileExplorer
        Private ReadOnly _filePicker As MASApplicationWindowFilePicker
        Private ReadOnly _toasts As MASApplicationWindowToasts
        Private ReadOnly _tooltips As MASApplicationWindowTooltips
        Private ReadOnly _progress As MASApplicationWindowProgress
        Private ReadOnly _ownedDisposables As New List(Of IDisposable)()
        Private _disposed As Boolean

        Friend Sub New(rootHost As MASSkiaRootHost)
            If rootHost Is Nothing Then Throw New ArgumentNullException(NameOf(rootHost))

            _rootHost = rootHost
            _dialogs = New MASApplicationWindowDialogs(_rootHost)
            _contextMenus = New MASApplicationWindowContextMenus(_rootHost)
            _fileExplorerService = New MASFileExplorerService(_rootHost)
            _filePickerService = New MASFilePickerService(_rootHost)
            _fileExplorer = New MASApplicationWindowFileExplorer(_fileExplorerService, AddressOf ThrowIfDisposed)
            _filePicker = New MASApplicationWindowFilePicker(_filePickerService, AddressOf ThrowIfDisposed)
            _toasts = New MASApplicationWindowToasts(New MASToastFloatService(_rootHost))
            _tooltips = New MASApplicationWindowTooltips(_rootHost.TooltipsCore, AddressOf ThrowIfDisposed)
            _progress = New MASApplicationWindowProgress(_rootHost)

            RegisterOwnedDisposable(_contextMenus)
            RegisterOwnedDisposable(_toasts)
        End Sub

        Public ReadOnly Property IsDisposed As Boolean
            Get
                Return _disposed
            End Get
        End Property

        Private Sub ThrowIfDisposed()
            If _disposed Then Throw New ObjectDisposedException(NameOf(MASApplicationWindowServices))
            _rootHost.ThrowIfDisposedCore()
        End Sub

        Public ReadOnly Property Dialogs As MASApplicationWindowDialogs
            Get
                ThrowIfDisposed()
                Return _dialogs
            End Get
        End Property

        Public ReadOnly Property ContextMenus As MASApplicationWindowContextMenus
            Get
                ThrowIfDisposed()
                Return _contextMenus
            End Get
        End Property

        Public ReadOnly Property FileExplorer As MASApplicationWindowFileExplorer
            Get
                ThrowIfDisposed()
                Return _fileExplorer
            End Get
        End Property

        Public ReadOnly Property FilePicker As MASApplicationWindowFilePicker
            Get
                ThrowIfDisposed()
                Return _filePicker
            End Get
        End Property

        Public ReadOnly Property Toasts As MASApplicationWindowToasts
            Get
                ThrowIfDisposed()
                Return _toasts
            End Get
        End Property

        Public ReadOnly Property Tooltips As MASApplicationWindowTooltips
            Get
                ThrowIfDisposed()
                Return _tooltips
            End Get
        End Property

        ''' <summary>
        ''' Official floating operation-progress facade for one MAS application window.
        ''' It hosts MASOperationProgressBox inside the root-owned FloatRuntime without creating a PanelShell dialog.
        ''' </summary>
        Public ReadOnly Property Progress As MASApplicationWindowProgress
            Get
                ThrowIfDisposed()
                Return _progress
            End Get
        End Property

        ''' <summary>
        ''' Advanced compatibility access to the underlying RootHost-backed file explorer service.
        ''' Prefer MASApplicationWindow.Services.FileExplorer for normal SDK code.
        ''' </summary>
        <Obsolete("AdvancedFileExplorer is a internal advanced compatibility hook. Prefer MASApplicationWindow.Services.FileExplorer for new SDK code.", True)>
        Friend ReadOnly Property AdvancedFileExplorer As MASFileExplorerService
            Get
                ThrowIfDisposed()
                Return _fileExplorerService
            End Get
        End Property

        ''' <summary>
        ''' Advanced compatibility access to the underlying RootHost-backed file picker service.
        ''' Prefer MASApplicationWindow.Services.FilePicker for normal SDK code.
        ''' </summary>
        <Obsolete("AdvancedFilePicker is a internal advanced compatibility hook. Prefer MASApplicationWindow.Services.FilePicker for new SDK code.", True)>
        Friend ReadOnly Property AdvancedFilePicker As MASFilePickerService
            Get
                ThrowIfDisposed()
                Return _filePickerService
            End Get
        End Property

        ''' <summary>
        ''' Advanced compatibility access to the root-owned Float runtime for framework extensions.
        ''' Prefer the typed window service and shell facades for normal SDK code.
        ''' </summary>
        <Obsolete("AdvancedFloatRuntime is a internal advanced compatibility hook. Prefer MASApplicationWindow.Services/Shell typed facades for new SDK code.", True)>
        Friend ReadOnly Property AdvancedFloatRuntime As MASFloatRuntime
            Get
                ThrowIfDisposed()
                Return _rootHost.FloatRuntimeCore
            End Get
        End Property

        Private Sub RegisterOwnedDisposable(value As IDisposable)
            If value Is Nothing Then Return
            _ownedDisposables.Add(value)
        End Sub

        Public Sub Dispose() Implements IDisposable.Dispose
            If _disposed Then Return
            _disposed = True

            ' Ownership contract:
            ' - ContextMenus and Toasts allocate disposable helper services and are disposed here.
            ' - Dialogs, FileExplorer, FilePicker, and Tooltips are facades over RootHost/FloatRuntime-owned lifecycles.
            ' - FileExplorerService/FilePickerService are non-disposable request builders; active surfaces close through FloatRuntime.
            For index As Integer = _ownedDisposables.Count - 1 To 0 Step -1
                Try
                    _ownedDisposables(index).Dispose()
                Catch masCaughtException1 As Exception
                    Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException1)
                End Try
            Next

            _ownedDisposables.Clear()
        End Sub

    End Class

End Namespace
