/****************************************************************************
 * Copyright 2022 Leonid S. Usov <leonid.s.usov at gmail.com>               *
 * Copyright 2022 Thomas E. Dickey                                          *
 *                                                                          *
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 * copy of this software and associated documentation files (the            *
 * "Software"), to deal in the Software without restriction, including      *
 * without limitation the rights to use, copy, modify, merge, publish,      *
 * distribute, distribute with modifications, sublicense, and/or sell       *
 * copies of the Software, and to permit persons to whom the Software is    *
 * furnished to do so, subject to the following conditions:                 *
 *                                                                          *
 * The above copyright notice and this permission notice shall be included  *
 * in all copies or substantial portions of the Software.                   *
 *                                                                          *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 ****************************************************************************/
/*
 * $Id: test_mouse.c,v 1.26 2022/12/04 00:40:11 tom Exp $
 *
 * Author: Leonid S Usov
 *
 * Observe mouse events in the raw terminal or parsed ncurses modes
 */

#include <test.priv.h>

#if defined(NCURSES_MOUSE_VERSION) && !defined(_NC_WINDOWS)

static int logoffset = 0;

static int
raw_loop(void)
{
    struct termios tty;
    struct termios old;
    char *xtermcap;

    tcgetattr(0, &old);
#if HAVE_CFMAKERAW
    cfmakeraw(&tty);
#else
    tty = old;
    tty.c_iflag &= (unsigned) (~(IGNBRK | BRKINT | PARMRK | ISTRIP
				 | INLCR | IGNCR | ICRNL | IXON));
    tty.c_oflag &= (unsigned) (~OPOST);
    tty.c_lflag &= (unsigned) (~(ECHO | ECHONL | ICANON | ISIG | IEXTEN));
    tty.c_cflag &= (unsigned) (~(CSIZE | PARENB));
    tty.c_cflag |= CS8;
    tcsetattr(0, TCSANOW, &tty);
#endif

    setupterm(NULL, 0, 0);
    xtermcap = tigetstr("XM");
    if (!VALID_STRING(xtermcap)) {
	fprintf(stderr, "couldn't get XM terminfo");
	return 1;
    }

    putp(tparm(xtermcap, 1));
    fflush(stdout);

    tcsetattr(0, TCSANOW, &tty);

    while (1) {
	int c = getc(stdin);
	const char *pretty;

	if (c == -1 || c == '\003') {
	    break;
	} else if (c == '\033') {
	    printf("\r\n\\E");
	} else if ((pretty = unctrl((chtype) c)) != NULL) {
	    printf("%s", pretty);
	} else if (isprint(c)) {
	    printf("%c", c);
	} else {
	    printf("{%x}", UChar(c));
	}
    }

    putp(tparm(xtermcap, 0));
    fflush(stdout);
    tcsetattr(0, TCSANOW, &old);
    return 0;
}

static void logw(const char *fmt, ...) GCC_PRINTFLIKE(1, 2);

static void
logw(const char *fmt, ...)
{
    int row = getcury(stdscr);
    va_list args;

    va_start(args, fmt);
    wmove(stdscr, row++, 0);
    vw_printw(stdscr, fmt, args);
    va_end(args);

    clrtoeol();

    row %= (getmaxy(stdscr) - logoffset);
    if (row < logoffset) {
	row = logoffset;
    }

    wmove(stdscr, row, 0);
    wprintw(stdscr, ">");
    clrtoeol();
}

