/*
***************************************************************************
* This file comprises part of PDCurses. PDCurses is Public Domain software.
* You may use this code for whatever purposes you desire. This software
* is provided AS IS with NO WARRANTY whatsoever.
* Should this software be used in another application, an acknowledgement
* that PDCurses code is used would be appreciated, but is not mandatory.
*
* Any changes which you make to this software which may improve or enhance
* it, should be forwarded to the current maintainer for the benefit of 
* other users.
*
* The only restriction placed on this code is that no distribution of
* modified PDCurses code be made under the PDCurses name, by anyone
* other than the current maintainer.
* 
* See the file maintain.er for details of the current maintainer.
***************************************************************************
*/
/*
 *
 * This is a test program for the PDCurses screen package for IBM PC type
 * machines.
 * This program was written by John Burnell (johnb@kea.am.dsir.govt.nz)
 *
 *  wrs(5/28/93) -- modified to be consistent (perform identically) with either
 *                  PDCurses or under Unix System V, R4
 *
 */

#ifdef PDCDEBUG
char *rcsid_testcurs  = "$Id$";
#endif

#include <stdio.h>
#include <curses.h>

#if defined(XCURSES)
	char *XCursesProgramName = "testcurs";
#endif

#ifdef __STDC__
void inputTest (WINDOW *);
void scrollTest (WINDOW *);
void introTest (WINDOW *);
int initTest (WINDOW **);
void outputTest (WINDOW *);
void padTest (WINDOW *);
void display_menu(int,int);
#  ifdef PDCURSES
void resizeTest (WINDOW *);
#  endif
#else
void inputTest ();
void scrollTest ();
void introTest ();
int initTest ();
void outputTest ();
void padTest ();
void display_menu();
#  ifdef PDCURSES
void resizeTest ();
#  endif
#endif

struct commands
{
 char *text;
#ifdef __STDC__
 void (*function)(WINDOW *);
#else
 void (*function)();
#endif
};
typedef struct commands COMMAND;
#ifdef PDCURSES
#define MAX_OPTIONS 6
#else
#define MAX_OPTIONS 5
#endif
COMMAND command[MAX_OPTIONS] =
{
 {"Intro Test",introTest},
 {"Pad Test",padTest},
#ifdef PDCURSES
 {"Resize Test",resizeTest},
#endif
 {"Scroll Test",scrollTest},
 {"Input Test",inputTest},
 {"Output Test",outputTest}
};

int     width, height;

int main()
{
WINDOW  *win;
int key,old_option=(-1),new_option=0;
bool quit=FALSE;

#ifdef PDCDEBUG
	PDC_debug("testcurs started\n");
#endif
    if (initTest (&win)) {return 1;}

#ifdef A_COLOR
    if (has_colors())
      {
       init_pair(1,COLOR_WHITE,COLOR_BLUE);
       wbkgd(win, COLOR_PAIR(1));
      }
    else
       wbkgd(win, A_REVERSE);
#else
    wbkgd(win, A_REVERSE);
#endif

    erase();
    display_menu(old_option,new_option);
    while(1)
      {
       noecho();
       keypad(stdscr,TRUE);
       raw();
       key = getch();
       switch(key)
         {
          case 10:
          case 13:
          case KEY_ENTER:
                         erase();
                         refresh();
                         (*command[new_option].function)(win);
                         erase();
                         display_menu(old_option,new_option);
                         break;
          case KEY_UP:
                         new_option = (new_option == 0) ? new_option : new_option-1;
                         display_menu(old_option,new_option);
                         break;
          case KEY_DOWN:
                         new_option = (new_option == MAX_OPTIONS-1) ? new_option : new_option+1;
                         display_menu(old_option,new_option);
                         break;
          case 'Q':
          case 'q':
                         quit = TRUE;
                         break;
          default:       break;
         }
       if (quit == TRUE)
          break;
      }

    delwin (win);
    endwin();
    return 0;
}
#ifdef __STDC__
void Continue (WINDOW *win)
#else
void Continue (win)
WINDOW *win;
#endif
{
    wmove(win, 10, 1);
    wclrtoeol(win);
    mvwaddstr(win, 10, 1, " Press any key to continue");
    wrefresh(win);
    raw();
    wgetch(win);
}

