/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

/* scr.cc - The screen reading library
 *
 * Note: Although C++, this code requires no standard C++ library.
 * This is important as BRLTTY *must not* rely on too many
 * run-time shared libraries, nor be a huge executable.
 */

#include "prologue.h"

#include "log.h"
#include "scr.h"
#include "scr_special.h"
#include "update.h"
#include "message.h"

#include "scr_frozen.h"
static FrozenScreen frozenScreen;

static int
frozenScreen_construct (void) {
  return frozenScreen.construct(&mainScreen.base);
}

#include "scr_help.h"
static HelpScreen helpScreen;

static int
helpScreen_construct (void) {
  return helpScreen.construct();
}

#include "scr_menu.h"
#include "menu_prefs.h"
static MenuScreen menuScreen;

static int
menuScreen_construct (void) {
  Menu *menu = getPreferencesMenu();
  if (!menu) return 0;

  updateLogMessagesSubmenu();
  return menuScreen.construct(menu);
}

typedef struct {
  const char *const name;
  int (*const construct) (void);
  void (**const destruct) (void);
  BaseScreen *const base;

  const unsigned autoDestruct:1;

  unsigned isConstructed:1;
  unsigned isActive:1;
} SpecialScreenEntry;

#define SPECIAL_SCREEN_INITIALIZER(type) \
  .name = #type, \
  .construct = type ## Screen_construct, \
  .destruct = &type ## Screen.destruct, \
  .base = &type ## Screen.base

static SpecialScreenEntry specialScreenTable[] = {
  [SCR_FROZEN] = {
    SPECIAL_SCREEN_INITIALIZER(frozen),
    .autoDestruct = 1
  },

  [SCR_HELP] = {
    SPECIAL_SCREEN_INITIALIZER(help)
  },

  [SCR_MENU] = {
    SPECIAL_SCREEN_INITIALIZER(menu)
  },
};

static const unsigned char specialScreenCount = ARRAY_COUNT(specialScreenTable);

static SpecialScreenEntry *
getSpecialScreenEntry (SpecialScreenType type) {
  return &specialScreenTable[type];
}

static void
logScreenAction (const char *type, const char *name, const char *action) {
  logMessage(LOG_DEBUG, "%s %s screen: %s", action, type, name);
}

static void
logMainScreenAction (const char *action) {
  logScreenAction("main", screen->definition.name, action);
}

static void
logSpecialScreenAction (const SpecialScreenEntry *sse, const char *action) {
  logScreenAction("special", sse->name, action);
}

static int
constructSpecialScreen (SpecialScreenEntry *sse) {
  if (sse->isConstructed) return !sse->autoDestruct;
  logSpecialScreenAction(sse, "constructing");
  if (!sse->construct()) return 0;
  sse->isConstructed = 1;
  return 1;
}

static void
destructSpecialScreen (SpecialScreenEntry *sse) {
  if (sse->isConstructed) {
    logSpecialScreenAction(sse, "destructing");
    (*sse->destruct)();
    sse->isConstructed = 0;
  }
}

void
beginSpecialScreens (void) {
  initializeFrozenScreen(&frozenScreen);
  initializeMenuScreen(&menuScreen);
  initializeHelpScreen(&helpScreen);
}

void
endSpecialScreens (void) {
  SpecialScreenEntry *sse = specialScreenTable;
  SpecialScreenEntry *end = sse + specialScreenCount;

  while (sse < end) {
    destructSpecialScreen(sse);
    sse += 1;
  }
}

static void
announceCurrentScreen (void) {
  const char *title = currentScreen->getTitle();
  if (title) message(NULL, title, 0);
}

static void
setCurrentScreen (BaseScreen *screen) {
  if (screen != currentScreen) {
    currentScreen->onBackground();
    currentScreen = screen;
    currentScreen->onForeground();

    scheduleUpdate("new screen selected");
    announceCurrentScreen();
  }
}

static void
setSpecialScreen (const SpecialScreenEntry *sse) {
  logSpecialScreenAction(sse, "selecting");
  setCurrentScreen(sse->base);
}

static void
selectCurrentScreen (void) {
  const SpecialScreenEntry *sse = specialScreenTable;
  const SpecialScreenEntry *end = sse + specialScreenCount;

  while (sse < end) {
    if (sse->isActive) {
      setSpecialScreen(sse);
      return;
    }

    sse += 1;
  }

  logMainScreenAction("selecting");
  setCurrentScreen(&mainScreen.base);
}

int
activateSpecialScreen (SpecialScreenType type) {
  SpecialScreenEntry *sse = getSpecialScreenEntry(type);

  if (!constructSpecialScreen(sse)) return 0;
  logSpecialScreenAction(sse, "activating");
  sse->isActive = 1;
  setSpecialScreen(sse);
  return 1;
}

void
deactivateSpecialScreen (SpecialScreenType type) {
  SpecialScreenEntry *sse = getSpecialScreenEntry(type);

  logSpecialScreenAction(sse, "deactivating");
  sse->isActive = 0;
  if (sse->autoDestruct) destructSpecialScreen(sse);
  selectCurrentScreen();
}

int
haveSpecialScreen (SpecialScreenType type) {
  return getSpecialScreenEntry(type)->isActive;
}

int
isSpecialScreen (SpecialScreenType type) {
  return currentScreen == getSpecialScreenEntry(type)->base;
}

int
constructHelpScreen (void) {
  SpecialScreenEntry *sse = getSpecialScreenEntry(SCR_HELP);

  return constructSpecialScreen(sse);
}

int
addHelpPage (void) {
  return helpScreen.addPage();
}

unsigned int
getHelpPageCount (void) {
  return helpScreen.getPageCount();
}

unsigned int
getHelpPageNumber (void) {
  return helpScreen.getPageNumber();
}

int
setHelpPageNumber (unsigned int number) {
  return helpScreen.setPageNumber(number);
}

int
clearHelpPage (void) {
  return helpScreen.clearPage();
}

int
addHelpLine (const wchar_t *characters) {
  return helpScreen.addLine(characters);
}

unsigned int
getHelpLineCount (void) {
  return helpScreen.getLineCount();
}
