// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: testprog.cpp
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: Doug Gaer    
// File Creation Date: 03/21/97 
// Date Last Modified: 12/03/97
// Copyright (c) 1997 Douglas M. Gaer
// ----------------------------------------------------------- // 
// ------------- Program Description and Details ------------- // 
// ----------------------------------------------------------- // 
/*
This is a test program for the terminal interface class.

The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
All those who put this code or its derivatives in a commercial
product MUST mention this copyright in their documentation for
users of the products in which this code or its derivative
classes are used. Otherwise, you have the freedom to redistribute
verbatim copies of this source code, adapt it to your specific
needs, or improve the code and release your improvements to the
public provided that the modified files carry prominent notices
stating that you changed the files and the date of any change.

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
*/
// ----------------------------------------------------------- // 
#include <iostream.h>
#include <ctype.h>
#include <string.h>
#include "terminal.hpp"

const int selections = 10;
const int functions = 10;
typedef void (*MF)(); // Function pointer to menu functions

void Exit();
void CursorPositionTest(); // Full screen curser test
void Dialogs();            // User interface functions
void InputFunctions();     // Test input functions
void StatusLine();         // Status line function
void Justification();      // Test right, left, and center justification
void VideoTest();          // Test video attributes 
void KBWait();             // Test KBWait function
void ScanCodes();          // Display keyboard scan codes
void GetTerm();            // Get the terminal type

const char *MainMenu[selections] = {
  "(0) - To exit this program",
  "(1) - Cursor position test",
  "(2) - Standard dialog test",
  "(3) - Input function test",
  "(4) - Status line test",
  "(5) - Line justification test",
  "(6) - Video attributes test",
  "(7) - Key board wait test",
  "(8) - Display keyboard scancodes",
  "(9) - Get the terminal type"
};

MF MMFunctions[functions] = {
  &Exit,
  &CursorPositionTest, // Full screen curser test
  &Dialogs,            // User interface functions
  &InputFunctions,     // Test input functions
  &StatusLine,         // Status line function
  &Justification,      // Test right, left, and center justification
  &VideoTest,          // Test video attributes 
  &KBWait,             // Test KBWait function
  &ScanCodes,          // Display keyboard scan codes
  &GetTerm             // Get the terminal type
};

void Menu()
{
  const char *title = "TERMINAL CLASS TEST PROGRAM'S MAIN MENU" ;

  Coords *p = new Coords(0, 0);
  p->SetX(terminal->Center(title));
  p->SetY(terminal->ScreenCenter(selections));
  terminal->ClearScreen();
  terminal->Write(title, p->XPos(), p->YPrev());

  for(int i = 0; i < selections; i++)
    terminal->Write(MainMenu[i], p->XPos(), p->YOffset(1));
  
  terminal->Write("Press the number of your selection >",
		  p->XPos(), p->YOffset(2));
}

void ProcessArgs()
{
  int c;
  while(1) {
    Menu();
    c = terminal->GetChar();
    switch(tolower(c)) {
      case '0': 
	(*MMFunctions[0]) (); // Call the appropriate menu function
	return;
      case '1':
	(*MMFunctions[1]) (); // Call the appropriate menu function
	break;
      case '2':
	(*MMFunctions[2]) (); // Call the appropriate menu function
	break;
      case '3':
	(*MMFunctions[3]) (); // Call the appropriate menu function
	break;
      case '4':
	(*MMFunctions[4]) (); // Call the appropriate menu function
	break;
      case '5':
	(*MMFunctions[5]) (); // Call the appropriate menu function
	break;
      case '6':
	(*MMFunctions[6]) (); // Call the appropriate menu function
	break;
      case '7':
	(*MMFunctions[7]) (); // Call the appropriate menu function
	break;
      case '8':
	(*MMFunctions[8]) (); // Call the appropriate menu function
	break;
      case '9':
	(*MMFunctions[9]) (); // Call the appropriate menu function
	break;
      default:
	break;
    }
  }
}

int main()
{
  terminal->init();   // Initialize the terminal

  ProcessArgs();      // Enter main communictions loop

  terminal->ClearScreen(); 
  terminal->finish(); // Restore the terminal before exiting
  return 0;
}

void ScanCodes()
{
  char c; int x, y;
  terminal->ClearScreen();
  x = y = 0;
  terminal->Write("Displaying keyboard scan codes...", x, y);
  y = y+2;
  terminal->Write("Type keys. Press Esc when finished",x ,y);
  y = y+2;
  terminal->MoveCursor(x, y);
  while ((c = terminal->GetChar()) != Escape) {
    y = y+1;
    terminal->Write("The ", x, y);
    terminal->Write(c);
    terminal->Write(" key value is: ");
    terminal->Write((int)c & 255);
    if(y > terminal->MaxLines()-1) {
      terminal->ClearScreen();
      terminal->Write("Type keys. Press Esc when finished",0 ,0);
      y = 2;
      terminal->MoveCursor(x, y);
    }
  }
  terminal->ClearScreen();
}

