using System.Collections.Concurrent;
namespace Terminal.Gui.App;
///
/// Implementation of core methods using the modern
/// main loop architecture with component factories for different platforms.
///
public partial class ApplicationImpl : IApplication
{
///
/// INTERNAL: Creates a new instance of the Application backend.
///
internal ApplicationImpl () { }
///
/// INTERNAL: Creates a new instance of the Application backend.
///
///
internal ApplicationImpl (IComponentFactory componentFactory) { _componentFactory = componentFactory; }
#region Singleton
///
/// Configures the singleton instance of to use the specified backend implementation.
///
///
public static void SetInstance (IApplication? app)
{
_instance = app;
}
// Private static readonly Lazy instance of Application
private static IApplication? _instance;
///
/// Gets the currently configured backend implementation of gateway methods.
///
public static IApplication Instance => _instance ??= new ApplicationImpl ();
#endregion Singleton
private string? _driverName;
#region Input
private IMouse? _mouse;
///
/// Handles mouse event state and processing.
///
public IMouse Mouse
{
get
{
if (_mouse is null)
{
_mouse = new MouseImpl { App = this };
}
return _mouse;
}
set => _mouse = value ?? throw new ArgumentNullException (nameof (value));
}
private IKeyboard? _keyboard;
///
/// Handles keyboard input and key bindings at the Application level
///
public IKeyboard Keyboard
{
get
{
if (_keyboard is null)
{
_keyboard = new KeyboardImpl { App = this };
}
return _keyboard;
}
set => _keyboard = value ?? throw new ArgumentNullException (nameof (value));
}
#endregion Input
#region View Management
private ApplicationPopover? _popover;
///
public ApplicationPopover? Popover
{
get
{
if (_popover is null)
{
_popover = new () { App = this };
}
return _popover;
}
set => _popover = value;
}
private ApplicationNavigation? _navigation;
///
public ApplicationNavigation? Navigation
{
get
{
if (_navigation is null)
{
_navigation = new () { App = this };
}
return _navigation;
}
set => _navigation = value ?? throw new ArgumentNullException (nameof (value));
}
private Toplevel? _current;
///
public Toplevel? Current
{
get => _current;
set
{
_current = value;
if (_current is { })
{
_current.App = this;
}
}
}
// BUGBUG: Technically, this is not the full lst of sessions. There be dragons here, e.g. see how Toplevel.Id is used. What
///
public ConcurrentStack SessionStack { get; } = new ();
///
public Toplevel? CachedSessionTokenToplevel { get; set; }
#endregion View Management
///
public new string ToString () => Driver?.ToString () ?? string.Empty;
}