// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import "ICoreState.idl";
import "IControlSettings.idl";
import "EventArgs.idl";

namespace Microsoft.Terminal.Control
{

    // This is a mirror of
    // ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState,
    // but projectable.
    // !! LOAD BEARING !! If you make this a struct with Booleans (like they
    // make the most sense as), then the app will crash trying to toss one of
    // these across the process boundary. I haven't the damndest idea why.
    [flags] enum MouseButtonState {
        IsLeftButtonDown = 0x1,
        IsMiddleButtonDown = 0x2,
        IsRightButtonDown = 0x4
    };

    enum ClearBufferType
    {
        Screen,
        Scrollback,
        All
    };

    enum SelectionInteractionMode
    {
        None,
        Mouse,
        Keyboard,
        Mark
    };

    [flags] enum SelectionEndpointTarget {
        Start = 0x1,
        End = 0x2
    };

    struct SelectionData
    {
        Microsoft.Terminal.Core.Point StartPos;
        Microsoft.Terminal.Core.Point EndPos;
        SelectionEndpointTarget Endpoint;
        Boolean StartAtLeftBoundary;
        Boolean EndAtRightBoundary;
    };

    struct SearchRequest
    {
        String Text;
        Boolean GoForward;
        Boolean CaseSensitive;
        Boolean RegularExpression;
        Boolean ResetOnly;
        Int32 ScrollOffset;
    };

    struct SearchResults
    {
        Int32 TotalMatches;
        Int32 CurrentMatch;
        Boolean SearchInvalidated;
        Boolean SearchRegexInvalid;
    };

    [default_interface] runtimeclass SelectionColor
    {
        SelectionColor();
        Microsoft.Terminal.Core.Color Color;
        // If true, color.R is a value between 0 and 15, indicating an indexed color.
        // This mirrors how TextColor works internally, which is the primary target of this interface.
        Boolean IsIndex16;
    };

    [default_interface] runtimeclass CommandHistoryContext
    {
        IVector<String> History { get; };
        String CurrentCommandline { get; };
        IVector<String> QuickFixes { get; };
    };

    [default_interface] runtimeclass ControlCore : ICoreState
    {
        ControlCore(IControlSettings settings,
                    IControlAppearance unfocusedAppearance,
                    Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);

        Boolean Initialize(Single actualWidth,
                           Single actualHeight,
                           Single compositionScale);

        void UpdateSettings(IControlSettings settings, IControlAppearance appearance);
        void ApplyAppearance(Boolean focused);

        Microsoft.Terminal.TerminalConnection.ITerminalConnection Connection;

        IControlSettings Settings { get; };
        IControlAppearance FocusedAppearance { get; };
        IControlAppearance UnfocusedAppearance { get; };
        Boolean HasUnfocusedAppearance();
        void SetHighContrastMode(Boolean enabled);

        void ApplyPreviewColorScheme(Microsoft.Terminal.Core.ICoreScheme scheme);
        void ResetPreviewColorScheme();

        void SetOverrideColorScheme(Microsoft.Terminal.Core.ICoreScheme scheme);

        UInt64 SwapChainHandle { get; };

        Windows.Foundation.Size FontSize { get; };
        Windows.Foundation.Size FontSizeInDips { get; };
        UInt16 FontWeight { get; };
        Single Opacity { get; };
        Boolean UseAcrylic { get; };

        Boolean TryMarkModeKeybinding(Int16 vkey,
                                      Microsoft.Terminal.Core.ControlKeyStates modifiers);
        Boolean TrySendKeyEvent(Int16 vkey,
                                Int16 scanCode,
                                Microsoft.Terminal.Core.ControlKeyStates modifiers,
                                Boolean keyDown);
        Boolean SendCharEvent(Char ch,
                              Int16 scanCode,
                              Microsoft.Terminal.Core.ControlKeyStates modifiers);
        void SendInput(String text);
        void PasteText(String text);
        void SelectAll();
        void ClearSelection();
        Boolean ToggleBlockSelection();
        void ToggleMarkMode();
        Boolean SwitchSelectionEndpoint();
        Boolean ExpandSelectionToWord();
        void ClearBuffer(ClearBufferType clearType);

        void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
        void ClearHoveredCell();

        void ResetFontSize();
        void AdjustFontSize(Single fontSizeDelta);
        void SizeChanged(Single width, Single height);
        void ScaleChanged(Single scale);
        void SizeOrScaleChanged(Single width, Single height, Single scale);

        void ToggleShaderEffects();
        void ToggleReadOnlyMode();
        void SetReadOnlyMode(Boolean readOnlyState);

        Microsoft.Terminal.Core.Point CursorPosition { get; };
        Boolean ForceCursorVisible;
        void ResumeRendering();

        SearchResults Search(SearchRequest request);
        void ClearSearch();

        Microsoft.Terminal.Core.Color ForegroundColor { get; };
        Microsoft.Terminal.Core.Color BackgroundColor { get; };

        SelectionData SelectionInfo { get; };
        SelectionInteractionMode SelectionMode();

        String HoveredUriText { get; };
        Windows.Foundation.IReference<Microsoft.Terminal.Core.Point> HoveredCell { get; };

        Boolean IsInReadOnlyMode { get; };
        void EnablePainting();

        String ReadEntireBuffer();
        CommandHistoryContext CommandHistory();
        Boolean QuickFixesAvailable { get; };

        void AdjustOpacity(Single Opacity, Boolean relative);
        void WindowVisibilityChanged(Boolean showOrHide);

        void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);

        void ContextMenuSelectCommand();
        void ContextMenuSelectOutput();
        Boolean ShouldShowSelectCommand();
        Boolean ShouldShowSelectOutput();

        void OpenCWD();

        void ClearQuickFix();

        // These events are called from some background thread
        event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
        event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
        event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
        event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
        event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
        event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
        event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
        event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;

        // These events are always called from the UI thread (bugs aside)
        event Windows.Foundation.TypedEventHandler<Object, FontSizeChangedArgs> FontSizeChanged;
        event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> ConnectionStateChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> HoveredHyperlinkChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> SwapChainChanged;
        event Windows.Foundation.TypedEventHandler<Object, RendererWarningArgs> RendererWarning;
        event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
        event Windows.Foundation.TypedEventHandler<Object, TransparencyChangedEventArgs> TransparencyChanged;
        event Windows.Foundation.TypedEventHandler<Object, Object> OutputIdle;
        event Windows.Foundation.TypedEventHandler<Object, UpdateSelectionMarkersEventArgs> UpdateSelectionMarkers;
        event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
        event Windows.Foundation.TypedEventHandler<Object, Object> CloseTerminalRequested;
        event Windows.Foundation.TypedEventHandler<Object, Object> RestartTerminalRequested;

        event Windows.Foundation.TypedEventHandler<Object, Object> Attached;

        event Windows.Foundation.TypedEventHandler<Object, CompletionsChangedEventArgs> CompletionsChanged;

    };
}
