Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports Nexamas.UI.Components
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Host
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Theming
Imports Nexamas.UI.TextInput
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Application

    Partial Public NotInheritable Class MASApplicationWindowControls

        Public Sub Add(control As MASControlBase)
            ExecuteControlsUiThread(
                "Add",
                Sub()
                    AddCore(control)
                End Sub)
        End Sub


        Private Sub AddCore(control As MASControlBase)
            If control Is Nothing Then Throw New ArgumentNullException(NameOf(control))

            If TypeOf control Is MASMenuBar Then
                Throw New InvalidOperationException("MASMenuBar is application chrome and cannot be added as a page/direct control. Use window.Controls.AddMenuBar(...), which attaches the standard full-width MainMenuBar below the TopBar through the shell-owned chrome slot.")
            End If

            Dim wasAlreadyHosted As Boolean = ContainsCore(control)
            If IsRetainedLayoutBuildAdmissionActiveInternal() Then
                Layer.Add(control)
                AdmitRetainedLayoutBuildControlInternal(control, wasAlreadyHosted)
                Return
            End If

            AdoptConsumerOwnedControlInternal(control)
            Layer.Add(control)
        End Sub


        ''' <summary>
        ''' Adds a direct Skia MAS control to this window and returns the same typed instance for fluent consumer code.
        ''' Use this when the control was created manually or by a Create* method on this facade.
        ''' </summary>

        Public Function AddControl(Of TControl As MASControlBase)(control As TControl,
                                                                Optional configure As Action(Of TControl) = Nothing) As TControl
            Return ExecuteControlsUiThread(
                "AddControl",
                Function()
                    If control Is Nothing Then Throw New ArgumentNullException(NameOf(control))
                    If configure IsNot Nothing Then configure.Invoke(control)
                    AddCore(control)
                    Return control
                End Function)
        End Function

        Private Function AddCreatedControlInternal(Of TControl As MASControlBase)(control As TControl) As TControl
            Return ExecuteControlsUiThread(
                "AddCreatedControl",
                Function()
                    If control Is Nothing Then Throw New ArgumentNullException(NameOf(control))

                    Dim trackAsFactoryCreated As Boolean = Not IsRetainedLayoutBuildAdmissionActiveInternal()
                    Dim wasAlreadyHosted As Boolean = ContainsCore(control)

                    AddCore(control)

                    If trackAsFactoryCreated AndAlso Not wasAlreadyHosted AndAlso ContainsCore(control) Then
                        _factoryCreatedControls.Add(control)
                    End If

                    Return control
                End Function)
        End Function

        Private Shared Function ConfigureControl(Of TControl As MASControlBase)(control As TControl,
                                                                              configure As Action(Of TControl)) As TControl
            If control Is Nothing Then Throw New ArgumentNullException(NameOf(control))
            If configure IsNot Nothing Then configure.Invoke(control)
            Return control
        End Function
    End Class

End Namespace
