/*
 *  textbox.c -- implements the text box
 *
 *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
 *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "dialog.h"

static void back_lines(int n);
static void print_page(WINDOW * win, int height, int width);
static void print_line(WINDOW * win, int row, int width);
static char *get_line(void);
static void print_position(WINDOW * win, int height, int width);

static int hscroll, fd, file_size, bytes_read;
static int begin_reached = 1, end_reached, page_length;
static char *buf, *page;

/*
 * Display text from a file in a dialog box.
 */
int dialog_textbox(const char *title, const char *file, int height, int width)
{
	int i, x, y, cur_x, cur_y, fpos, key = 0;
	int passed_end;
	char search_term[MAX_LEN + 1];
	WINDOW *dialog, *text;

	search_term[0] = '\0';	/* no search term entered yet */

	/* Open input file for reading */
	if ((fd = open(file, O_RDONLY)) == -1) {
		endwin();
		fprintf(stderr,
			"\nCan't open input file in dialog_textbox().\n");
		exit(-1);
	}
	/* Get file size. Actually, 'file_size' is the real file size - 1,
	   since it's only the last byte offset from the beginning */
	if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
		endwin();
		fprintf(stderr,
			"\nError getting file size in dialog_textbox().\n");
		exit(-1);
	}
	/* Restore file pointer to beginning of file after getting file size */
	if (lseek(fd, 0, SEEK_SET) == -1) {
		endwin();
		fprintf(stderr,
			"\nError moving file pointer in dialog_textbox().\n");
		exit(-1);
	}
	/* Allocate space for read buffer */
	if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
		endwin();
		fprintf(stderr,
			"\nCan't allocate memory in dialog_textbox().\n");
		exit(-1);
	}
	if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
		endwin();
		fprintf(stderr, "\nError reading file in dialog_textbox().\n");
		exit(-1);
	}
	buf[bytes_read] = '\0';	/* mark end of valid data */
	page = buf;		/* page is pointer to start of page to be displayed */

	/* center dialog box on screen */
	x = (COLS - width) / 2;
	y = (LINES - height) / 2;

	draw_shadow(stdscr, y, x, height, width);

	dialog = newwin(height, width, y, x);
	keypad(dialog, TRUE);

	/* Create window for text region, used for scrolling text */
	text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
	wattrset(text, dialog_attr);
	wbkgdset(text, dialog_attr & A_COLOR);

	keypad(text, TRUE);

	/* register the new window, along with its borders */
	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);

	wattrset(dialog, border_attr);
	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
	for (i = 0; i < width - 2; i++)
		waddch(dialog, ACS_HLINE);
	wattrset(dialog, dialog_attr);
	wbkgdset(dialog, dialog_attr & A_COLOR);
	waddch(dialog, ACS_RTEE);

	if (title != NULL && strlen(title) >= width - 2) {
		/* truncate long title -- mec */
		char *title2 = malloc(width - 2 + 1);
		memcpy(title2, title, width - 2);
		title2[width - 2] = '\0';
		title = title2;
	}

	if (title != NULL) {
		wattrset(dialog, title_attr);
		mvwaddch(dialog, 0, (width - strlen(title)) / 2 - 1, ' ');
		waddstr(dialog, (char *)title);
		waddch(dialog, ' ');
	}
	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
	wnoutrefresh(dialog);
	getyx(dialog, cur_y, cur_x);	/* Save cursor position */

	/* Print first page of text */
	attr_clear(text, height - 4, width - 2, dialog_attr);
	print_page(text, height - 4, width - 2);
	print_position(dialog, height, width);
	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
	wrefresh(dialog);

	while ((key != ESC) && (key != '\n')) {
		key = wgetch(dialog);
		switch (key) {
		case 'E':	/* Exit */
		case 'e':
		case 'X':
		case 'x':
			delwin(dialog);
			free(buf);
			close(fd);
			return 0;
		case 'g':	/* First page */
		case KEY_HOME:
			if (!begin_reached) {
				begin_reached = 1;
				/* First page not in buffer? */
				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
					endwin();
					fprintf(stderr,
						"\nError moving file pointer in dialog_textbox().\n");
					exit(-1);
				}
				if (fpos > bytes_read) {	/* Yes, we have to read it in */
					if (lseek(fd, 0, SEEK_SET) == -1) {
						endwin();
						fprintf(stderr,
							"\nError moving file pointer in "
							"dialog_textbox().\n");
						exit(-1);
					}
					if ((bytes_read =
					     read(fd, buf, BUF_SIZE)) == -1) {
						endwin();
						fprintf(stderr,
							"\nError reading file in dialog_textbox().\n");
						exit(-1);
					}
					buf[bytes_read] = '\0';
				}
				page = buf;
				print_page(text, height - 4, width - 2);
				print_position(dialog, height, width);
				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
				wrefresh(dialog);
			}
			break;
		case 'G':	/* Last page */
		case KEY_END:

			end_reached = 1;
			/* Last page not in buffer? */
			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
				endwin();
				fprintf(stderr,
					"\nError moving file pointer in dialog_textbox().\n");
				exit(-1);
			}
			if (fpos < file_size) {	/* Yes, we have to read it in */
				if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
					endwin();
					fprintf(stderr,
						"\nError moving file pointer in dialog_textbox().\n");
					exit(-1);
				}
				if ((bytes_read =
				     read(fd, buf, BUF_SIZE)) == -1) {
					endwin();
					fprintf(stderr,
						"\nError reading file in dialog_textbox().\n");
					exit(-1);
				}
				buf[bytes_read] = '\0';
			}
			page = buf + bytes_read;
			back_lines(height - 4);
			print_page(text, height - 4, width - 2);
			print_position(dialog, height, width);
			wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
			wrefresh(dialog);
			break;
		case 'K':	/* Previous line */
		case 'k':
		case KEY_UP:
			if (!begin_reached) {
				back_lines(page_length + 1);

				/* We don't call print_page() here but use scrolling to ensure
				   faster screen update. However, 'end_reached' and
				   'page_length' should still be updated, and 'page' should
				   point to start of next page. This is done by calling
				   get_line() in the following 'for' loop. */
				scrollok(text, TRUE);
				wscrl(text, -1);	/* Scroll text region down one line */
				scrollok(text, FALSE);
				page_length = 0;
				passed_end = 0;
				for (i = 0; i < height - 4; i++) {
					if (!i) {
						/* print first line of page */
						print_line(text, 0, width - 2);
						wnoutrefresh(text);
					} else
						/* Called to update 'end_reached' and 'page' */
						get_line();
					if (!passed_end)
						page_length++;
					if (end_reached && !passed_end)
						passed_end = 1;
				}

				print_position(dialog, height, width);
				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
				wrefresh(dialog);
			}
			break;
		case 'B':	/* Previous page */
		case 'b':
		case KEY_PPAGE:
			if (begin_reached)
				break;
			back_lines(page_length + height - 4);
			print_page(text, height - 4, width - 2);
			print_position(dialog, height, width);
			wmove(dialog, cur_y, cur_x);
			wrefresh(dialog);
			break;
		case 'J':	/* Next line */
		case 'j':
		case KEY_DOWN:
			if (!end_reached) {
				begin_reached = 0;
				scrollok(text, TRUE);
				scroll(text);	/* Scroll text region up one line */
				scrollok(text, FALSE);
				print_line(text, height - 5, width - 2);
				wnoutrefresh(text);
				print_position(dialog, height, width);
				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
				wrefresh(dialog);
			}
			break;
		case KEY_NPAGE:	/* Next page */
		case ' ':
			if (end_reached)
				break;

			begin_reached = 0;
			print_page(text, height - 4, width - 2);
			print_position(dialog, height, width);
			wmove(dialog, cur_y, cur_x);
			wrefresh(dialog);
			break;
		case '0':	/* Beginning of line */
		case 'H':	/* Scroll left */
		case 'h':
		case KEY_LEFT:
			if (hscroll <= 0)
				break;

			if (key == '0')
				hscroll = 0;
			else
				hscroll--;
			/* Reprint current page to scroll horizontally */
			back_lines(page_length);
			print_page(text, height - 4, width - 2);
			wmove(dialog, cur_y, cur_x);
			wrefresh(dialog);
			break;
		case 'L':	/* Scroll right */
		case 'l':
		case KEY_RIGHT:
			if (hscroll >= MAX_LEN)
				break;
			hscroll++;
			/* Reprint current page to scroll horizontally */
			back_lines(page_length);
			print_page(text, height - 4, width - 2);
			wmove(dialog, cur_y, cur_x);
			wrefresh(dialog);
			break;
		case ESC:
			break;
		}
	}

	delwin(dialog);
	free(buf);
	close(fd);
	return -1;		/* ESC pressed */
}

