/*
 *  newdemo.c	-	A demo program using PDCurses. The program illustrate
 *  	 		the use of colours for text output.
 *
 * $Id: newdemo.c,v 1.41 2014/08/02 23:10:56 tom Exp $
 */

#include <test.priv.h>

#include <time.h>

/*
 *  The Australian map
 */
static CONST_MENUS char *AusMap[16] =
{
    "           A           A ",
    "    N.T. AAAAA       AAAA ",
    "     AAAAAAAAAAA  AAAAAAAA ",
    "   AAAAAAAAAAAAAAAAAAAAAAAAA Qld.",
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
    " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
    "   AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.",
    "W.A. AAAAAAAAA      AAAAAA Vic.",
    "       AAA   S.A.     AA",
    "                       A  Tas.",
    ""
};

/*
 *  Funny messages
 */
#define NMESSAGES   6

static const char *messages[] =
{
    "Hello from the Land Down Under",
    "The Land of crocs. and a big Red Rock",
    "Where the sunflower runs along the highways",
    "the dusty red roads lead one to loneliness",
    "Blue sky in the morning and",
    "freezing nights and twinkling stars",
    ""
};

/*
 *  Trap interrupt
 */
static void
trap(int sig GCC_UNUSED)
{
    endwin();
    ExitProgram(EXIT_FAILURE);
}

/*
 *  Wait for user
 */
static int
WaitForUser(WINDOW *win)
{
    time_t t;
    chtype key;

    nodelay(win, TRUE);
    t = time((time_t *) 0);
    while (1) {
	if ((int) (key = (chtype) wgetch(win)) != ERR) {
	    if (key == 'q' || key == 'Q')
		return 1;
	    else
		return 0;
	}
	if (time((time_t *) 0) - t > 5)
	    return 0;
    }
}

static void
set_colors(WINDOW *win, int pair, int foreground, int background)
{
    if (has_colors()) {
	if (pair > COLOR_PAIRS)
	    pair = COLOR_PAIRS;
	init_pair((short) pair, (short) foreground, (short) background);
	(void) wattrset(win, AttrArg(COLOR_PAIR(pair), 0));
    }
}

static chtype
use_colors(WINDOW *win, int pair, chtype attrs)
{
    if (has_colors()) {
	if (pair > COLOR_PAIRS)
	    pair = COLOR_PAIRS;
	attrs |= (chtype) COLOR_PAIR(pair);
    }
    (void) wattrset(win, AttrArg(attrs, 0));
    return attrs;
}

/*
 * Test sub windows
 */
static int
SubWinTest(WINDOW *win)
{
    int w, h, sw, sh, bx, by;
    WINDOW *swin1, *swin2, *swin3;

    getmaxyx(win, h, w);
    getbegyx(win, by, bx);
    sw = w / 3;
    sh = h / 3;

    if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) {
	return 1;
    }
    if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) {
	delwin(swin1);
	return 1;
    }
    if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) {
	delwin(swin1);
	delwin(swin2);
	return 1;
    }

    set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
    werase(swin1);
    MvWAddStr(swin1, 0, 3, "Sub-window 1");
    wrefresh(swin1);

    set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
    werase(swin2);
    MvWAddStr(swin2, 0, 3, "Sub-window 2");
    wrefresh(swin2);

    set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
    werase(swin3);
    MvWAddStr(swin3, 0, 3, "Sub-window 3");
    wrefresh(swin3);

    delwin(swin1);
    delwin(swin2);
    delwin(swin3);
    WaitForUser(win);
    return 0;
}

static int
bounce(int n, int *dir, int len)
{
    if (*dir > 0)
	++n;
    else
	--n;
    if (n <= 1 || n >= len - 2)
	*dir = *dir ? 0 : 1;
    return n;
}

/*
 *  Bouncing balls
 */
static int
BouncingBalls(WINDOW *win)
{
    int w, h;
    int x1, y1, xd1, yd1;
    int x2, y2, xd2, yd2;
    int x3, y3, xd3, yd3;

    getmaxyx(win, h, w);

    x1 = 2 + rand() % (w - 4);
    y1 = 2 + rand() % (h - 4);
    x2 = 2 + rand() % (w - 4);
    y2 = 2 + rand() % (h - 4);
    x3 = 2 + rand() % (w - 4);
    y3 = 2 + rand() % (h - 4);

    xd1 = 1;
    yd1 = 1;
    xd2 = 1;
    yd2 = 0;
    xd3 = 0;
    yd3 = 1;

    nodelay(win, TRUE);

    while (wgetch(win) == ERR) {
	x1 = bounce(x1, &xd1, w);
	y1 = bounce(y1, &yd1, h);
	x2 = bounce(x2, &xd2, w);
	y2 = bounce(y2, &yd2, h);
	x3 = bounce(x3, &xd3, w);
	y3 = bounce(y3, &yd3, h);

	set_colors(win, 11, COLOR_RED, COLOR_BLUE);
	MvWAddCh(win, y1, x1, 'O');

	set_colors(win, 12, COLOR_BLUE, COLOR_RED);
	MvWAddCh(win, y2, x2, '*');

	set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
	MvWAddCh(win, y3, x3, '@');

	wmove(win, 0, 0);
	wrefresh(win);
	delay_output(100);
    }
    return 0;
}

