Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Components.ContextMenu
Imports Nexamas.UI.Components.DropDownMenu
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Host
Imports SkiaSharp

Namespace Nexamas.UI.Application

    ''' <summary>
    ''' Beginner-facing context menu API for one MASApplicationWindow.
    ''' It keeps context-menu registration under window.Services instead of exposing RootHost wiring.
    ''' </summary>
    Public NotInheritable Class MASApplicationWindowContextMenus
        Implements IDisposable

        Private Const DefaultOwnerKey As String = "MAS.Application.ContextMenus"

        Private ReadOnly _coordinator As MASContextMenuCoordinator
        Private _disposed As Boolean

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

            _coordinator = MASContextMenuService.CreateCore(
                rootHost:=rootHost,
                invalidate:=AddressOf rootHost.RequestInvalidate,
                ownerKey:=DefaultOwnerKey)
        End Sub

        ''' <summary>
        ''' Registers a right-click context menu scope using a logical-space region.
        ''' </summary>
        Public Function Register(key As String,
                                 regionLogical As SKRect,
                                 buildMenu As Action(Of MASDropDownMenuBuilder)) As MASApplicationWindowContextMenus

            ThrowIfDisposed()
            If buildMenu Is Nothing Then Throw New ArgumentNullException(NameOf(buildMenu))

            _coordinator.AddScope(
                key:=NormalizeKey(key),
                regionLogical:=regionLogical,
                buildMenu:=buildMenu)

            Return Me
        End Function
        Public Function OnCommand(handler As Action(Of String)) As MASApplicationWindowContextMenus
            ThrowIfDisposed()
            If handler Is Nothing Then Return Me

            _coordinator.OnCommandInvoked(
                Sub(sender As MASContextMenuCoordinator, commandId As String)
                    handler.Invoke(commandId)
                End Sub)

            Return Me
        End Function

        Friend Function OnCommandInvoked(handler As EventHandler(Of MASContextMenuCommandEventArgs)) As MASApplicationWindowContextMenus
            ThrowIfDisposed()
            If handler Is Nothing Then Return Me

            _coordinator.OnCommandInvoked(handler)
            Return Me
        End Function

        Public Sub Clear()
            ThrowIfDisposed()
            _coordinator.ClearScopes()
        End Sub

        Public Sub Close()
            ThrowIfDisposed()
            _coordinator.Close()
        End Sub

        ''' <summary>
        ''' Internal access to the root-backed coordinator for MAS-owned integrations.
        ''' </summary>
        Friend ReadOnly Property CoordinatorCore As MASContextMenuCoordinator
            Get
                ThrowIfDisposed()
                Return _coordinator
            End Get
        End Property

        Private Shared Function NormalizeKey(key As String) As String
            Dim safe As String = If(key, String.Empty).Trim()
            If safe.Length = 0 Then Return "ContextMenuScope"
            Return safe
        End Function

        Private Sub ThrowIfDisposed()
            If _disposed Then
                Throw New ObjectDisposedException(NameOf(MASApplicationWindowContextMenus))
            End If
        End Sub

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

            Try
                _coordinator.Dispose()
            Catch masCaughtException1 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException1)
            End Try
        End Sub

    End Class

End Namespace
