using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
namespace Terminal.Gui.App;
///
/// Interface for instances that provide backing functionality to static
/// gateway class .
///
public interface IApplication
{
#region Keyboard
///
/// Handles keyboard input and key bindings at the Application level.
///
///
///
/// Provides access to keyboard state, key bindings, and keyboard event handling. Set during .
///
///
IKeyboard Keyboard { get; set; }
#endregion Keyboard
#region Mouse
///
/// Handles mouse event state and processing.
///
///
///
/// Provides access to mouse state, mouse grabbing, and mouse event handling. Set during .
///
///
IMouse Mouse { get; set; }
#endregion Mouse
#region Initialization and Shutdown
/// Initializes a new instance of Application.
///
/// The short name (e.g. "dotnet", "windows", "unix", or "fake") of the
/// to use. If not specified the default driver for the platform will be used.
///
///
/// Call this method once per instance (or after has been called).
///
/// This function loads the right for the platform, creates a main loop coordinator,
/// initializes keyboard and mouse handlers, and subscribes to driver events.
///
///
/// must be called when the application is closing (typically after
/// has returned) to ensure resources are cleaned up and terminal settings restored.
///
///
/// The function combines and
/// into a single call. An application can use
/// without explicitly calling .
///
///
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
public void Init (string? driverName = null);
///
/// This event is raised after the and methods have been called.
///
///
/// Intended to support unit tests that need to know when the application has been initialized.
///
public event EventHandler>? InitializedChanged;
/// Gets or sets whether the application has been initialized.
bool Initialized { get; set; }
/// Shutdown an application initialized with .
///
/// Shutdown must be called for every call to or
/// to ensure all resources are cleaned
/// up (Disposed) and terminal settings are restored.
///
public void Shutdown ();
///
/// Resets the state of this instance.
///
/// If true, ignores disposed state checks during reset.
///
///
/// Encapsulates all setting of initial state for Application; having this in a function like this ensures we
/// don't make mistakes in guaranteeing that the state of this singleton is deterministic when
/// starts running and after returns.
///
///
/// IMPORTANT: Ensure all property/fields are reset here. See Init_ResetState_Resets_Properties unit test.
///
///
public void ResetState (bool ignoreDisposed = false);
#endregion Initialization and Shutdown
#region Begin->Run->Iteration->Stop->End
///
/// Building block API: Creates a and prepares the provided for
/// execution. Not usually called directly by applications. Use
/// instead.
///
///
/// The that needs to be passed to the method upon
/// completion.
///
/// The to prepare execution for.
///
///
/// This method prepares the provided for running. It adds this to the
/// list of s, lays out the SubViews, focuses the first element, and draws the
/// on the screen. This is usually followed by starting the main loop, and then the
/// method upon termination which will undo these changes.
///
///
/// Raises the event before returning.
///
///
public SessionToken Begin (Toplevel toplevel);
///
/// Runs a new Session creating a and calling . When the session is
/// stopped, will be called.
///
/// Handler for any unhandled exceptions (resumes when returns true, rethrows when null).
///
/// The driver name. If not specified the default driver for the platform will be used. Must be
/// if has already been called.
///
/// The created . The caller is responsible for disposing this object.
///
/// Calling first is not needed as this function will initialize the application.
///
/// must be called when the application is closing (typically after Run has returned) to
/// ensure resources are cleaned up and terminal settings restored.
///
///
/// The caller is responsible for disposing the object returned by this method.
///
///
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
public Toplevel Run (Func? errorHandler = null, string? driverName = null);
///
/// Runs a new Session creating a -derived object of type
/// and calling . When the session is stopped,
/// will be called.
///
/// The type of to create and run.
/// Handler for any unhandled exceptions (resumes when returns true, rethrows when null).
///
/// The driver name. If not specified the default driver for the platform will be used. Must be
/// if has already been called.
///
/// The created object. The caller is responsible for disposing this object.
///
///
/// This method is used to start processing events for the main application, but it is also used to run other
/// modal s such as boxes.
///
///
/// To make stop execution, call
/// or .
///
///
/// Calling is equivalent to calling
/// , followed by starting the main loop, and then calling
/// .
///
///
/// When using or ,
/// will be called automatically.
///
///
/// In RELEASE builds: When is any exceptions will be
/// rethrown. Otherwise, will be called. If
/// returns the main loop will resume; otherwise this method will exit.
///
///
/// must be called when the application is closing (typically after Run has returned) to
/// ensure resources are cleaned up and terminal settings restored.
///
///
/// In RELEASE builds: When is any exceptions will be
/// rethrown. Otherwise, will be called. If
/// returns the main loop will resume; otherwise this method will exit.
///
///
/// The caller is responsible for disposing the object returned by this method.
///
///
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
public TView Run (Func? errorHandler = null, string? driverName = null)
where TView : Toplevel, new ();
///
/// Runs a new Session using the provided view and calling
/// .
/// When the session is stopped, will be called..
///
/// The to run as a modal.
/// Handler for any unhandled exceptions (resumes when returns true, rethrows when null).
///
///
/// This method is used to start processing events for the main application, but it is also used to run other
/// modal s such as boxes.
///
///
/// To make stop execution, call
/// or .
///
///
/// Calling is equivalent to calling
/// , followed by starting the main loop, and then calling
/// .
///
///
/// When using or ,
/// will be called automatically.
///
///
/// must be called when the application is closing (typically after Run has returned) to
/// ensure resources are cleaned up and terminal settings restored.
///
///
/// In RELEASE builds: When is any exceptions will be
/// rethrown. Otherwise, will be called. If
/// returns the main loop will resume; otherwise this method will exit.
///
///
/// The caller is responsible for disposing the object returned by this method.
///
///
public void Run (Toplevel view, Func? errorHandler = null);
///
/// Raises the event.
///
///
/// This is called once per main loop iteration, before processing input, timeouts, or rendering.
///
public void RaiseIteration ();
/// This event is raised on each iteration of the main loop.
///
///
/// This event is raised before input processing, timeout callbacks, and rendering occur each iteration.
///
/// See also and .
///
public event EventHandler? Iteration;
/// Runs on the main UI loop thread.
/// The action to be invoked on the main processing thread.
///
///
/// If called from the main thread, the action is executed immediately. Otherwise, it is queued via
/// with and will be executed on the next main loop
/// iteration.
///
///
void Invoke (Action? action);
/// Runs on the main UI loop thread.
/// The action to be invoked on the main processing thread.
///
///
/// If called from the main thread, the action is executed immediately. Otherwise, it is queued via
/// with and will be executed on the next main loop
/// iteration.
///
///
void Invoke (Action action);
///
/// Building block API: Ends a Session and completes the execution of a that was started with
/// . Not usually called directly by applications.
///
/// will automatically call this method when the session is stopped.
///
/// The returned by the method.
///
///
/// This method removes the from the stack, raises the
/// event, and disposes the .
///
///
public void End (SessionToken sessionToken);
/// Requests that the currently running Session stop. The Session will stop after the current iteration completes.
///
/// This will cause to return.
///
/// This is equivalent to calling with as the parameter.
///
///
void RequestStop ();
/// Requests that the currently running Session stop. The Session will stop after the current iteration completes.
///
/// The to stop. If , stops the currently running .
///
///
/// This will cause to return.
///
/// Calling is equivalent to setting the
/// property on the specified to .
///
///
void RequestStop (Toplevel? top);
///
/// Set to to cause the session to stop running after first iteration.
///
///
///
/// Used primarily for unit testing. When , will be called
/// automatically after the first main loop iteration.
///
///
bool StopAfterFirstIteration { get; set; }
///
/// Raised when has been called and has created a new .
///
///
/// If is , callers to
/// must also subscribe to and manually dispose of the token
/// when the application is done.
///
public event EventHandler? SessionBegun;
///
/// Raised when was called and the session is stopping. The event args contain a
/// reference to the
/// that was active during the session. This can be used to ensure the Toplevel is disposed of properly.
///
///
/// If is , callers to
/// must also subscribe to and manually dispose of the token
/// when the application is done.
///
public event EventHandler? SessionEnded;
#endregion Begin->Run->Iteration->Stop->End
#region Toplevel Management
/// Gets or sets the currently active Toplevel.
///
///
/// This is set by and cleared by .
///
///
Toplevel? Current { get; set; }
/// Gets the stack of all active Toplevel sessions.
///
///
/// Toplevels are added to this stack by and removed by
/// .
///
///
ConcurrentStack SessionStack { get; }
///
/// Caches the Toplevel associated with the current Session.
///
///
/// Used internally to optimize Toplevel state transitions.
///
Toplevel? CachedSessionTokenToplevel { get; set; }
#endregion Toplevel Management
#region Screen and Driver
/// Gets or sets the console driver being used.
///
///
/// Set by based on the driver parameter or platform default.
///
///
IDriver? Driver { get; set; }
///
/// Gets or sets whether will be forced to output only the 16 colors defined in
/// . The default is , meaning 24-bit (TrueColor) colors will be
/// output as long as the selected supports TrueColor.
///
bool Force16Colors { get; set; }
///
/// Forces the use of the specified driver (one of "fake", "dotnet", "windows", or "unix"). If not
/// specified, the driver is selected based on the platform.
///
string ForceDriver { get; set; }
///
/// Gets or sets the size of the screen. By default, this is the size of the screen as reported by the
/// .
///
///
///
/// If the has not been initialized, this will return a default size of 2048x2048; useful
/// for unit tests.
///
///
Rectangle Screen { get; set; }
/// Raised when the terminal's size changed. The new size of the terminal is provided.
///
///
/// This event is raised when the driver detects a screen size change. The event provides the new screen
/// rectangle.
///
///
public event EventHandler>? ScreenChanged;
///
/// Gets or sets whether the screen will be cleared, and all Views redrawn, during the next Application iteration.
///
///
///
/// This is typically set to when a View's changes and that view
/// has no SuperView (e.g. when is moved or resized).
///
///
/// Automatically reset to after processes it.
///
///
bool ClearScreenNextIteration { get; set; }
///
/// Collection of sixel images to write out to screen when updating.
/// Only add to this collection if you are sure terminal supports sixel format.
///
List Sixel { get; }
#endregion Screen and Driver
#region Layout and Drawing
///
/// Causes any Toplevels that need layout to be laid out, then draws any Toplevels that need display. Only Views
/// that need to be laid out (see ) will be laid out. Only Views that need to be drawn
/// (see ) will be drawn.
///
///
/// If the entire View hierarchy will be redrawn. The default is and
/// should only be overridden for testing.
///
///
///
/// This method is called automatically each main loop iteration when any views need layout or drawing.
///
///
/// If is , the screen will be cleared before
/// drawing and the flag will be reset to .
///
///
public void LayoutAndDraw (bool forceRedraw = false);
///
/// Calls on the most focused view.
///
///
/// Does nothing if there is no most focused view.
///
/// If the most focused view is not visible within its superview, the cursor will be hidden.
///
///
/// if a view positioned the cursor and the position is visible.
public bool PositionCursor ();
#endregion Layout and Drawing
#region Navigation and Popover
/// Gets or sets the popover manager.
///
///
/// Manages application-level popover views. Initialized during .
///
///
ApplicationPopover? Popover { get; set; }
/// Gets or sets the navigation manager.
///
///
/// Manages focus navigation and tracking of the most focused view. Initialized during .
///
///
ApplicationNavigation? Navigation { get; set; }
#endregion Navigation and Popover
#region Timeouts
/// Adds a timeout to the application.
/// The time span to wait before invoking the callback.
///
/// The callback to invoke. If it returns , the timeout will be reset and repeat. If it
/// returns , the timeout will stop and be removed.
///
///
/// Call with the returned value to stop the timeout.
///
///
///
/// When the time specified passes, the callback will be invoked on the main UI thread.
///
///
/// calls StopAll on to remove all timeouts.
///
///
object AddTimeout (TimeSpan time, Func callback);
/// Removes a previously scheduled timeout.
/// The token returned by .
///
/// if the timeout is successfully removed; otherwise, .
/// This method also returns if the timeout is not found.
///
bool RemoveTimeout (object token);
///
/// Handles recurring events. These are invoked on the main UI thread - allowing for
/// safe updates to instances.
///
///
///
/// Provides low-level access to the timeout management system. Most applications should use
/// and instead.
///
///
ITimedEvents? TimedEvents { get; }
#endregion Timeouts
///
/// Gets a string representation of the Application as rendered by .
///
/// A string representation of the Application
public string ToString ();
}