import { Tip } from './tip';
import { IMenu } from './app-menu';
import { WindowState } from './window-state';
import { PreferencesTab } from './preferences';

import { ApplicationTheme } from './application-theme';


/** All of the shared app state. */
export interface IAppState {
  /**
   * The current state of the window, ie maximized, minimized full-screen etc.
   */
  readonly windowState: WindowState;

  /**
   * The current zoom factor of the window represented as a fractional number
   * where 1 equals 100% (ie actual size) and 2 represents 200%.
   */
  readonly windowZoomFactor: number;

  /**
   * A value indicating whether or not the current application
   * window has focus.
   */
  readonly appIsFocused: boolean;

  readonly showWelcomeFlow: boolean;
  readonly currentPopup: Popup | null;
  readonly currentFoldout: Foldout | null;

  /**
   * A list of currently open menus with their selected items
   * in the application menu.
   *
   * The semantics around what constitues an open menu and how
   * selection works is defined by the AppMenu class and the
   * individual components transforming that state.
   *
   * Note that as long as the renderer has received an application
   * menu from the main process there will always be one menu
   * "open", that is the root menu which can't be closed. In other
   * words, a non-zero length appMenuState does not imply that the
   * application menu should be visible. Currently thats defined by
   * whether the app menu is open as a foldout (see currentFoldout).
   *
   * Not applicable on macOS unless the in-app application menu has
   * been explicitly enabled for testing purposes.
   */
  readonly appMenuState: ReadonlyArray<IMenu>;

  readonly errors: ReadonlyArray<Error>;

  /**
   * The width of the repository sidebar.
   *
   * This affects the changes and history sidebar
   * as well as the first toolbar section which contains
   * repo selection on all platforms and repo selection and
   * app menu on Windows.
   *
   * Lives on IAppState as opposed to IRepositoryState
   * because it's used in the toolbar as well as the
   * repository.
   */
  readonly sidebarWidth: number;

  /** The width of the commit summary column in the history view */
  readonly commitSummaryWidth: number;

  /** Whether we should hide the toolbar (and show inverted window controls) */
  readonly titleBarStyle: 'light' | 'dark';

  /**
   * Used to highlight access keys throughout the app when the
   * Alt key is pressed. Only applicable on non-macOS platforms.
   */
  readonly highlightAccessKeys: boolean;

  /** Whether we should show the update banner */
  readonly isUpdateAvailableBannerVisible: boolean;

  /** Whether we should show a confirmation dialog */
  readonly askForConfirmationOnRepositoryRemoval: boolean;

  /** Whether we should show a confirmation dialog */
  readonly askForConfirmationOnDiscardChanges: boolean;

  /** The currently selected appearance (aka theme) */
  readonly selectedTheme: ApplicationTheme;
}

export enum PopupType {
  Preferences = 1,
  About,
  Acknowledgements,
  TermsAndConditions,
}

export type Popup =
  | { type: PopupType.Preferences; initialSelectedTab?: PreferencesTab }
  | { type: PopupType.About }
  | { type: PopupType.Acknowledgements }
  | { type: PopupType.TermsAndConditions }
  ;

export enum FoldoutType {
  AppMenu,
  AddMenu,
}

export interface AppMenuFoldout {
  type: FoldoutType.AppMenu;

  /**
   * Whether or not the application menu was opened with the Alt key, this
   * enables access key highlighting for applicable menu items as well as
   * keyboard navigation by pressing access keys.
   */
  enableAccessKeyNavigation: boolean;

  /**
   * Whether the menu was opened by pressing Alt (or Alt+X where X is an
   * access key for one of the top level menu items). This is used as a
   * one-time signal to the AppMenu to use some special semantics for
   * selection and focus. Specifically it will ensure that the last opened
   * menu will receive focus.
   */
  openedWithAccessKey?: boolean;
}

export type Foldout =
  | { type: FoldoutType.AddMenu }
  | AppMenuFoldout
  ;