#ifdef __STDC_
int initTest (WINDOW **win)
#else
int initTest (win)
WINDOW **win;
#endif
{
#ifdef PDCDEBUG
	PDC_debug("initTest called\n");
#endif
    initscr();
#ifdef PDCDEBUG
	PDC_debug("after initscr()\n");
#endif
#ifdef A_COLOR
    if (has_colors())
       start_color();
#endif
    width  = 60;
    height = 13;                /* Create a drawing window */
    *win = newwin(height, width, (LINES-height)/2, (COLS-width)/2);
    if(*win == NULL)
    {   endwin();
        return 1;
    }
    return(0);
}
#ifdef __STDC__
void introTest (WINDOW *win)
#else
void introTest (win)
WINDOW *win;
#endif
{
    wmove( win, height/2-5, width/2 );
    wvline( win, ACS_VLINE, 10 );
    wmove( win, height/2, width/2-10 );
    whline( win, ACS_HLINE, 20 );
    Continue(win);

    beep ();
    werase(win);

    box(win, ACS_VLINE, ACS_HLINE);
    wrefresh(win);
    cbreak ();
    mvwaddstr(win, 1, 1, "You should have rectangle in the middle of the screen");
    mvwaddstr(win, 2, 1, "You should have heard a beep");
    Continue(win);
    return;
}
#ifdef __STDC__
void scrollTest (WINDOW *win)
#else
void scrollTest (win)
WINDOW *win;
#endif
{
    int i;
    int OldX, OldY;
    char *Message = "The window will now scroll slowly";

/* disable typeahead checking */

    typeahead(-1);

    mvwprintw (win, height - 2, 1, Message);
    wrefresh (win);
    scrollok(win, TRUE);
    for (i = 1; i <= height; i++) {
      napms (150);
      scroll(win);
      wrefresh (win);
    };

    getmaxyx (win, OldY, OldX);
    mvwprintw (win, 6, 1, "The top of the window will scroll");
    wmove (win, 1, 1);
    wsetscrreg (win, 0, 4);
    box(win, ACS_VLINE, ACS_HLINE);
    wrefresh (win);
    for (i = 1; i <= 5; i++) 
      {
       napms (500);
       scroll(win);
       wrefresh (win);
      }

    mvwprintw (win, 3, 1, "The bottom of the window will scroll");
    wmove (win, 8, 1);
    wsetscrreg (win, 5, --OldY);
    box(win, ACS_VLINE, ACS_HLINE);
    wrefresh (win);
    for (i = 5; i <= OldY; i++) 
      {
       napms (300);
       wscrl(win,-1);
       wrefresh (win);
      }
    wsetscrreg (win, 0, OldY);

}
#ifdef __STDC__
void inputTest (WINDOW *win)
#else
void inputTest (win)
WINDOW *win;
#endif
{
    int w, h, bx, by, sw, sh, i, c,num;
    char buffer [80];
    WINDOW *subWin;
    wclear (win);

    getmaxyx(win, h, w);
    getbegyx(win, by, bx);

    sw = w / 3;
    sh = h / 3;
    if((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == NULL)
        return;

#ifdef A_COLOR
    if (has_colors())
      {
       init_pair(2,COLOR_WHITE,COLOR_RED);
       wbkgd(subWin, COLOR_PAIR(2) | A_BOLD);
      }
    else
       wbkgd(subWin, A_BOLD);
#else
    wbkgd(subWin, A_BOLD);
#endif
    box(subWin, ACS_VLINE, ACS_HLINE);
    wrefresh(win);

    nocbreak();
    mvwaddstr(win, 2, 1, "Press some keys for 5 seconds");
    mvwaddstr(win, 1, 1, "Pressing ^C should do nothing");
    wrefresh(win);

    werase (subWin);
    box(subWin, ACS_VLINE, ACS_HLINE);
    for (i = 0; i < 5; i++) 
      {
       mvwprintw (subWin, 1, 1, "Time = %d", i);
       wrefresh(subWin);
       napms(1000);
       flushinp();
      }

    delwin (subWin);
    werase(win);
    flash();
    wrefresh(win);
    napms(500);
    flushinp();

    mvwaddstr(win, 2, 1, "Press a key, followed by ENTER");
    wmove(win, 9, 10);
    wrefresh(win);
    echo();
    noraw();
    wgetnstr(win, buffer, 3);
    flushinp();

    wmove(win, 9, 10);
    wdelch(win);
    mvwaddstr(win, 4, 1, "The character should now have been deleted");
    Continue(win);

    wclear (win);
    mvwaddstr(win, 2, 1, "Press a function key or an arrow key");
    wrefresh(win);
    keypad(win, TRUE);
    raw();
    c = wgetch(win);

    nodelay(win, TRUE);
    wgetch(win);
    nodelay(win, FALSE);

    refresh();
    wclear (win);
    mvwaddstr(win, 3, 2, "The window should have moved");
    mvwaddstr(win, 4, 2, "This text should have appeared without you pressing a key");
    mvwprintw(win, 2, 2, "Keycode = %d", c);
    mvwaddstr(win, 6, 2, "Enter a number then a string seperated by space");
    mvwin(win, 2, 1);
    wrefresh(win);
    mvwscanw(win, 7, 6, "%d %s", &num,buffer);
    mvwprintw(win, 8, 6, "String: %s Number: %d", buffer,num);
    Continue(win);
}
#ifdef __STDC__
void outputTest (WINDOW *win)
#else
void outputTest (win)
WINDOW *win;
#endif
{
    WINDOW *win1;
    char Buffer [80];
    chtype ch;
    int by, bx;

    nl ();
    wclear (win);
    mvwaddstr(win, 1, 1, "You should now have a screen in the upper left corner, and this text should have wrapped");
    waddstr(win,"\nThis text should be down\n");
    waddstr(win,  "and broken into two here ^");
    Continue(win);

    wclear(win);
    wattron(win, A_BOLD);
    mvwaddstr(win, 1, 1, "A new window will appear with this text in it");
    mvwaddstr(win, 8, 1, "Press any key to continue");
    wrefresh(win);
    wgetch(win);

    getbegyx(win, by, bx);

    win1 = newwin(10, 50, 15, 25);
    if(win1 == NULL)
    {   endwin();
        return;
    }
#ifdef A_COLOR
    if (has_colors())
      {
       init_pair(3,COLOR_BLUE,COLOR_WHITE);
       wbkgd(win1, COLOR_PAIR(3));
      }
    else
       wbkgd(win1, A_NORMAL);
#else
    wbkgd(win1, A_NORMAL);
#endif
    wclear (win1);
    mvwaddstr(win1, 5, 1, "This text should appear; using overlay option");
    copywin(win, win1,0,0,0,0,9,49,TRUE);

#if defined(PDCURSES) && !defined(XCURSES)
    box(win1,0xb3,0xc4);
#else
    box(win1,ACS_VLINE,ACS_HLINE);
#endif
    wmove(win1, 8, 26);
    wrefresh(win1);
    wgetch(win1);

    wclear(win1);
    wattron(win1, A_BLINK);
    mvwaddstr(win1, 4, 1, "This blinking text should appear in only the second window");
    wattroff(win1, A_BLINK);
    mvwin(win1, by, bx);
    overlay(win, win1);
    mvwin(win1,15,25);
    wmove(win1, 8, 26);
    wrefresh(win1);
    wgetch(win1);
    delwin(win1);

    clear();
    wclear(win);
    wrefresh(win);
    mvwaddstr(win, 6, 2, "This line shouldn't appear");
    mvwaddstr(win, 4, 2, "Only half of the next line is visible");
    mvwaddstr(win, 5, 2, "Only half of the next line is visible");
    wmove(win, 6, 1);
    wclrtobot (win);
    wmove(win, 5, 20);
    wclrtoeol (win);
    mvwaddstr(win, 8, 2, "This line also shouldn't appear");
    wmove(win, 8, 1);
    winsdelln(win,-1);
    Continue(win);

    wmove (win, 5, 9);
    ch = winch (win);

    wclear(win);
    wmove (win, 6, 2);
    waddstr (win, "The next char should be l:  ");
    winsch (win, ch);
    Continue(win);

    mvwinsstr( win, 6, 2, "A1B2C3D4E5" );
    Continue(win);

    wmove(win, 5, 1);
    winsdelln (win,1);
    mvwaddstr(win, 5, 2, "The lines below should have moved down");
    Continue(win);

    wclear(win);
    wmove(win, 2, 2);
    wprintw(win, "This is a formatted string in a window: %d %s\n", 42, "is it");
    mvwaddstr(win, 10, 1, "Enter a string: ");
    wrefresh(win);
    echo();
    wscanw (win, "%s", Buffer);

    printw("This is a formatted string in stdscr: %d %s\n", 42, "is it");
    mvaddstr(10, 1, "Enter a string: ");
    scanw ("%s", Buffer);

    wclear(win);
    curs_set(2);
    mvwaddstr(win, 1, 1, "The cursor should appear as a block");
    Continue(win);

    wclear(win);
    curs_set(0);
    mvwaddstr(win, 1, 1, "The cursor should have disappeared");
    Continue(win);

    wclear(win);
    curs_set(1);
    mvwaddstr(win, 1, 1, "The cursor should be an underline");
    Continue(win);

#ifdef A_COLOR
    if ( has_colors() )
      {
       wclear(win);
       mvwaddstr(win, 1, 1, "Colors should change after you press a key");
       Continue(win);
       init_pair(1, COLOR_RED, COLOR_WHITE);
       wrefresh(win);
    }
#endif

    werase(win);
    mvwaddstr(win, 1, 1, "Information About Your Terminal");
    mvwaddstr(win, 3, 1, termname());
    mvwaddstr(win, 4, 1, longname());
    if ( termattrs() & A_BLINK )
       mvwaddstr(win,5, 1, "This terminal supports blinking.");
    else
       mvwaddstr(win,5, 1, "This terminal does NOT support blinking.");

    mvwaddnstr( win, 7,5, "Have a nice day!ok", 16 );
    wrefresh(win);

    mvwinnstr( win, 7,5, Buffer, 18 );
    mvaddstr( LINES-2, 10, Buffer );
    refresh();
    Continue(win);
}

#ifdef PDCURSES
#ifdef __STDC__
void resizeTest(WINDOW *dummy)
#else
void resizeTest(dummy)
WINDOW *dummy;
#endif
{
    WINDOW *win1;
    char Buffer [80];
    chtype ch;

    savetty ();

    clear();
    refresh();
#ifdef __PDCURSES__
    resize_screen(50);
#endif


    win1 = newwin(11, 50, 14, 25);
    if(win1 == NULL)
    {   endwin();
        return;
    }
#ifdef A_COLOR
    if (has_colors())
      {
       init_pair(3,COLOR_BLUE,COLOR_WHITE);
       wattrset(win1, COLOR_PAIR(3));
      }
#endif
    wclear (win1);

    mvwaddstr(win1, 1, 1, "The screen may now have 50 lines");
    Continue(win1);

    resetty ();

    wclear (win1);
    mvwaddstr(win1, 1, 1, "The screen should now be reset");
    Continue(win1);

    delwin(win1);

    clear();
    refresh();

}
#endif

#ifdef __STDC__
void padTest(WINDOW *dummy)
#else
void padTest(dummy)
WINDOW *dummy;
#endif
{
WINDOW *pad,*spad;

 pad = newpad(50,100);
 wattron(pad, A_REVERSE);
 mvwaddstr(pad, 5, 2, "This is a new pad");
 wattrset(pad,0);
 mvwaddstr(pad, 8, 0, "The end of this line should be truncated here:except  now");
 mvwaddstr(pad,11, 1, "This line should not appear.It will now");
 wmove(pad, 10, 1);
 wclrtoeol(pad);
 mvwaddstr(pad, 10, 1, " Press any key to continue");
 prefresh(pad,0,0,0,0,10,45);
 keypad(pad, TRUE);
 raw();
 wgetch(pad);

 spad = subpad(pad,12,25,6,52);
 mvwaddstr(spad, 2, 2, "This is a new subpad");
 box(spad,0,0);
 prefresh(pad,0,0,0,0,15,75);
 keypad(pad, TRUE);
 raw();
 wgetch(pad);

 mvwaddstr(pad, 35, 2, "This is displayed at line 35 in the pad");
 mvwaddstr(pad, 40, 1, " Press any key to continue");
 prefresh(pad,30,0,0,0,10,45);
 keypad(pad, TRUE);
 raw();
 wgetch(pad);

 delwin(pad);
}

#ifdef __STDC__
void display_menu(int old_option,int new_option)
#else
void display_menu(old_option,new_option)
int old_option,new_option;
#endif
{
 register int i;

 attrset(A_NORMAL);
 mvaddstr(3,20,"PDCurses Test Program");

 for (i=0;i<MAX_OPTIONS;i++)
    mvaddstr(5+i,25,command[i].text);
 if (old_option != (-1))
    mvaddstr(5+old_option,25,command[old_option].text);
 attrset(A_REVERSE);
 mvaddstr(5+new_option,25,command[new_option].text);
 attrset(A_NORMAL);
 mvaddstr(13,3,"Use Up and Down Arrows to select - Enter to run - Q to quit");
 refresh();
}

