Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Components
Imports Nexamas.UI.FileSystem
Imports Nexamas.UI.FloatRuntime
Imports SkiaSharp

Namespace Nexamas.UI.Application

    ''' <summary>
    ''' Hosted file picker facade for MASApplicationWindow.Services.
    ''' Keeps raw/unhosted file picker creation behind the application entry surface; SDK consumers use Show* hosted routes or control factories.
    ''' </summary>
    Public NotInheritable Class MASApplicationWindowFilePicker

        Private Const DefaultOwnerKey As String = "MAS.FilePicker.Service"
        Private ReadOnly _service As MASFilePickerService
        Private ReadOnly _throwIfDisposed As Action

        Private ReadOnly Property Service As MASFilePickerService
            Get
                _throwIfDisposed.Invoke()
                Return _service
            End Get
        End Property

        Friend Sub New(service As MASFilePickerService, throwIfDisposed As Action)
            If service Is Nothing Then Throw New ArgumentNullException(NameOf(service))
            If throwIfDisposed Is Nothing Then Throw New ArgumentNullException(NameOf(throwIfDisposed))
            _service = service
            _throwIfDisposed = throwIfDisposed
        End Sub

        Friend Function Create(options As MASFilePickerOptions) As MASFilePickerControl
            Return Service.Create(options)
        End Function

        Friend Function OpenFile(Optional title As String = "Open File",
                                 Optional initialPath As String = "",
                                 Optional filter As String = "*.*",
                                 Optional showHidden As Boolean = False,
                                 Optional allowMultiSelect As Boolean = False,
                                 Optional footerText As String = "",
                                 Optional primaryButtonText As String = "") As MASFilePickerControl
            Return Service.OpenFile(title, initialPath, filter, showHidden, allowMultiSelect, footerText, primaryButtonText)
        End Function

        Friend Function SaveFile(Optional title As String = "Save File",
                                 Optional initialPath As String = "",
                                 Optional filter As String = "*.*",
                                 Optional fileName As String = "",
                                 Optional confirmOverwrite As Boolean = True,
                                 Optional showHidden As Boolean = False,
                                 Optional primaryButtonText As String = "",
                                 Optional footerText As String = "") As MASFilePickerControl
            Return Service.SaveFile(title, initialPath, filter, fileName, confirmOverwrite, showHidden, primaryButtonText, footerText)
        End Function

        Friend Function PickFolder(Optional title As String = "Select Folder",
                                   Optional initialPath As String = "",
                                   Optional showHidden As Boolean = False,
                                   Optional primaryButtonText As String = "",
                                   Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                   Optional footerText As String = "") As MASFilePickerControl
            Return Service.PickFolder(title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText)
        End Function

        Friend Function PickTargets(targetKinds As MASFileSystemSelectionKinds,
                                    Optional title As String = "Select Targets",
                                    Optional initialPath As String = "",
                                    Optional showHidden As Boolean = False,
                                    Optional allowMultiSelect As Boolean = False,
                                    Optional primaryButtonText As String = "",
                                    Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                    Optional footerText As String = "") As MASFilePickerControl
            Return Service.PickTargets(targetKinds, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText)
        End Function

        Friend Function PickDrive(Optional title As String = "Select Drive",
                                  Optional initialPath As String = "",
                                  Optional showHidden As Boolean = False,
                                  Optional allowMultiSelect As Boolean = False,
                                  Optional primaryButtonText As String = "",
                                  Optional footerText As String = "") As MASFilePickerControl
            Return Service.PickDrive(title, initialPath, showHidden, allowMultiSelect, primaryButtonText, footerText)
        End Function

        Friend Function PickFolders(Optional title As String = "Select Folders",
                                    Optional initialPath As String = "",
                                    Optional showHidden As Boolean = False,
                                    Optional primaryButtonText As String = "",
                                    Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                    Optional footerText As String = "") As MASFilePickerControl
            Return Service.PickFolders(title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText)
        End Function

        Friend Function PickFolderOrDrive(Optional title As String = "Select Targets",
                                          Optional initialPath As String = "",
                                          Optional showHidden As Boolean = False,
                                          Optional allowMultiSelect As Boolean = True,
                                          Optional primaryButtonText As String = "",
                                          Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                          Optional footerText As String = "") As MASFilePickerControl
            Return Service.PickFolderOrDrive(title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText)
        End Function

        Public Function ShowOpenFile(Optional ownerKey As String = DefaultOwnerKey,
                                     Optional title As String = "Open File",
                                     Optional initialPath As String = "",
                                     Optional filter As String = "*.*",
                                     Optional showHidden As Boolean = False,
                                     Optional allowMultiSelect As Boolean = False,
                                     Optional footerText As String = "",
                                     Optional primaryButtonText As String = "",
                                     Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                     Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                     Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                     Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowOpenFileEx(ownerKey, title, initialPath, filter, showHidden, allowMultiSelect, footerText, primaryButtonText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowOpenFileEx(Optional ownerKey As String = DefaultOwnerKey,
                                       Optional title As String = "Open File",
                                       Optional initialPath As String = "",
                                       Optional filter As String = "*.*",
                                       Optional showHidden As Boolean = False,
                                       Optional allowMultiSelect As Boolean = False,
                                       Optional footerText As String = "",
                                       Optional primaryButtonText As String = "",
                                       Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                       Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                       Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                       Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowOpenFileEx(ownerKey, title, initialPath, filter, showHidden, allowMultiSelect, footerText, primaryButtonText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowSaveFile(Optional ownerKey As String = DefaultOwnerKey,
                                     Optional title As String = "Save File",
                                     Optional initialPath As String = "",
                                     Optional filter As String = "*.*",
                                     Optional fileName As String = "",
                                     Optional confirmOverwrite As Boolean = True,
                                     Optional showHidden As Boolean = False,
                                     Optional primaryButtonText As String = "",
                                     Optional footerText As String = "",
                                     Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                     Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                     Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                     Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowSaveFileEx(ownerKey, title, initialPath, filter, fileName, confirmOverwrite, showHidden, primaryButtonText, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowSaveFileEx(Optional ownerKey As String = DefaultOwnerKey,
                                       Optional title As String = "Save File",
                                       Optional initialPath As String = "",
                                       Optional filter As String = "*.*",
                                       Optional fileName As String = "",
                                       Optional confirmOverwrite As Boolean = True,
                                       Optional showHidden As Boolean = False,
                                       Optional primaryButtonText As String = "",
                                       Optional footerText As String = "",
                                       Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                       Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                       Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                       Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowSaveFileEx(ownerKey, title, initialPath, filter, fileName, confirmOverwrite, showHidden, primaryButtonText, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowPickFolder(Optional ownerKey As String = DefaultOwnerKey,
                                       Optional title As String = "Select Folder",
                                       Optional initialPath As String = "",
                                       Optional showHidden As Boolean = False,
                                       Optional primaryButtonText As String = "",
                                       Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                       Optional footerText As String = "",
                                       Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                       Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                       Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                       Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowPickFolderEx(ownerKey, title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowPickFolderEx(Optional ownerKey As String = DefaultOwnerKey,
                                         Optional title As String = "Select Folder",
                                         Optional initialPath As String = "",
                                         Optional showHidden As Boolean = False,
                                         Optional primaryButtonText As String = "",
                                         Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                         Optional footerText As String = "",
                                         Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                         Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                         Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                         Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowPickFolderEx(ownerKey, title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowPickTargets(ownerKey As String,
                                        targetKinds As MASFileSystemSelectionKinds,
                                        Optional title As String = "Select Targets",
                                        Optional initialPath As String = "",
                                        Optional showHidden As Boolean = False,
                                        Optional allowMultiSelect As Boolean = False,
                                        Optional primaryButtonText As String = "",
                                        Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                        Optional footerText As String = "",
                                        Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                        Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                        Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                        Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowPickTargetsEx(ownerKey, targetKinds, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowPickTargetsEx(ownerKey As String,
                                          targetKinds As MASFileSystemSelectionKinds,
                                          Optional title As String = "Select Targets",
                                          Optional initialPath As String = "",
                                          Optional showHidden As Boolean = False,
                                          Optional allowMultiSelect As Boolean = False,
                                          Optional primaryButtonText As String = "",
                                          Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                          Optional footerText As String = "",
                                          Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                          Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                          Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                          Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowPickTargetsEx(ownerKey, targetKinds, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowPickDrive(Optional ownerKey As String = DefaultOwnerKey,
                                      Optional title As String = "Select Drive",
                                      Optional initialPath As String = "",
                                      Optional showHidden As Boolean = False,
                                      Optional allowMultiSelect As Boolean = False,
                                      Optional primaryButtonText As String = "",
                                      Optional footerText As String = "",
                                      Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                      Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                      Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                      Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowPickDriveEx(ownerKey, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowPickDriveEx(Optional ownerKey As String = DefaultOwnerKey,
                                        Optional title As String = "Select Drive",
                                        Optional initialPath As String = "",
                                        Optional showHidden As Boolean = False,
                                        Optional allowMultiSelect As Boolean = False,
                                        Optional primaryButtonText As String = "",
                                        Optional footerText As String = "",
                                        Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                        Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                        Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                        Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowPickDriveEx(ownerKey, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowPickFolders(Optional ownerKey As String = DefaultOwnerKey,
                                        Optional title As String = "Select Folders",
                                        Optional initialPath As String = "",
                                        Optional showHidden As Boolean = False,
                                        Optional primaryButtonText As String = "",
                                        Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                        Optional footerText As String = "",
                                        Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                        Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                        Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                        Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowPickFoldersEx(ownerKey, title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowPickFoldersEx(Optional ownerKey As String = DefaultOwnerKey,
                                          Optional title As String = "Select Folders",
                                          Optional initialPath As String = "",
                                          Optional showHidden As Boolean = False,
                                          Optional primaryButtonText As String = "",
                                          Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                          Optional footerText As String = "",
                                          Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                          Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                          Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                          Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowPickFoldersEx(ownerKey, title, initialPath, showHidden, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        Public Function ShowPickFolderOrDrive(Optional ownerKey As String = DefaultOwnerKey,
                                              Optional title As String = "Select Targets",
                                              Optional initialPath As String = "",
                                              Optional showHidden As Boolean = False,
                                              Optional allowMultiSelect As Boolean = True,
                                              Optional primaryButtonText As String = "",
                                              Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                              Optional footerText As String = "",
                                              Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                              Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                              Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                              Optional onCancelled As Action = Nothing) As MASApplicationSurfaceHandle

            Return ToCompatibilitySurfaceHandle(
                ShowPickFolderOrDriveEx(ownerKey, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, onOpened, onClosed, onAccepted, onCancelled))
        End Function

        Friend Function ShowPickFolderOrDriveEx(Optional ownerKey As String = DefaultOwnerKey,
                                                Optional title As String = "Select Targets",
                                                Optional initialPath As String = "",
                                                Optional showHidden As Boolean = False,
                                                Optional allowMultiSelect As Boolean = True,
                                                Optional primaryButtonText As String = "",
                                                Optional acceptCurrentPathWhenNoSelection As Boolean = False,
                                                Optional footerText As String = "",
                                                Optional onOpened As Action(Of MASApplicationOpenedEventArgs) = Nothing,
                                                Optional onClosed As Action(Of MASApplicationClosedEventArgs) = Nothing,
                                                Optional onAccepted As Action(Of MASFilePickerResult) = Nothing,
                                                Optional onCancelled As Action = Nothing) As MASApplicationSurfaceShowResult

            Return MASApplicationSurfaceShowResult.FromFloatShowResult(
                Service.ShowPickFolderOrDriveEx(ownerKey, title, initialPath, showHidden, allowMultiSelect, primaryButtonText, acceptCurrentPathWhenNoSelection, footerText, ToApplicationOpenedCallback(onOpened), ToApplicationClosedCallback(onClosed), onAccepted, onCancelled))
        End Function

        ''' <summary>
        ''' Returns whether a file-picker surface handle is still open through this window service.
        ''' </summary>
        Public Function IsOpen(handle As MASApplicationSurfaceHandle) As Boolean
            If handle Is Nothing Then Return False
            Return Service.IsOpen(handle.FloatHandleCore)
        End Function

        ''' <summary>
        ''' Closes a file-picker surface previously returned by a Show* method.
        ''' </summary>
        Public Sub Close(handle As MASApplicationSurfaceHandle,
                         Optional reason As MASApplicationCloseReason = MASApplicationCloseReason.Programmatic)

            If handle Is Nothing Then Return
            Service.Close(handle.FloatHandleCore, MASApplicationSurfaceContractMapper.ToFloatCloseReason(reason))
        End Sub

        ''' <summary>
        ''' Closes only file-picker surfaces whose owner key is currently owned by this service.
        ''' </summary>
        Public Sub CloseByOwner(ownerKey As String,
                                Optional reason As MASApplicationCloseReason = MASApplicationCloseReason.Programmatic)

            Service.CloseByOwner(ownerKey, MASApplicationSurfaceContractMapper.ToFloatCloseReason(reason))
        End Sub

        Friend Function GetDefaultAvailableBoundsLogical() As SKRect
            Return Service.GetDefaultAvailableBoundsLogical()
        End Function

        Private Shared Function ToApplicationOpenedCallback(onOpened As Action(Of MASApplicationOpenedEventArgs)) As Action(Of MASFloatHandle)
            If onOpened Is Nothing Then Return Nothing

            Return Sub(handle As MASFloatHandle)
                       Dim args As MASApplicationOpenedEventArgs = MASApplicationOpenedEventArgs.FromFloatHandle(handle)
                       If args IsNot Nothing Then onOpened.Invoke(args)
                   End Sub
        End Function

        Private Shared Function ToApplicationClosedCallback(onClosed As Action(Of MASApplicationClosedEventArgs)) As Action(Of MASFloatClosedEventArgs)
            If onClosed Is Nothing Then Return Nothing

            Return Sub(args As MASFloatClosedEventArgs)
                       onClosed.Invoke(MASApplicationClosedEventArgs.FromFloatEventArgs(args))
                   End Sub
        End Function

        Private Shared Function ToCompatibilitySurfaceHandle(result As MASApplicationSurfaceShowResult) As MASApplicationSurfaceHandle
            If result Is Nothing Then Return Nothing

            If result.Status = MASApplicationSurfaceShowStatus.Rejected Then
                Throw New InvalidOperationException("Application surface show rejected: " & result.Reason)
            End If

            Return result.Handle
        End Function

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

    End Class

End Namespace