/*
 * Go back 'n' lines in text file. Called by dialog_textbox().
 * 'page' will be updated to point to the desired line in 'buf'.
 */
static void back_lines(int n)
{
	int i, fpos;

	begin_reached = 0;
	/* We have to distinguish between end_reached and !end_reached
	   since at end of file, the line is not ended by a '\n'.
	   The code inside 'if' basically does a '--page' to move one
	   character backward so as to skip '\n' of the previous line */
	if (!end_reached) {
		/* Either beginning of buffer or beginning of file reached? */
		if (page == buf) {
			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
				endwin();
				fprintf(stderr,
					"\nError moving file pointer in "
					"back_lines().\n");
				exit(-1);
			}
			if (fpos > bytes_read) {	/* Not beginning of file yet */
				/* We've reached beginning of buffer, but not beginning of
				   file yet, so read previous part of file into buffer.
				   Note that we only move backward for BUF_SIZE/2 bytes,
				   but not BUF_SIZE bytes to avoid re-reading again in
				   print_page() later */
				/* Really possible to move backward BUF_SIZE/2 bytes? */
				if (fpos < BUF_SIZE / 2 + bytes_read) {
					/* No, move less then */
					if (lseek(fd, 0, SEEK_SET) == -1) {
						endwin();
						fprintf(stderr,
							"\nError moving file pointer in "
							"back_lines().\n");
						exit(-1);
					}
					page = buf + fpos - bytes_read;
				} else {	/* Move backward BUF_SIZE/2 bytes */
					if (lseek
					    (fd, -(BUF_SIZE / 2 + bytes_read),
					     SEEK_CUR)
					    == -1) {
						endwin();
						fprintf(stderr,
							"\nError moving file pointer "
							"in back_lines().\n");
						exit(-1);
					}
					page = buf + BUF_SIZE / 2;
				}
				if ((bytes_read =
				     read(fd, buf, BUF_SIZE)) == -1) {
					endwin();
					fprintf(stderr,
						"\nError reading file in back_lines().\n");
					exit(-1);
				}
				buf[bytes_read] = '\0';
			} else {	/* Beginning of file reached */
				begin_reached = 1;
				return;
			}
		}
		if (*(--page) != '\n') {	/* '--page' here */
			/* Something's wrong... */
			endwin();
			fprintf(stderr, "\nInternal error in back_lines().\n");
			exit(-1);
		}
	}
	/* Go back 'n' lines */
	for (i = 0; i < n; i++)
		do {
			if (page == buf) {
				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
					endwin();
					fprintf(stderr,
						"\nError moving file pointer in back_lines().\n");
					exit(-1);
				}
				if (fpos > bytes_read) {
					/* Really possible to move backward BUF_SIZE/2 bytes? */
					if (fpos < BUF_SIZE / 2 + bytes_read) {
						/* No, move less then */
						if (lseek(fd, 0, SEEK_SET) ==
						    -1) {
							endwin();
							fprintf(stderr,
								"\nError moving file pointer "
								"in back_lines().\n");
							exit(-1);
						}
						page = buf + fpos - bytes_read;
					} else {	/* Move backward BUF_SIZE/2 bytes */
						if (lseek
						    (fd,
						     -(BUF_SIZE / 2 +
						       bytes_read),
						     SEEK_CUR) == -1) {
							endwin();
							fprintf(stderr,
								"\nError moving file pointer"
								" in back_lines().\n");
							exit(-1);
						}
						page = buf + BUF_SIZE / 2;
					}
					if ((bytes_read =
					     read(fd, buf, BUF_SIZE)) == -1) {
						endwin();
						fprintf(stderr,
							"\nError reading file in "
							"back_lines().\n");
						exit(-1);
					}
					buf[bytes_read] = '\0';
				} else {	/* Beginning of file reached */
					begin_reached = 1;
					return;
				}
			}
		} while (*(--page) != '\n');
	page++;
}