static void
usage(int ok)
{
    static const char *msg[] =
    {
	"Usage: test_mouse [options]"
	,""
	,"Test mouse events.  These examples for $TERM demonstrate xterm"
	,"features:"
	,"    xterm"
	,"    xterm-1002"
	,"    xterm-1003"
	,""
	,USAGE_COMMON
	,"Options:"
	," -r       show raw input stream, injecting a new line before every ESC"
	," -i n     set mouse interval to n; default is 0 (no double-clicks)"
	," -T term  use terminal description other than $TERM"
    };
    unsigned n;
    for (n = 0; n < sizeof(msg) / sizeof(char *); ++n) {
	fprintf(stderr, "%s\n", msg[n]);
    }
    ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
/* *INDENT-OFF* */
VERSION_COMMON()
/* *INDENT-ON* */

int
main(int argc, char *argv[])
{
    bool rawmode = FALSE;
    int interval = 0;
    int ch;
    MEVENT event;
    char *my_environ = NULL;
    const char *term_format = "TERM=%s";

    while ((ch = getopt(argc, argv, OPTS_COMMON "i:rT:")) != -1) {
	switch (ch) {
	case 'i':
	    interval = atoi(optarg);
	    break;
	case 'r':
	    rawmode = TRUE;
	    break;
	case 'T':
	    my_environ = malloc(strlen(term_format) + strlen(optarg));
	    sprintf(my_environ, term_format, optarg);
	    putenv(my_environ);
	    break;
	case OPTS_VERSION:
	    show_version(argv);
	    ExitProgram(EXIT_SUCCESS);
	default:
	    usage(ch == OPTS_USAGE);
	    /* NOTREACHED */
	}
    }
    if (optind < argc) {
	usage(FALSE);
	ExitProgram(EXIT_FAILURE);
    }

    if (rawmode) {
	printf("Entering raw mode. Ctrl-c to quit.\n");
	return raw_loop();
    }

    initscr();
    noecho();
    cbreak();			/* Line buffering disabled; pass everything */
    nonl();
    keypad(stdscr, TRUE);

    /* Get all the mouse events */
    mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
    mouseinterval(interval);

    logw("Ctrl-c to quit");
    logw("--------------");
    if (my_environ)
	logw("%s", my_environ);
    logoffset = getcury(stdscr);

    while (1) {
	int c = getch();

	switch (c) {
	case KEY_MOUSE:
	    if (getmouse(&event) == OK) {
		unsigned btn;
		mmask_t events;
#if NCURSES_MOUSE_VERSION > 1
		const unsigned max_btn = 5;
#else
		const unsigned max_btn = 4;
#endif
		const mmask_t btn_mask = (NCURSES_BUTTON_RELEASED |
					  NCURSES_BUTTON_PRESSED |
					  NCURSES_BUTTON_CLICKED |
					  NCURSES_DOUBLE_CLICKED |
					  NCURSES_TRIPLE_CLICKED);
		bool found = FALSE;
		for (btn = 1; btn <= max_btn; btn++) {
		    events = (mmask_t) (event.bstate
					& NCURSES_MOUSE_MASK(btn, btn_mask));
		    if (events == 0)
			continue;
#define ShowQ(btn,name) \
	(((event.bstate & NCURSES_MOUSE_MASK(btn, NCURSES_ ## name)) != 0) \
	 ? (" " #name) \
	 : "")
#define ShowM(name) \
	(((event.bstate & NCURSES_MOUSE_MASK(btn, BUTTON_ ## name)) != 0) \
	 ? (" " #name) \
	 : "")
#define ShowP() \
	 ((event.bstate & REPORT_MOUSE_POSITION) != 0 \
	  ? " position" \
	  : "")
		    logw("[%08lX] button %d%s%s%s%s%s%s%s%s%s @ %d, %d",
			 (unsigned long) events,
			 btn,
			 ShowQ(btn, BUTTON_RELEASED),
			 ShowQ(btn, BUTTON_PRESSED),
			 ShowQ(btn, BUTTON_CLICKED),
			 ShowQ(btn, DOUBLE_CLICKED),
			 ShowQ(btn, TRIPLE_CLICKED),
			 ShowM(SHIFT),
			 ShowM(CTRL),
			 ShowM(ALT),
			 ShowP(),
			 event.y, event.x);
		    found = TRUE;
		}
		/*
		 * A position report need not have a button associated with it.
		 * The modifiers probably are unused.
		 */
		if (!found && (event.bstate & REPORT_MOUSE_POSITION)) {
		    logw("[%08lX]%s%s%s%s @ %d, %d",
			 (unsigned long) events,
			 ShowM(SHIFT),
			 ShowM(CTRL),
			 ShowM(ALT),
			 ShowP(),
			 event.y, event.x);
		}
	    }
	    break;
	case '\003':
	    goto end;
	default:
	    logw("got another char: 0x%x", UChar(c));
	}
	refresh();
    }
  end:
    endwin();
    ExitProgram(EXIT_SUCCESS);
}
#else
int
main(void)
{
    printf("This program requires the ncurses library\n");
    ExitProgram(EXIT_FAILURE);
}
#endif
