//********************************************************************************
//* File       : AnsiCmd.hpp                                                     *
//* Author     : Mahlon R. Smith                                                 *
//*              Copyright (c) 2022-2026 Mahlon R. Smith, The Software Samurai   *
//*                 GNU GPL copyright notice below                               *
//* Date       : 05-Apr-2026                                                     *
//* Version    : (see AnsiCmdVersion string in AnsiCmd.cpp)                      *
//*                                                                              *
//* Description: AnsiCmd class definition.                                       *
//*                                                                              *
//* This class defines a simple and comprehensive way to set the terminal        *
//* program's text attributes. These include foreground and background color     *
//* and intensity, as well as bold, underline, italic, blinking, and other,      *
//* less used and less widely supported attributes.                              *
//* These include cursor positioning, overline, strike-through and all other     *
//* attributes defined in the ISO/IEC 2022 control code and control sequence     *
//* set. See man pages: "man console_codes 4"                                    *
//* See also ECMA-48, ISO/IEC 6429, FIPS 86, ANSI X3.64, JIS X 0211.             *
//*                                                                              *
//* This implementation is intended primarily for Linux in its various flavors,  *
//* but it is also well-suited for other platforms that support some subset      *
//* of the ANSI escape sequence set.                                             *
//*                                                                              *
//* Note that if the terminal receives an escape sequence or control code        *
//* which is not supported by the system, it will _probably_ be ignored;         *
//* however, it is prudent to verify, wherever possible, that all invoked        *
//* sequences are supported by the target system.                                *
//*                                                                              *
//*             https://en.wikipedia.org/wiki/ANSI_escape_code                   *
//********************************************************************************

//*************************************************************
//** The base class is the AnsiCmd class which is mandatory. **
//** However, the API-level methods and data including the   **
//** skForm and skField classes, as well as the ACWin class  **
//** are optional, and provide additional functionality for  **
//** creating user-input forms and dialog-window-oriented    **
//** objects.                                                **
//** Note: Debugging methods require the API functionality.  **
//** Note: Access to the system clipboard requires the       **
//**       the API functionality.                            **
//*************************************************************
#define INCLUDE_API (1)
#if INCLUDE_API != 0
//** Enable/disable WaylandCB system clipboard interface.    **
#define INCLUDE_WAYLANDCB (1)
#endif   // INCLUDE_API

//* Enable/disable class-level debugging information and test methods.*
#define DEBUG_ANSICMD (1)
#if DEBUG_ANSICMD != 0
//* Optionally enable debug log file *
#define DEBUG_LOG (1)
//* Optionally enable AnsiCmd test suite *
#define DEBUG_ANSICMD_TEST (1)
#endif   // DEBUG_ANSICMD

#include "AnsiCmdDef.hpp"     //* General definitions and library #includes

//* Minimum and maximum indices for terminal's color lookup table.   *
//* Setting of color attributes is managed by methods dedicated to   *
//* each specific color group.                                       *
//* Three/Four-bit color group: acSetFg(), acSetBg(), acSetFgBg().   *
//* Eight-bit color group: acSet8bitFg() and acSet8bitBg().          *
//* RGB color group: acSetRgbFg() and acSetRgbBg().                  *
//* Greyscale color group: acSetGreyscaleFg() and acSetGreyscaleBg().*
const uint8_t minLOOKUP = 0 ;    // minimum index for 256-color lookup table
const uint8_t maxLOOKUP = 255 ;  // maximum index for 256-color lookup table
const uint8_t min8BIT   = 16 ;   // minimum index for 8-bit color matrix
const uint8_t max8BIT   = 231 ;  // maximum index for 8-bit color matrix
const uint8_t minRGB = min8BIT ; // minimum index for RGB color matrix
const uint8_t maxRGB = max8BIT ; // maximum index for RGB color matrix
const uint8_t minGSCALE = 232 ;  // minimum greyscale index
const uint8_t maxGSCALE = 255 ;  // maximum greyscale index
const uint8_t primeFONT = 10 ;   // ANSI code for primary font

const short LOCALE_LEN = 64 ; // max length of stored locale filename

//***************************************************************************
//* Terminal configuration definitions indicating the target I/O stream.    *
//* Note: For the system calls made by the AnsiCmd class to the terminal    *
//* emulator, these values are equivalent because we are accessing the      *
//* terminal's VIRTUAL file system, not a real file system.                 *
//***************************************************************************
enum TermStream : int
{
   stdIn  = 0,
   stdOut = 1,
   stdErr = 2
} ;

//* Echo options for _unbuffered_ 'stdin' input stream. *
//* See acBufferedInput() method for more information.  *
enum EchoOpt : short
{
   noEcho = ZERO, // Echo of input stream to the window is disabled.
   termEcho,      // Allow the terminal to control echo of input to the window.
                  // (This will also be the setting when input-buffering is enabled.)