void CursorPositionTest()
{
  terminal->ClearScreen();
  
  const char Pop = '*';     // Display cursor position character
  short x = 0, y = 0;
  unsigned char lastc = 0;
  unsigned char c = 0;
  char *sl = "U-up, D-down, L-left, R-right, Esc to quit...";
  int len = strlen(sl);
  
  while (c != Escape) {
    terminal->StatusLine(sl);
    terminal->Write("x: ", len + 5, terminal->MaxLines()-1);
    terminal->Write(x);
    terminal->Write(" y: ");
    terminal->Write(y);
    terminal->MoveCursor(x, y);
    c = terminal->GetChar();
    switch (tolower(c))	{
      case ' ': case '\r':
	terminal->Write(Pop, x, y);
	terminal->PutBack(lastc);
	break;
      case 'u': // up cursor
	if (y-- == 0) y = terminal->MaxLines()-1;
	lastc = c;
	break;
      case 'd': // down cursor
	if (++y == terminal->MaxLines()-1) y = 0; // Avoid  status line
	lastc = c;
	break;
      case 'l': // left cursor
	if (x-- == 0) x = terminal->MaxCols()-1;
	lastc = c;
	break;
      case 'r': //  right cursor
	if (++x == terminal->MaxCols()) x = 0;
	lastc = c;
	break;
      default:
	break;
    }
  }
  terminal->ClearScreen();
}

void VideoTest()
{
  int x, y;
  x = y = 0;
  terminal->ClearScreen();
  terminal->Write("Testing video attributes...", x, y);
  y = y+2;
  terminal->StandOut("Stand Out video mode", x, y);
  y = y+2;
  terminal->Write("Normal text", x, y);
  y = y+2;
  terminal->AnyKey(x, y);
  terminal->ClearScreen();
}

void Justification()
{
  terminal->ClearScreen();
  terminal->Write("Testing left, center, and right justification", 0, 0);
  char *fox = "This quick brown fox jumps over the lazy dog";
  char *nums = "0123456789";
  char *alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  terminal->Write(nums, 0, 2);
  terminal->Write(nums, terminal->Center(nums), 4);
  terminal->Write(nums, terminal->Right(nums), 6);

  terminal->Write(alpha, 0, 8);
  terminal->Write(alpha, terminal->Center(alpha), 10);
  terminal->Write(alpha, terminal->Right(alpha), 12);

  terminal->Write(fox, 0, 14);
  terminal->Write(fox, terminal->Center(fox), 16);
  terminal->Write(fox, terminal->Right(fox), 18);

  terminal->AnyKey(0, 20);
  terminal->ClearScreen();
}

void InputFunctions()
{
  terminal->ClearScreen();
  Coords *pos = new Coords(0, 0);
  terminal->Write("Testing input functions...", pos->XPos(), pos->YPos());

  terminal->Write("Enter a string: ", pos->XPos(), pos->YOffset(2)); 
  char buf[81];
  terminal->GetString(buf);
  terminal->Write("You entered: ", pos->XPos(), pos->YOffset(2)); 
  terminal->Write(buf);

  terminal->Write("Enter a password: ", pos->XPos(), pos->YOffset(2)); 
  terminal->GetPassword(buf);
  terminal->Write("You entered: ", pos->XPos(), pos->YOffset(2)); 
  terminal->Write(buf);

  terminal->Write("Enter a number: ", pos->XPos(), pos->YOffset(2)); 
  int num = terminal->GetInt();
  terminal->Write("You entered: ", pos->XPos(), pos->YOffset(2)); 
  terminal->Write(num); 

  terminal->Write("Enter a floating point number: ",
		  pos->XPos(), pos->YOffset(2)); 
  double fp = terminal->GetFloat();
  terminal->Write("You entered: ", pos->XPos(), pos->YOffset(2)); 
  terminal->Write(fp);

  terminal->AnyKey(pos->XPos(), pos->YOffset(2)); 
  terminal->ClearScreen();
}

void KBWait()
{
  terminal->ClearScreen();
  terminal->Write("Testing KBWait() function...", 0, 0);
  terminal->AnyKey(0, 1);
  
  int i, j = 0; 
  for(;;) { // Continue processing until any key is pressed
    for(i = 0; i < terminal->MaxCols(); i++) {
      terminal->Write('*', i, j);
    }
    j++;
    if(terminal->KBWait()) break; 
  }
  terminal->ClearScreen();
}

void Dialogs()
{
  Coords *pos = new Coords(0, 0);
  terminal->ClearScreen();
  terminal->Write("Testing standard dialogs functions...",
		  pos->XPos(), pos->YPos()); 

  int yn = terminal->YesNo(pos->XPos(), pos->YOffset(2)); 
  if(yn) 
    terminal->Write("You pressed \'y\' to continue",
		    pos->XPos(), pos->YOffset(2)); 

  terminal->MoveCursor(pos->XPos(), pos->YOffset(2)); 
  yn = terminal->YesNo();
  if(!yn) 
    terminal->Write("You pressed \'n\' not to continue",
		    pos->XPos(), pos->YOffset(2)); 

  terminal->AnyKey(pos->XPos(), pos->YOffset(2)); 

  terminal->ClearScreen();
}

void StatusLine()
{
  terminal->ClearScreen();
  terminal->Write("Testing status line functions...",0, 0);
  terminal->StatusLine("Normal mode bottom, left justified status line");
  terminal->AnyKey(0, 2);
  terminal->ClearScreen();
}

void GetTerm()
{
  terminal->ClearScreen();
  if(getenv("TERM")) {
    terminal->Write("The TERM variable is set: ", 0, 0); 
    terminal->Write(terminal->GetTerm());
  }
  else
    terminal->Write("The TERM variable is not set.", 0, 0); 

  terminal->Write("The maximum number of lines = ", 0, 1);
  terminal->Write(terminal->MaxLines());
  terminal->Write("The maximum number of columns = ", 0, 2);
  terminal->Write(terminal->MaxCols());
  terminal->AnyKey(0, 4);
  terminal->ClearScreen();
}

void Exit()
{
  return; 
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //
