Option Strict On
Option Explicit On

Namespace Nexamas.UI.FloatRuntime

    ' ============================================================
    ' MASFloatRuntime Contract
    ' Class: MASFloatFocusManager
    '
    ' Purpose:
    '   Coordinates focus ownership for active Floats.
    '
    ' Responsibility:
    '   Tracks which Float currently owns focus and provides explicit
    '   focus handoff/restore points for Nexamas UI integration.
    '
    ' Owns:
    '   Current focus-owner handle reference.
    '   Previous focus token reference.
    '
    ' Does Not Own:
    '   Platform focus APIs.
    '   WinForms focus calls.
    '   Keyboard routing.
    '   Text input routing.
    '   Lifecycle authorization.
    '   Host state.
    '   Result delivery.
    '
    ' Allowed Dependencies:
    '   MASFloatHandle.
    '   MASFloatLifecycleRecord.
    '   MASFloatCapabilities.
    '
    ' Forbidden Dependencies:
    '   Legacy Overlay classes.
    '   OverlayHost.
    '   OverlayManager.
    '   OverlayContent.
    '   OverlayLayer.
    '   OverlayService.
    '   WinForms Control focus implementation.
    '   Feature-owned lifecycle services.
    '
    ' Lifecycle Role:
    '   Called by Coordinator/Input flow when a Float opens or closes.
    '   Does not open or close Floats by itself.
    '
    ' Threading:
    '   Must be accessed on the runtime/UI path.
    '   Does not perform random UI marshaling.
    '
    ' Mutation Rules:
    '   Focus owner may be changed only through runtime-owned flow.
    '   Previous focus token is opaque and belongs to Nexamas UI adapter.
    '
    ' Invariants:
    '   Focus ownership is explicit.
    '   Only Floats with OwnsFocus capability should become focus owner.
    '   Stale handles must not clear or replace newer focus ownership.
    '
    ' Failure Rules:
    '   Missing records are ignored.
    '   Restore for stale handles is ignored.
    ' ============================================================
    Friend NotInheritable Class MASFloatFocusManager

        Private _currentFocusOwner As MASFloatHandle
        Private _previousFocusToken As Object

        Friend ReadOnly Property CurrentFocusOwner As MASFloatHandle
            Get
                Return _currentFocusOwner
            End Get
        End Property

        Friend ReadOnly Property HasFocusOwner As Boolean
            Get
                Return _currentFocusOwner IsNot Nothing
            End Get
        End Property

        Friend Sub CaptureForOpening(
            record As MASFloatLifecycleRecord,
            previousFocusToken As Object
        )
            If record Is Nothing OrElse
               record.ResolvedRequest Is Nothing OrElse
               record.ResolvedRequest.Descriptor Is Nothing Then
                Return
            End If

            If Not record.ResolvedRequest.Descriptor.Capabilities.HasFlag(MASFloatCapabilities.OwnsFocus) Then
                Return
            End If

            _previousFocusToken = previousFocusToken
            _currentFocusOwner = record.Handle
        End Sub

        Friend Function ShouldRouteKeyboardTo(
            record As MASFloatLifecycleRecord
        ) As Boolean
            If record Is Nothing OrElse record.Handle Is Nothing Then
                Return False
            End If

            If _currentFocusOwner Is Nothing Then
                Return False
            End If

            Return IsSameHandle(_currentFocusOwner, record.Handle)
        End Function

        Friend Function ReleaseForClosing(
            handle As MASFloatHandle,
            ByRef previousFocusToken As Object
        ) As Boolean
            previousFocusToken = Nothing

            If handle Is Nothing OrElse _currentFocusOwner Is Nothing Then
                Return False
            End If

            If Not IsSameHandle(_currentFocusOwner, handle) Then
                Return False
            End If

            previousFocusToken = _previousFocusToken
            _previousFocusToken = Nothing
            _currentFocusOwner = Nothing

            Return True
        End Function

        Friend Sub Clear()
            _previousFocusToken = Nothing
            _currentFocusOwner = Nothing
        End Sub

        Private Shared Function IsSameHandle(
            left As MASFloatHandle,
            right As MASFloatHandle
        ) As Boolean
            If left Is Nothing OrElse right Is Nothing Then
                Return False
            End If

            Return left.Id = right.Id AndAlso left.Generation = right.Generation
        End Function

    End Class

End Namespace