   //* For these options, automatic terminal echo is disabled.    *
   //* Graphical (printing) characters are echoed to the terminal *
   //* window programatically. "Special" keycodes are translated  *
   //* and processed according to the soft-echo sub-option.       *
   softEchoA,     // Translate all supported special keycodes (default)
   softEchoB,     // Translate basic special keys (discard selection keycodes)
   softEchoC,     // Translate only the cursor keys (discard edit keycodes)
   softEchoD,     // Translation disabled (all non-printing keycodes discarded)
   softEchoE,     // Translate Edit keys: Backspace, Delete, Insert and 
                  // text-selection keys (discard cursor keycodes)
   // Note: When the 'noEcho' option is active, all special keys defined in the 
   //       'softEchoA' group are decoded and reported as valid keycodes.
} ;

//* Specify the type of signal handler to use when *
//* the Ctrl+C signal handler method is specified. *
enum CCH_Type : wchar_t
{
   cchtTerm,               // terminal issues kill signal (local handler inactive)
   cchtExit,               // exit the application
   cchtUser,               // prompt user for response
   cchtCopy,               // interpret as the "Copy" command (special keycode)
   cchtIgnore,             // ignore the break signal (default when handler active)
} ;

//******************************************************
//* The TermConfig class is initialized using terminal *
//* configuration information from the command-line.   *
//******************************************************
class TermConfig
{
   public:
   TermConfig ( void )              // default constructor
   {
      this->reset () ;
   }
   ~TermConfig ( void )             // destructor
   { /* Nothing to do at this time. */ }

   //* Set all data members to default values.*
   void reset ( void )
   {
      //* Set data members to default values *
      this->termStream = stdIn ;    // target the input stream
      this->localeName[0] = L'\0' ; // indicates locale from terminal environment
      this->echoOption = termEcho ; // terminal controls stdin echo
      this->bufferInput = true ;    // terminal buffers data from stdin
      this->wideStream = true ;     // wide I/O stream
      this->nonStandard = false ;   // standard ANSI compliant terminal
      this->bcType = cchtTerm ;     // default Ctrl+C processing type (terminal handler)
      this->bcAlert = true ;        // audible alert when discarding Ctrl+C signal
      this->suspendSignal = true ;  // suspend signal captured
      this->quitSignal = true ;     // quit signal captured
      this->cursorStyle = csDflt ;  // default cursor style
      this->foreground = aesFG_DFLT ; // default foreground attribute
      this->background = aesBG_DFLT ; // default background attribute
   }
   //* Specify target I/O stream.                              *
   //* Note: In practical terms, the selection of the target   *
   //* stream is not important because changes made to one     *
   //* stream are reflected in all streams.                    *
   TermStream termStream ;

   //* Name of configuration file (default "ansicmd.cfg").     *
   //* [NOT YET IMPLEMENTED]                                   *
   char    configFile[gsALLOCMIN] ;

   //* Filename of alternate locale (null string by default).  *
   //* If not specified, locale will be taken from terminal    *
   //* environment.                                            *
   char    localeName[LOCALE_LEN] ;

   //* Characters received through 'stdin' will be echoed      *
   //* (displayed) in the terminal window according to the     *
   //* specified member of enum EchoOpt.                       *
   //* When system buffering of input is active, we have no    *
   //* control over input echo, so this option will be ignored.*
   //* When buffering is disabled (see 'bufferInput', below),  *
   //* the specified echo option will be used:                 *
   //* noEcho  : input data not echoed to window (default)     *
   //* termEcho: terminal automatically echoes input           *
   //* softEcho[A|C|D|E]: the 'acRead' method echos (writes)   *
   //* all printing characters to the terminal window as they  *
   //* arrive. The "special" keys (cursor,bksp/del/ins) are    *
   //* processed according to specified soft-echo sub-option.  *
   EchoOpt echoOption ;

   //* Specify whether data from 'stdin' will be buffered by   *
   //* the system or whether it will be sent directly to the   *
   //* application.                                            *
   // 'false' : disable input buffering                        *
   // 'true;  : input buffering enabled (default)              *
   bool    bufferInput ;

   //* Select the width of the input/output streams.           *
   //* 'true'  : wide (32-bit) I/O streams, wcin and wcout     *
   //* 'false' : narrow (8/7-bit) I/O streams, cin and cout    *
   bool    wideStream ;

   //* Specify whether the host terminal is ANSI compliant.    *
   //* A compliant terminal supports all of the common commands*
   //* of ANSI standard (ANSI X3.64 (ISO/IEC6429)).            *
   //* 'true'  : non-standard terminal emulator                *
   //* 'false' : ANSI compliant terminal emulator (default)    *
   bool    nonStandard ;

   //* Capture the Panic Button (CTRL+C key).                  *
   //* Signal-capture type: member of enum CCH_Type            *
   //* Default: cchtTerm - Terminal handles CTRL+C break-signal*
   CCH_Type bcType ;
   //* For 'bcType' == cchtIgnore ONLY: audible alert.         *
   //* Default: 'false'.                                       *
   bool     bcAlert ;

   //* Capture SIGTSTP (suspend) signal generated by Ctrl+Z.   *
   //* If 'true', capture signal and convert to ordinary key.  *
   //* If 'false', terminal handles Ctrl+Z suspend signal.     *
   bool suspendSignal ;