/*
 *  Main driver
 */
int
main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
{
    WINDOW *win;
    int w, x, y, i, j, k;
    char buffer[SIZEOF(messages) * 80];
    const char *message;
    int width, height;
    chtype save[80];
    chtype c;

    setlocale(LC_ALL, "");

    CATCHALL(trap);

    initscr();
    if (has_colors())
	start_color();
    cbreak();
    curs_set(0);
    width = 48;
    height = 14;		/* Create a drawing window */
    win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
    if (win == NULL) {
	endwin();
	ExitProgram(EXIT_FAILURE);
    }

    while (1) {
	set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
	werase(win);

	set_colors(win, 2, COLOR_RED, COLOR_RED);
	box(win, ACS_VLINE, ACS_HLINE);
	wrefresh(win);
	/* Do ramdom output of a character */
	use_colors(win, 1, A_NORMAL);
	c = 'a';
	for (i = 0; i < 5000; ++i) {
	    x = rand() % (width - 2) + 1;
	    y = rand() % (height - 2) + 1;
	    MvWAddCh(win, y, x, c);
	    wrefresh(win);
	    nodelay(win, TRUE);
	    if (wgetch(win) != ERR)
		break;
	    if (i == 2000) {
		c = 'b';
		set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
	    }
	}

	SubWinTest(win);
	/* Erase and draw green window */
	set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
	wbkgd(win, use_colors(win, 4, A_BOLD));
	werase(win);
	wrefresh(win);
	/* Draw RED bounding box */
	use_colors(win, 2, A_NORMAL);
	box(win, ' ', ' ');
	wrefresh(win);
	/* Display Australia map */
	use_colors(win, 4, A_BOLD);
	i = 0;
	while (*AusMap[i]) {
	    MvWAddStr(win, i + 1, 8, AusMap[i]);
	    wrefresh(win);
	    delay_output(50);
	    ++i;
	}

	set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
	use_colors(win, 5, A_BLINK);
	MvWAddStr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
	wrefresh(win);

	/* Draw running messages */
	set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
	message = messages[j = 0];
	i = 1;
	w = width - 2;
	strcpy(buffer, message);
	while (j < NMESSAGES) {
	    while ((int) strlen(buffer) < w) {
		strcat(buffer, " ... ");
		strcat(buffer, messages[++j % NMESSAGES]);
	    }

	    if (i < w)
		(void) mvwaddnstr(win, height / 2, w - i, buffer, i);
	    else
		(void) mvwaddnstr(win, height / 2, 1, buffer, w);

	    wrefresh(win);
	    nodelay(win, TRUE);
	    if (wgetch(win) != ERR) {
		flushinp();
		break;
	    }
	    if (i++ >= w) {
		for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
	    }
	    delay_output(100);
	}

	j = 0;
	/*  Draw running As across in RED */
	set_colors(win, 7, COLOR_RED, COLOR_GREEN);
	memset(save, ' ', sizeof(save));
	for (i = 2; i < width - 4; ++i) {
	    k = (int) mvwinch(win, 4, i);
	    if (k == ERR)
		break;
	    save[j++] = c = (chtype) k;
	    c &= A_CHARTEXT;
	    MvWAddCh(win, 4, i, c);
	}
	wrefresh(win);

	/* Put a message up wait for a key */
	i = height - 2;
	use_colors(win, 5, A_NORMAL);
	MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
	wrefresh(win);

	if (WaitForUser(win) == 1)
	    break;

	j = 0;			/* Restore the old line */
	for (i = 2; i < width - 4; ++i)
	    MvWAddCh(win, 4, i, save[j++]);
	wrefresh(win);

	BouncingBalls(win);
	/* Put a message up wait for a key */
	i = height - 2;
	use_colors(win, 5, A_NORMAL);
	MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
	wrefresh(win);
	if (WaitForUser(win) == 1)
	    break;
    }
    endwin();
    ExitProgram(EXIT_SUCCESS);
}