/*
 * Print a new page of text. Called by dialog_textbox().
 */
static void print_page(WINDOW * win, int height, int width)
{
	int i, passed_end = 0;

	page_length = 0;
	for (i = 0; i < height; i++) {
		print_line(win, i, width);
		if (!passed_end)
			page_length++;
		if (end_reached && !passed_end)
			passed_end = 1;
	}
	wnoutrefresh(win);
}

/*
 * Print a new line of text. Called by dialog_textbox() and print_page().
 */
static void print_line(WINDOW * win, int row, int width)
{
	int y, x;
	char *line;

	line = get_line();
	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
	wmove(win, row, 0);	/* move cursor to correct line */
	waddch(win, ' ');
	waddnstr(win, line, MIN(strlen(line), width - 2));

	getyx(win, y, x);
	/* Clear 'residue' of previous line */
#if OLD_NCURSES
	{
		int i;
		for (i = 0; i < width - x; i++)
			waddch(win, ' ');
	}
#else
	wclrtoeol(win);
#endif
}

/*
 * Return current line of text. Called by dialog_textbox() and print_line().
 * 'page' should point to start of current line before calling, and will be
 * updated to point to start of next line.
 */
static char *get_line(void)
{
	int i = 0, fpos;
	static char line[MAX_LEN + 1];

	end_reached = 0;
	while (*page != '\n') {
		if (*page == '\0') {
			/* Either end of file or end of buffer reached */
			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
				endwin();
				fprintf(stderr,
					"\nError moving file pointer in "
					"get_line().\n");
				exit(-1);
			}
			if (fpos < file_size) {	/* Not end of file yet */
				/* We've reached end of buffer, but not end of file yet,
				   so read next part of file into buffer */
				if ((bytes_read =
				     read(fd, buf, BUF_SIZE)) == -1) {
					endwin();
					fprintf(stderr,
						"\nError reading file in get_line().\n");
					exit(-1);
				}
				buf[bytes_read] = '\0';
				page = buf;
			} else {
				if (!end_reached)
					end_reached = 1;
				break;
			}
		} else if (i < MAX_LEN)
			line[i++] = *(page++);
		else {
			/* Truncate lines longer than MAX_LEN characters */
			if (i == MAX_LEN)
				line[i++] = '\0';
			page++;
		}
	}
	if (i <= MAX_LEN)
		line[i] = '\0';
	if (!end_reached)
		page++;		/* move pass '\n' */

	return line;
}

/*
 * Print current position
 */
static void print_position(WINDOW * win, int height, int width)
{
	int fpos, percent;

	if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
		endwin();
		fprintf(stderr,
			"\nError moving file pointer in print_position().\n");
		exit(-1);
	}
	wattrset(win, position_indicator_attr);
	wbkgdset(win, position_indicator_attr & A_COLOR);
	percent = !file_size ?
	    100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
	wmove(win, height - 3, width - 9);
	wprintw(win, "(%3d%%)", percent);
}