   //* Capture SIGQUIT (quit) signal generated by either       *
   //* Ctrl+4 or Ctrl+\.                                       *
   //* If 'true', capture signal and ;perform orderly shutdown.*
   //* If 'false', terminal handles Ctrl+4 quit signal.        *
   bool quitSignal ;

   //* Select cursor style: member of enum CurStyle.           *
   //* Default: csDflt - terminal default cursor shape.        *
   CurStyle cursorStyle ;

   //* Specify the initial foreground (text) color attribute.  *
   //* Member of enum aeSeq: aesFG_xxxx (default:aesFG_DFLT)   *
   aeSeq   foreground ;

   //* Specify the initial background (text) color attribute.  *
   //* Member of enum aeSeq: aesBG_xxxx (default:aesBG_DFLT)   *
   aeSeq   background ;

} ;   // TermConfig

//********************************************************************
//* Text for command-line help used by the application is defined    *
//* in AnsiCmdApi.cpp and is declared as 'extern' elsewhere.         *
//********************************************************************
extern const char* HelpTerm ;
extern const char* HelpAnsi ;

//********************************************************************
//* Used for passing testing data to AnsiCmd functional tests.       *
//* See the ansicmdSetup() method and the ansiTest() method.         *
//********************************************************************
class dbgArgs { public: wchar_t major, minor, supp, attr ; } ;

//********************************************************************
//* Non-member Methods:                                              *
//* -------------------                                              *
//* These methods can be used by the application to parse            *
//* command-line arguments for setup of the AnsiCmd class.           *
//*  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  --- *
//********************************************************************
//* ansicmdSetup (terminal setup):                                   *
//* ------------------------------                                   *
//* Parse command-line arguments for setup of the terminal window.   *
//* --term option: specifies terminal setup options.                 *
//*                                                                  *
//* Input  : gsCmd   : (by reference) command-line arguments         *
//*          tCfg    : (by reference) receives decoded               *
//*                    terminal configuration options                *
//*                                                                  *
//* Returns: 'true'  if all tokens successfully decoded              *
//*          'false' if syntax error or invalid argument             *
//********************************************************************
bool ansicmdSetup ( const gString& gsCmd, TermConfig& tCfg ) ;
//********************************************************************
//* ansicmdSetup (AnsiCmd class development and testing options:     *
//* ------------------------------------------------------------     *
//* Parse command-line arguments for setup of AnsiCmd test options.  *
//* --test option: specifies an AnsiCmd-class functionality test.    *
//*                                                                  *
//* Input  : gsCmd   : (by reference) command-line arguments         *
//*          args    : (by reference) receives testing arguments     *
//*                                                                  *
//* Returns: 'true'  if all tokens successfully decoded              *
//*          'false' if syntax error or invalid argument             *
//********************************************************************
bool ansicmdSetup ( const gString& gsCmd, dbgArgs& args ) ;

//********************************************************
//* The TermSet class manages terminal configuration and *
//* data tracking. All methods and data are private and  *
//* are used internally by the AnsiCmd class.            *
//* For public copy of these data, see termConfig below. *
//********************************************************
class TermSet
{
   //* All methods and data members are private.    *
   //* The AnsiCmd class is specified as a 'friend'.*
   private:
   TermSet ( void ) ;
   TermSet ( const TermConfig& tCfg ) ;
   ~TermSet ( void ) ;
   bool getTermInfo ( TermStream tStream, TermIos& tIos, bool orig = false ) ;
   bool setTermInfo ( TermStream tStream, bool buffered, EchoOpt eopt ) ;
   bool termConfig ( TermStream tStream, const TermIos& tIos ) ;
   bool restoreTermInfo ( bool restoreAll = false ) ;
   bool echoOption ( EchoOpt eopt ) ;
   bool cursorStyle ( CurStyle style, aeSeq color = aesFG_DFLT ) ;
   bool blockingInput ( bool block ) ;
   bool captureBreakSignal ( bool enable, CCH_Type handlerType = cchtIgnore, 
                            bool alert = false, void* handlerAddr = NULL ) ;
   bool captureSuspendSignal ( bool enable ) ;
   bool captureQuitSignal ( bool enable ) ;
   bool FlushStdin ( void ) ;
   void reset ( void ) ;         // initialize all data members

   TermIos strOrig ;    // stream settings captured on first call (instantiation)
   TermIos strMods ;    // modified stream settings
   TermStream aStr ;    // active terminal stream (this is actually not very important)
   CurStyle  curStyle ; // member of enum CurStyle (csDflt by default)
   CCH_Type cchType ;   // member of enum CCH_Type (cchtTerm by default)
   EchoOpt inpEch ;     // member of enum EchoOpt (termEcho by default)
   bool    inpBuf ;     // 'true' if buffered input stream, 'false' if unbuffered input
   bool    inpBlk ;     // 'true' if blocking read of input stream, 'false' if non-blocking
   bool    cchAlert ;   // 'true' if audible alert when Break signal (CTRL+C) received
   bool    curVis ;     // 'true' if cursor is currently visible, else 'false'
   bool    quitCap ;    // 'true' if quit signal captured
   bool    suspCap ;    // 'true' if suspend signal captured
   bool    flowCap ;    // 'true' if flow control signals disabled
   bool    isWin ;      // 'true' if TermSet object is a member of ACWin class
   bool    strCap ;     // 'true' if original stream settings captured
   bool    strMod ;     // 'true' if stream settings modified (strMods==modified settings)

