Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Host
Imports Nexamas.UI.Theming

Namespace Nexamas.UI.Application

    ''' <summary>
    ''' Beginner-facing theme facade exposed from one MASApplicationWindow.
    ''' The facade is window-owned for convenience, but theme selection is application-global.
    ''' ThemeManager/ThemeHost remain internal implementation details behind this stable facade.
    ''' </summary>
    Public NotInheritable Class MASApplicationWindowTheme

        Private ReadOnly _rootHost As MASSkiaRootHost

        Private ReadOnly Property RootHost As MASSkiaRootHost
            Get
                _rootHost.ThrowIfDisposedCore()
                Return _rootHost
            End Get
        End Property

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

        ''' <summary>
        ''' Advanced compatibility access to the per-window ThemeHost snapshot owner.
        ''' Beginner SDK code should prefer this facade's Current/TryUse/Use methods.
        ''' </summary>
        <Obsolete("Advanced raw ThemeHost access. Prefer Current/CurrentId/GetAll/TryUse/Use/Refresh on MASApplicationWindow.Theme for normal SDK code.", True)>
        Friend ReadOnly Property AdvancedThemeHost As ThemeHost
            Get
                Return RootHost.ThemeHostCore
            End Get
        End Property


        ''' <summary>
        ''' Nexamas UI currently uses one global application theme selection. This property makes
        ''' the scope explicit so window-level access does not imply independent per-window themes.
        ''' </summary>
        Public ReadOnly Property Scope As MASApplicationThemeScope
            Get
                Return MASApplicationThemeScope.GlobalApplication
            End Get
        End Property

        ''' <summary>
        ''' True because this facade changes ThemeManager.Current for the whole application process.
        ''' </summary>
        Public ReadOnly Property IsGlobalApplicationTheme As Boolean
            Get
                Return True
            End Get
        End Property

        Public ReadOnly Property Current As IMASAppTheme
            Get
                _rootHost.ThrowIfDisposedCore()
                Return MASApplicationTheme.CurrentCore
            End Get
        End Property

        Public ReadOnly Property CurrentId As String
            Get
                _rootHost.ThrowIfDisposedCore()
                Return MASApplicationTheme.CurrentIdCore
            End Get
        End Property

        Public ReadOnly Property CurrentDisplayName As String
            Get
                _rootHost.ThrowIfDisposedCore()
                Return MASApplicationTheme.CurrentDisplayNameCore
            End Get
        End Property

        Public Function GetAll() As IReadOnlyList(Of IMASAppTheme)
            _rootHost.ThrowIfDisposedCore()
            Return MASApplicationTheme.GetAllCore()
        End Function

        Public Function GetById(id As String) As IMASAppTheme
            _rootHost.ThrowIfDisposedCore()
            Return MASApplicationTheme.GetByIdCore(id)
        End Function

        ''' <summary>
        ''' Attempts to apply the theme globally for the application process, then refreshes this window immediately.
        ''' Other windows refresh through the shared ThemeManager change notification observed by their ThemeHost.
        ''' </summary>
        Public Function TryUse(id As String) As Boolean
            _rootHost.ThrowIfDisposedCore()
            Dim applied As Boolean = MASApplicationTheme.TryUseCore(id)

            If applied Then
                RefreshWindowTheme()
            End If

            Return applied
        End Function

        ''' <summary>
        ''' Applies the theme globally for the application process.
        ''' </summary>
        Public Sub Use(id As String)
            If String.IsNullOrWhiteSpace(id) Then
                Throw New ArgumentException("Theme id cannot be null, empty, or whitespace.", NameOf(id))
            End If

            If Not TryUse(id) Then
                Throw New InvalidOperationException("Theme '" & id & "' is not registered.")
            End If
        End Sub


        ''' <summary>
        ''' Explicitly named alias for TryUse. Prefer this in multi-window code to make global scope obvious.
        ''' </summary>
        Public Function TryUseGlobally(id As String) As Boolean
            Return TryUse(id)
        End Function

        ''' <summary>
        ''' Explicitly named alias for Use. Prefer this in multi-window code to make global scope obvious.
        ''' </summary>
        Public Sub UseGlobally(id As String)
            Use(id)
        End Sub

        ''' <summary>
        ''' Internal registration seam for Nexamas UI-owned themes only.
        ''' Public SDK consumers select already registered themes by id; arbitrary IMASAppTheme registration is closed before v1.
        ''' </summary>
        Friend Sub Register(theme As IMASAppTheme)
            _rootHost.ThrowIfDisposedCore()
            MASApplicationTheme.RegisterCore(theme)
        End Sub

        ''' <summary>
        ''' Marks this window's ThemeHost snapshot stale and requests a repaint.
        ''' </summary>
        Public Sub Refresh()
            _rootHost.ThrowIfDisposedCore()
            RefreshWindowTheme()
        End Sub

        Private Sub RefreshWindowTheme()
            Dim root As MASSkiaRootHost = RootHost

            root.PostToUiThreadCore(
                Sub()
                    If root.IsDisposed Then Return

                    Try
                        If root.ThemeHostCore IsNot Nothing Then
                            root.ThemeHostCore.Invalidate()
                        End If
                    Catch masCaughtException1 As Exception
                        Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(
                            masCaughtException1,
                            "MASApplicationWindowTheme.Refresh")
                    End Try
                End Sub,
                "MASApplicationWindowTheme.Refresh")

        End Sub

    End Class

End Namespace