   friend class AnsiCmd ;  // AnsiCmd class has access to private members.
   friend class ACWin ;    //ACWin class has access to private members
} ;   // TermSet

//********************************************************************
//* Used during application development to verify configuration.     *
//* See AnsiCmd method: getConfig() and ACWin method WinInfo().      *
//* (Do not confuse with the TermConfig class, above.)               *
//********************************************************************
class termConfig
{
   public:
   short termRows ;           //* current terminal window rows
   short termCols ;           //* current terminal window columns
   const locale* ioLocale ;   //* application locale (language and text processing)
   TermIos tios ;             //* I/O stream settings
   CurStyle  curStyle ;       //* member of enum CurStyle
   CCH_Type cchType ;         //* member of enum CCH_Type
   EchoOpt inpEch ;           //* member of enum EchoOpt
   bool    inpBuf ;           //* 'true' if buffered input stream, 'false' if unbuffered input
   bool    inpBlk ;           //* 'true' if blocking read of input stream, 'false' if non-blocking
   bool    cchAlert ;         //* 'true' if audible alert when Break signal (CTRL+C) received
   bool    curVis ;           //* 'true' if cursor is currently visible, else 'false'
   bool    quitCap ;          //* 'true' if quit signal captured
   bool    suspCap ;          //* 'true' if suspend signal captured
   bool    flowCap ;          //* 'true' if flow control signals disabled
   bool    isWin ;            //* 'true' if TermSet object is a member of ACWin class
   bool    strCap ;           //* 'true' if original stream settings captured
   bool    fullReset ;        //* 'true' to enable, 'false' to disable
   bool    wideStream ;       //* wide (32-bit) or narrow (8-bit) I/O
} ;   // termConfig

//**********************************************************
//** Define the AnsiCmd class.                            **
//** This is the base class for the AnsiCmd link library. **
//**********************************************************
class AnsiCmd
{
   public:

   AnsiCmd ( void ) ;                        // default constructor
   AnsiCmd ( const TermConfig& tCfg ) ;      // initialization constructor
   virtual ~AnsiCmd ( void ) ;               // destructor

   //* Set all ANSI display attributes to default values.    *
   //* (This method does not modify terminal configuration.) *
   bool acReset ( void ) ;
   //* Set text foreground color (background unchanged) *
   bool acSetFg ( aeSeq fg ) ;
   //* Set text background color (foreground unchanged) *
   bool acSetBg ( aeSeq bg, bool synth = true ) ;
   //* Set text foreground AND background colors *
   bool acSetFgBg ( aeSeq fg, aeSeq bg ) ;
   //* Set text foreground background colors using acAttr bitfield value *
   bool acSetFgBg ( acAttr fgbg ) ;
   //* Set/reset a text modifier attribute *
   bool acSetMod ( aeSeq mod ) ;
   //* Reset all text modifiers, leaving base colors attributes unchanged *
   void acResetMods ( bool fullReset = false ) ;
   //* Set foreground color from 8-bit-color lookup table.*
   //* (min8BIT <= fg <= max8BIT)                         *
   bool acSet8bitFg ( uint8_t fg ) ;
   //* Set background color from 8-bit-color lookup table.*
   //* (min8BIT <= bg <= max8BIT)                         *
   bool acSet8bitBg ( uint8_t bg ) ;
   //* Set foreground color using R/G/B register values.*
   bool acSetRgbFg ( uint8_t rReg, uint8_t  gReg, uint8_t  bReg ) ;
   //* Set background color using R/G/B register values.*
   bool acSetRgbBg ( uint8_t rReg, uint8_t gReg, uint8_t bReg ) ;
   //* Set foreground color using "web-safe" R/G/B register values.*
   bool acSetWebFg ( WebSafeRGB hue, uint8_t shade ) ;
   //* Set background color using "web-safe" R/G/B register values.*
   bool acSetWebBg ( WebSafeRGB hue, uint8_t shade ) ;
   //* Set Greyscale foreground (background unchanged) *
   bool acSetGreyscaleFg ( uint8_t shade ) ;
   //* Set Greyscale background (foreground unchanged) *
   bool acSetGreyscaleBg ( uint8_t shade ) ;
   //* Set cursor position within terminal window. Full ANSI or absolute-only. *
   bool acSetCursor ( aeSeq curcmd, short arga = 1, short argb = 1 ) const ;
   bool acSetCursor ( short row, short col ) const ; // specify absolute position only
   bool acSetCursor ( const WinPos& wp ) const ;     // specify absolute position only
   //* Get the current cursor position *
   WinPos acGetCursor ( void ) const ;
   //* Set cursor type (or make cursor invisible) *
   bool acSetCursorStyle ( CurStyle style, aeSeq color = aesFG_DFLT ) ;
   //* Set font used to write subsequent text data *
   bool acSetFont ( aeSeq font, uint8_t fontnum = 0 ) ;
   //* Erase the specified area of the terminal window *
   bool acEraseArea ( aeSeq area, short rowOff = 0, short colOff = 0 ) const ;
   //* Reports the dimensions of the terminal window in rows and columns *
   bool acGetTermDimensions ( short& rows, short& cols ) const ;
   //* Reports the terminal dimensions *
   WinSize acGetTermSize ( void ) ;
   //* Get a copy of the current terminal I/O configuration.*
   bool acGetTermInfo ( TermStream tStream, TermIos& tIos, bool orig = false ) ;
   //* Interface to the seldom-supported and little-used "ideogram" group *
   bool acSetIdeogram ( aeSeq idea ) ;
   //* Flush stdout, (the active output stream, wcout or cout) *
   void acFlushOut ( void ) const ;
   //* Flush stdin, (discard all data in the active input stream, wcin or cin) *
   void acFlushIn ( void ) const ;
   //* Flush stdout and discard data from stdin *
   void acFlushStreams ( void ) const ;
   //* Capture a text string from the user *
   int acRead ( gString& gsIn, short limit = gsALLOCMIN ) const ;
   //* Capture a single keystroke from the user *
   wchar_t acRead ( void ) const ;
   //* Wait for user to press any key *
   wchar_t acPause ( bool nl = false ) const ;
   //* Pause for a specified amount of time OR until user presses a key *
   void acWait ( uint16_t seconds ) const ;
   //* Write text data (or ANSI sequence) to stdout beginning at the specified *
   //* cursor position. Final cursor position is returned.                     *
   WinPos acWrite ( WinPos wp, const gString& gsTxt, bool flush = true ) const ;
   WinPos acWrite ( short row, short col, const gString& gsTxt, bool flush = true ) const ;
   WinPos acWrite ( WinPos wp, const wchar_t* wTxt, bool flush = true ) const ;
   WinPos acWrite ( short row, short col, const wchar_t* wTxt, bool flush = true ) const ;
   WinPos acWrite ( WinPos wp, const char* cTxt, bool flush = true ) const ;
   WinPos acWrite ( short row, short col, const char* cTxt, bool flush = true ) const ;
   WinPos acWrite ( WinPos wp, wchar_t wchar, bool flush = true ) const ;
   WinPos acWrite ( short row, short col, wchar_t wchar, bool flush = true ) const ;
   WinPos acWrite ( WinPos wp, char cbyte, bool flush = true ) const ;
   WinPos acWrite ( short row, short col, char cbyte, bool flush = true ) const ;

   //* Write text data (or ANSI sequence) to stdout beginning at the current   *
   //* cursor position. This emulates TTY-style output.                        *
   void ttyWrite ( const gString& gsTxt, bool flush = true, bool nl = false ) const ;
   void ttyWrite ( const wchar_t*wTxt, bool flush = true, bool nl = false ) const ;
   void ttyWrite ( wchar_t wchar, bool flush = true, bool nl = false ) const ;
   void ttyWrite ( const char* cTxt, bool flush = true, bool nl = false ) const ;
   void ttyWrite ( const uint8_t* uTxt, bool flush = true, bool nl = false ) const ;
   void ttyWrite ( char cbyte, bool flush = true, bool nl = false ) const ;

   //* Clear the entire terminal window using fill character *
   void acClearScreen ( wchar_t fillchar = L' ', acAttr fillattr = acaUSEDFLT ) ;
   //* Clear the specified rectangular area using fill character *
   bool acClearArea ( short row, short col, short height, short width, 
                      wchar_t fillchar = L' ', acAttr fillattr = acaUSEDFLT ) ;
   bool acClearArea ( WinPos wpOrig, short height, short width, 
                      wchar_t fillchar = L' ', acAttr fillattr = acaUSEDFLT ) ;
   //* Invoke the console's default auditory alert (beep) *
   void acBeep ( short repeat = 1, short delay = 5, int freq = -1 ) const ;
   //* Sleep (pause) execution for the specified time period *
   void nsleep ( uint16_t tenths, uint16_t millisec = ZERO, time_t nanosec = ZERO ) const ;
   //* Set the "locale" for the application *
   bool acSetLocale ( const char * localeName = NULL ) ;
   //* Returns name of active locale *
   const char* acGetLocale ( void ) ;
   //* Set input/output streams' character width *
   bool acSetStreamWidth ( bool widechar ) ;
   //* Disable or enable input stream buffering and input-echo option. *
   bool acBufferedInput ( bool buffered, EchoOpt echoType, bool block = true ) ;
   //* Select the input character echo type. (enum EchoOpt).*
   bool acSetEchoOption ( EchoOpt echoType ) ;
   //* Get the current input-echo setting *
   EchoOpt acGetEchoOption ( void ) ;
   //* Enable or disable blocking read from the input stream (stdin). *
   bool acBlockingInput ( bool block ) ;
   //* Disable input buffering and capture all keyboard-generated signals. *
   bool  acCaptureSignals ( EchoOpt eopt = softEchoA ) ;
   //* Release all captured signals. Return control to the terminal software. *
   void acReleaseSignals ( void ) ;
   //* Enable or disable application-level capture of the BREAK key (CTRL+C). *
   bool acCaptureBreakSignal ( bool enable, CCH_Type handlerType = cchtIgnore, 
                               bool alert = false, void* handlerAddr = NULL ) ;
   //* Enable or disable application-level capture of the SUSPEND key (CTRL+Z). *
   bool acCaptureSuspendSignal ( bool enable ) ;
   //* Enable or disable application-level capture of the QUIT key (CTRL+4). *
   bool acCaptureQuitSignal ( bool enable ) ;
   //* Reset _all_ ANSI terminal attributes before modifying an attribute *
   bool acFullReset ( bool enable ) ;
   //* Restore terminal stream settings to original values.*
   bool acRestoreTermInfo ( bool restoreAll = false ) ;
   //* Return the AnsiCmd class version *
   const char* acVersion ( void ) const ;

   //* Called ONLY by the non-member method which handles *
   //* receipt of the break-signal (CTRL+C).              *
   void breaksignalReceived ( int sigNum ) ;

   //* Called ONLY by the non-member method which handles *
   //* receipt of the suspend signal (CTRL+Z).            *
   void suspendsignalReceived ( int sigNum ) ;

   //* Called ONLY by the non-member method which handles *
   //* receipt of the quit signal (CTRL+4 or CTRL+\).     *
   void quitsignalReceived ( int sigNum ) ;

   //** ------------------------------------------ **
   //**            API-level Methods               **
   //** (These methods are under the INCLUDE_API ) **
   //** (conditional compilation flag. See above.) **
   //** ------------------------------------------ **
   //* Modify or replace the current color attributes and text modifiers.*
   bool acSetAttributes ( acAttr newAttr, bool resetAll = false ) ;

   //* Construct an acAttr attribute bitmap from component values.*
   acAttr acComposeAttributes ( uint8_t fgVal, uint8_t bgVal, bool rgbfg, 
                                bool rgbbg, acAttr mods = acaPLAINTXT ) ;

   //* Get a copy of the current color attributes and text modifier flags.*
   void acGetAttributes ( acaExpand& decodedAttr ) ;

   //* Reformat the provided text to fit within the specified dimensions.*
   short acFormatParagraph ( gString& gsTxt, short maxRows, short maxCols, 
                             bool trunc = true, bool hypenbrk = false, 
                             int *truncIndex = NULL ) ;
   short acFormatParagraph ( wchar_t* wTxt, short maxRows, short maxCols, 
                             bool trunc = true, bool hypenbrk = false, 
                             int *truncIndex = NULL ) ;

   //* Temporarily return control to terminal shell program.   *
   int acShellOut ( const char* cmd = NULL, bool clrWin = false, 
                    acAttr txtAttr = acaUSEDFLT ) ;

   //* Draw a horizontal or vertical line in the terminal window.*
   WinPos acDrawLine ( const WinPos& wpOrig, short length, bool vertical, 
                       LineType lType = ltSINGLE, 
                       wchar_t begChar = L'\0', wchar_t endChar = L'\0' ) ;

   //* Draw a rectangle and optionally write text in the box.*
   WinPos acDrawBox ( WinPos wpOrig, short height, short width, 
                      LineType lType = ltSINGLE, const char *text = NULL ) ;

   //* Erase the specified area. (see acDrawBox()). *
   void acEraseBox ( WinPos wpOrig, short height, short width ) ;

   //* Display an AC_Box object in the terminal window.*
   WinPos acBoxDraw ( AC_Box& box, const char *text = NULL ) ;

   //* Erase the AC_Box data from the display.*
   void acBoxErase ( const AC_Box& box ) ;

   //* Erase the text area of of an AC_Box object.*
   WinPos acBoxClear ( const AC_Box& box ) ;

   //* Determine whether the specified keycode is one of the "special" keys. *
   bool isSpecialKey ( wchar_t& wkey, bool alert = false, EchoOpt *eopt = NULL ) const ;

   //* Determine whether the specified keycode is one of the   *
   //* "GUI" command keys _or_ one of the ASCII control codes. *
   //*      (excludes the "special" keycodes by default)       *
   bool isCommandKey ( wchar_t& wkey, bool all = false ) const ;

   //** ----- System Clipboard Access Group ----- **
   //* Establish communications with the system clipboard.  *
   bool acClipboardEnable ( gString* version = NULL ) ;
   //* Terminate the connection to system clipboard.        *
   void acClipboardDisable ( void ) ;
   //* Test the connection with the system clipboard.       *
   bool acClipboardTest ( void ) ;
   //* Get a copy of the text on the system clipboard.      *
   int acClipboardGetText ( gString& gsTxt ) ;
   //* Save the specified text to system clipboard.         *
   int acClipboardSetText ( const gString& gsTxt ) ;
   //* Returns UTF-32 characters stored on clipboard.       *
   int acClipboardCharCnt ( void ) ;
   //* Returns UTF-8 data bytes stored on clipboard.        *
   int acClipboardByteCnt ( void ) ;

   //** ------------------------------------------ **
   //** Methods for Management of Temporary files  **
   //** ------------------------------------------ **
   //* Create a unique sub-directory in the system's temp-file *
   //* directory to contain application's temporary files.     *
   bool acCreateTemppath ( const char* prefix = NULL ) ;
   //* Delete sub-directory containing the temporary files.    *
   void acDeleteTemppath ( void ) ;
   //* Create a unique path/filename for a temporary file.     *
   bool acCreateTempfile ( gString& tempPath ) ;
   //* Delete the specified temporary file.                    *
   bool acDeleteTempfile ( const gString& tmpPath ) ;

   //** --------------------------------- **
   //** Development and Debugging Methods **
   //** --------------------------------- **
   //* For use during development: Get a copy of current configuration. *
   void getConfig ( termConfig& tCfg ) ;

   //* For debugging only - Test the ANSI ecape sequences *
   //* and other functionality of the AnsiCmd class.      *
   void ansiTest ( dbgArgs& args ) ;

   //* Returns a copy of protected data members.                               *
   //* Used primarily by the ACWin class to synchronize terminal configuration.*
   //* Note that all data and methods of the TermSet class are private;        *
   //* however, ACWind is "friend" to TermSet class.                           *
   void getDataMembers ( TermSet* ts, acaExpand* ab, locale* lo, short& tr, 
                         short& tc, short& fn, bool& fr, bool& ws ) const ;

   #if DEBUG_ANSICMD != 0 && DEBUG_ANSICMD_TEST != 0 && INCLUDE_API != 0
   // Programmer's Note: For ease in debugging, this method is declared 'public';
   // however, it is called ONLY by the Test_SoftEcho() method and its 
   // associated callback functions.
   void tseReport ( const skForm& skf, const WinPos& wpRpt, uint8_t secret_code ) ;
   #endif   // DEBUG_ANSICMD && DEBUG_ANSICMD_TEST && INCLUDE_API

   //* Protected methods: *
   protected:
   //* Set the current color attributes and modifier.*
   void setAttributes ( const acaExpand& acaEx, bool setFgnd = true, 
                        bool setBgnd = true, bool setMods = true ) ;
   //* This overload compensates for a weakness in the GNU compiler.*
   void setAttributes ( acAttr acaval, bool setFgnd = true, 
                        bool setBgnd = true, bool setMods = true ) ;
   //* Conditional echo of key input to display.*
   bool softWrite ( wchar_t wchar ) const ;
   //* Non-blocking read from input stream.          *
   bool acReadNB ( wchar_t& wchar, uint16_t repeat, uint16_t delay, 
                   bool silent = true, uint32_t *flagPtr = NULL ) const ;
   bool acPeekNB ( wchar_t& wchar, uint16_t repeat, uint16_t delay, 
                   wchar_t pushChar ) const ;
   //* Copy the specified text to the clipboard.*
   int cbSet ( const gString& gsTxt, bool toSys = true ) ;
   //* Get a copy of the clipboard text.*
   int cbGet ( gString& gsTxt, bool fromSys = true ) ;

   //* Private methods: *
   private:
   void Initialize ( const TermConfig& tCfg ) ;
   void reset ( void ) ;
   void InitModFlag ( aeSeq mod ) ;
   short readSeq ( gString& gsIn, wchar_t termChar ) const ;
   WinPos writeNL ( WinPos& wp, const gString& gsCmd ) const ;
   bool set8Bit ( bool bgnd, uint8_t fgbg ) ;
   bool setRgbReg ( bool bgnd, uint8_t r, uint8_t g, uint8_t b ) ;
   bool setRgbWeb ( bool bgnd, WebSafeRGB hue, uint8_t shade ) ;
   bool setGreyscale ( bool bgnd, uint8_t shade ) ;
   bool specialkeyDecode ( wchar_t& wchar ) const ;
   void skpRefresh ( const skField& field, const WinPos& wpBase ) const ;
   wchar_t silentRead ( void ) const ;

   //***************************************************
   //** Testing Methods -- Located In AnsiCmdTest.cpp **
   //***************************************************
   private:
   #if DEBUG_ANSICMD != 0 && DEBUG_ANSICMD_TEST != 0 && INCLUDE_API != 0
   void ansiTest_Menu ( dbgArgs& args ) ;  // for debugging only
   void Test_4Bit ( void ) ;               // for debugging only
   void Test_Bg ( void ) ;                 // for debugging only
   void Test_8bitColor ( void ) ;          // for debugging only
   void Test_Greyscale ( void ) ;          // for debugging only
   void Test_RGB ( wchar_t rgbTest ) ;     // for debugging only
   void trgbStepWeb ( void ) ;             // for debugging only (extended RGB test)
   void trgbStepRed ( void ) ;             // for debugging only (extended RGB test)
   void trgbStepGreen ( void ) ;           // for debugging only (extended RGB test)
   void trgbStepBlue ( void ) ;            // for debugging only (extended RGB test)
   void trgbStepGrey ( void ) ;            // for debugging only (extended RGB test)
   void Test_AltFonts ( aeSeq fg ) ;       // for debugging only
   void Test_CursorPos ( aeSeq fg ) ;      // for debugging only
   void Test_UnbufferedInput ( aeSeq fg ) ;// for debugging only
   void Test_Erasures ( aeSeq fg ) ;       // for debugging only
   void Test_AixFgBg ( void ) ;            // for debugging only
   void Test_acaExpand ( wchar_t call ) ;  // for debugging only
   void Test_acaExpandSwap ( void ) ;      // for debugging only
   void Test_AsciiCodes ( aeSeq fg ) ;     // for debugging only
   void Test_Ideogram ( aeSeq fg ) ;       // for debugging only
   void Test_TermFlags ( aeSeq fg ) ;      // for debugging only 
   void Test_ModFlags ( aeSeq fg ) ;       // for debugging only 
   void Test_NonBlock ( aeSeq fg ) ;       // for debugging only
   void Test_RawInput ( aeSeq fg ) ;       // for debugging only
   void Test_OutputStream ( aeSeq fg ) ;   // for debugging only
   void Test_SoftEcho ( wchar_t eOpt, aeSeq fg ) ; // for debugging only 
   void tfPrompt ( short baseRow, short baseCol, // for debugging only
                   short prompt, const wchar_t *p2 = NULL ) ;
   void Test_Window ( aeSeq fg ) ;         // for debugging only
   void Test_Form ( aeSeq fg ) ;           // for debugging only
   void Test_Wrap ( aeSeq fg ) ;           // for debugging only
   void Test_WinDefault ( aeSeq fg ) ;     // for debugging only
   void Test_Dialog ( wchar_t group, wchar_t test ) ; // for debugging only
   void Test_Fifo ( aeSeq fg ) ;           // for debugging only
   void dumpFifoRec ( const void* bfifo, short& bi, WinPos& wpRpt, 
                      aeSeq fg, short baseRow, short areaHgt, short areaWid ) ;
   void Test_Menu ( aeSeq fg ) ;           // for debugging only
   void Test_Hilite ( wchar_t tMod, aeSeq fg ) ; // for debugging only
   void Test_Cookie ( wchar_t eOpt, aeSeq fg ) ; // for debugging only (Cookie Monster lives here :-)
   void Test_Clipboard_API ( aeSeq fg ) ;  // for debugging only
   void Test_Clipboard_Win ( aeSeq fg ) ;  // for debugging only
   void Test_Tfman ( aeSeq fg ) ;          // for debugging only
   void Test_LaunchExt ( wchar_t opt, aeSeq fg ) ; // for debugging only
   void Test_Box ( aeSeq fg ) ;            // for debugging only
   void Test_Line ( aeSeq fg ) ;           // for debugging only
   void Test_Write ( aeSeq fg ) ;          // for debugging only
   void twColorChart ( const WinPos& basePos ) ; // for debugging only
   void Test_Sandbox ( wchar_t parmA, wchar_t parmB ) ; // for debugging only
   void Test_ReportCurPos ( short row, short col, WinPos *wpos = NULL ) ; // for debugging only
   //* Capture and format state of Fg/Bg tracking flags -- for debugging only. *
   void acCaptureAttr ( gString& gs, short data, bool nl = true, bool title = false ) ;
   //* Display the text-modifier tracking flags -- for debugging only. *
   void acDumpMods ( short row, short col, const wchar_t *title = NULL ) ;
   //* Dump contents of termios structure -- for debugging only. *
   void acDumpTermInfo ( const TermIos& tios, short row, short col, 
                         short verb = ZERO, const gString *gstit = NULL ) ;
   //* Dump contents of a acaExpand object -- for debugging only. *
   void acaExpandDump ( const acaExpand& da, short row, short col, 
                        const gString *gstit = NULL ) ;
   //* Dump contents of an skForm object -- for debugging only. *
   void skFormDump ( const skForm& skf, short row, short col, 
                     const gString* gstit = NULL ) ;
   #endif   // DEBUG_ANSICMD && DEBUG_ANSICMD_TEST && INCLUDE_API

   //** Data Members: Defined as "protected" **
   //** so derived classes may access them.  **
   protected:
   acaExpand attrBits ;          // color attribute options
   short termRows ;              // current terminal window rows
   short termCols ;              // current terminal window columns
   short fontNum ;               // alternate font number 10==Primary, 11-19==Alternate
   TermSet *tset ;               // terminal I/O settings
   locale *ioLocale ;            // application locale (language and text processing)
   TFMan *tfm ;                  // temp-file management
   bool  fullReset ;             // 'true' to enable, 'false' to disable
   bool  wideStream ;            // 'true'  for wcout (wide output stream)
                                 // 'false' for cout (narrow output stream)
} ;   // AnsiCmd class
