/*
 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
 * Released under the terms of the GNU GPL v2.0.
 *
 * Derived from menuconfig.
 *
 */
#include "nconf.h"

/* a list of all the different widgets we use */
attributes_t attributes[ATTR_MAX+1] = {0};

/* available colors:
   COLOR_BLACK   0
   COLOR_RED     1
   COLOR_GREEN   2
   COLOR_YELLOW  3
   COLOR_BLUE    4
   COLOR_MAGENTA 5
   COLOR_CYAN    6
   COLOR_WHITE   7
   */
static void set_normal_colors(void)
{
	init_pair(NORMAL, -1, -1);
	init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);

	/* FORE is for the selected item */
	init_pair(MAIN_MENU_FORE, -1, -1);
	/* BACK for all the rest */
	init_pair(MAIN_MENU_BACK, -1, -1);
	init_pair(MAIN_MENU_GREY, -1, -1);
	init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
	init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);

	init_pair(SCROLLWIN_TEXT, -1, -1);
	init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
	init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);

	init_pair(DIALOG_TEXT, -1, -1);
	init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
	init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
	init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);

	init_pair(INPUT_BOX, COLOR_YELLOW, -1);
	init_pair(INPUT_HEADING, COLOR_GREEN, -1);
	init_pair(INPUT_TEXT, -1, -1);
	init_pair(INPUT_FIELD, -1, -1);

	init_pair(FUNCTION_HIGHLIGHT, -1, -1);
	init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
}

/* available attributes:
   A_NORMAL        Normal display (no highlight)
   A_STANDOUT      Best highlighting mode of the terminal.
   A_UNDERLINE     Underlining
   A_REVERSE       Reverse video
   A_BLINK         Blinking
   A_DIM           Half bright
   A_BOLD          Extra bright or bold
   A_PROTECT       Protected mode
   A_INVIS         Invisible or blank mode
   A_ALTCHARSET    Alternate character set
   A_CHARTEXT      Bit-mask to extract a character
   COLOR_PAIR(n)   Color-pair number n
   */
static void normal_color_theme(void)
{
	/* automatically add color... */
#define mkattr(name, attr) do { \
attributes[name] = attr | COLOR_PAIR(name); } while (0)
	mkattr(NORMAL, NORMAL);
	mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);

	mkattr(MAIN_MENU_FORE, A_REVERSE);
	mkattr(MAIN_MENU_BACK, A_NORMAL);
	mkattr(MAIN_MENU_GREY, A_NORMAL);
	mkattr(MAIN_MENU_HEADING, A_BOLD);
	mkattr(MAIN_MENU_BOX, A_NORMAL);

	mkattr(SCROLLWIN_TEXT, A_NORMAL);
	mkattr(SCROLLWIN_HEADING, A_BOLD);
	mkattr(SCROLLWIN_BOX, A_BOLD);

	mkattr(DIALOG_TEXT, A_BOLD);
	mkattr(DIALOG_BOX, A_BOLD);
	mkattr(DIALOG_MENU_FORE, A_STANDOUT);
	mkattr(DIALOG_MENU_BACK, A_NORMAL);

	mkattr(INPUT_BOX, A_NORMAL);
	mkattr(INPUT_HEADING, A_BOLD);
	mkattr(INPUT_TEXT, A_NORMAL);
	mkattr(INPUT_FIELD, A_UNDERLINE);

	mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
	mkattr(FUNCTION_TEXT, A_REVERSE);
}

static void no_colors_theme(void)
{
	/* automatically add highlight, no color */
#define mkattrn(name, attr) { attributes[name] = attr; }

	mkattrn(NORMAL, NORMAL);
	mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);

	mkattrn(MAIN_MENU_FORE, A_STANDOUT);
	mkattrn(MAIN_MENU_BACK, A_NORMAL);
	mkattrn(MAIN_MENU_GREY, A_NORMAL);
	mkattrn(MAIN_MENU_HEADING, A_BOLD);
	mkattrn(MAIN_MENU_BOX, A_NORMAL);

	mkattrn(SCROLLWIN_TEXT, A_NORMAL);
	mkattrn(SCROLLWIN_HEADING, A_BOLD);
	mkattrn(SCROLLWIN_BOX, A_BOLD);

	mkattrn(DIALOG_TEXT, A_NORMAL);
	mkattrn(DIALOG_BOX, A_BOLD);
	mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
	mkattrn(DIALOG_MENU_BACK, A_NORMAL);

	mkattrn(INPUT_BOX, A_BOLD);
	mkattrn(INPUT_HEADING, A_BOLD);
	mkattrn(INPUT_TEXT, A_NORMAL);
	mkattrn(INPUT_FIELD, A_UNDERLINE);

	mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
	mkattrn(FUNCTION_TEXT, A_REVERSE);
}

void set_colors()
{
	start_color();
	use_default_colors();
	set_normal_colors();
	if (has_colors()) {
		normal_color_theme();
	} else {
		/* give defaults */
		no_colors_theme();
	}
}


/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win,
		int starty,
		int startx,
		int width,
		const char *string,
		chtype color)
{      int length, x, y;
	float temp;


	if (win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if (startx != 0)
		x = startx;
	if (starty != 0)
		y = starty;
	if (width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length) / 2;
	x = startx + (int)temp;
	(void) wattrset(win, color);
	mvwprintw(win, y, x, "%s", string);
	refresh();
}

int get_line_no(const char *text)
{
	int i;
	int total = 1;

	if (!text)
		return 0;

	for (i = 0; text[i] != '\0'; i++)
		if (text[i] == '\n')
			total++;
	return total;
}

const char *get_line(const char *text, int line_no)
{
	int i;
	int lines = 0;

	if (!text)
		return 0;

	for (i = 0; text[i] != '\0' && lines < line_no; i++)
		if (text[i] == '\n')
			lines++;
	return text+i;
}

int get_line_length(const char *line)
{
	int res = 0;
	while (*line != '\0' && *line != '\n') {
		line++;
		res++;
	}
	return res;
}

/* print all lines to the window. */
void fill_window(WINDOW *win, const char *text)
{
	int x, y;
	int total_lines = get_line_no(text);
	int i;

	getmaxyx(win, y, x);
	/* do not go over end of line */
	total_lines = min(total_lines, y);
	for (i = 0; i < total_lines; i++) {
		char tmp[x+10];
		const char *line = get_line(text, i);
		int len = get_line_length(line);
		strncpy(tmp, line, min(len, x));
		tmp[len] = '\0';
		mvwprintw(win, i, 0, "%s", tmp);
	}
}

/* get the message, and buttons.
 * each button must be a char*
 * return the selected button
 *
 * this dialog is used for 2 different things:
 * 1) show a text box, no buttons.
 * 2) show a dialog, with horizontal buttons
 */
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
{
	va_list ap;
	char *btn;
	int btns_width = 0;
	int msg_lines = 0;
	int msg_width = 0;
	int total_width;
	int win_rows = 0;
	WINDOW *win;
	WINDOW *msg_win;
	WINDOW *menu_win;
	MENU *menu;
	ITEM *btns[btn_num+1];
	int i, x, y;
	int res = -1;


	va_start(ap, btn_num);
	for (i = 0; i < btn_num; i++) {
		btn = va_arg(ap, char *);
		btns[i] = new_item(btn, "");
		btns_width += strlen(btn)+1;
	}
	va_end(ap);
	btns[btn_num] = NULL;

	/* find the widest line of msg: */
	msg_lines = get_line_no(msg);
	for (i = 0; i < msg_lines; i++) {
		const char *line = get_line(msg, i);
		int len = get_line_length(line);
		if (msg_width < len)
			msg_width = len;
	}

	total_width = max(msg_width, btns_width);
	/* place dialog in middle of screen */
	y = (LINES-(msg_lines+4))/2;
	x = (COLS-(total_width+4))/2;


	/* create the windows */
	if (btn_num > 0)
		win_rows = msg_lines+4;
	else
		win_rows = msg_lines+2;

	win = newwin(win_rows, total_width+4, y, x);
	keypad(win, TRUE);
	menu_win = derwin(win, 1, btns_width, win_rows-2,
			1+(total_width+2-btns_width)/2);
	menu = new_menu(btns);
	msg_win = derwin(win, win_rows-2, msg_width, 1,
			1+(total_width+2-msg_width)/2);

	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
	set_menu_back(menu, attributes[DIALOG_MENU_BACK]);

	(void) wattrset(win, attributes[DIALOG_BOX]);
	box(win, 0, 0);

	/* print message */
	(void) wattrset(msg_win, attributes[DIALOG_TEXT]);
	fill_window(msg_win, msg);

	set_menu_win(menu, win);
	set_menu_sub(menu, menu_win);
	set_menu_format(menu, 1, btn_num);
	menu_opts_off(menu, O_SHOWDESC);
	menu_opts_off(menu, O_SHOWMATCH);
	menu_opts_on(menu, O_ONEVALUE);
	menu_opts_on(menu, O_NONCYCLIC);
	set_menu_mark(menu, "");
	post_menu(menu);


	touchwin(win);
	refresh_all_windows(main_window);
	while ((res = wgetch(win))) {
		switch (res) {
		case KEY_LEFT:
			menu_driver(menu, REQ_LEFT_ITEM);
			break;
		case KEY_RIGHT:
			menu_driver(menu, REQ_RIGHT_ITEM);
			break;
		case 10: /* ENTER */
		case 27: /* ESCAPE */
		case ' ':
		case KEY_F(F_BACK):
		case KEY_F(F_EXIT):
			break;
		}
		touchwin(win);
		refresh_all_windows(main_window);

		if (res == 10 || res == ' ') {
			res = item_index(current_item(menu));
			break;
		} else if (res == 27 || res == KEY_F(F_BACK) ||
				res == KEY_F(F_EXIT)) {
			res = KEY_EXIT;
			break;
		}
	}

	unpost_menu(menu);
	free_menu(menu);
	for (i = 0; i < btn_num; i++)
		free_item(btns[i]);

	delwin(win);
	return res;
}

int dialog_inputbox(WINDOW *main_window,
		const char *title, const char *prompt,
		const char *init, char **resultp, int *result_len)
{
	int prompt_lines = 0;
	int prompt_width = 0;
	WINDOW *win;
	WINDOW *prompt_win;
	WINDOW *form_win;
	PANEL *panel;
	int i, x, y;
	int res = -1;
	int cursor_position = strlen(init);
	int cursor_form_win;
	char *result = *resultp;

	if (strlen(init)+1 > *result_len) {
		*result_len = strlen(init)+1;
		*resultp = result = realloc(result, *result_len);
	}

	/* find the widest line of msg: */
	prompt_lines = get_line_no(prompt);
	for (i = 0; i < prompt_lines; i++) {
		const char *line = get_line(prompt, i);
		int len = get_line_length(line);
		prompt_width = max(prompt_width, len);
	}

	if (title)
		prompt_width = max(prompt_width, strlen(title));

	/* place dialog in middle of screen */
	y = (LINES-(prompt_lines+4))/2;
	x = (COLS-(prompt_width+4))/2;

	strncpy(result, init, *result_len);

	/* create the windows */
	win = newwin(prompt_lines+6, prompt_width+7, y, x);
	prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
	form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
	keypad(form_win, TRUE);

	(void) wattrset(form_win, attributes[INPUT_FIELD]);

	(void) wattrset(win, attributes[INPUT_BOX]);
	box(win, 0, 0);
	(void) wattrset(win, attributes[INPUT_HEADING]);
	if (title)
		mvwprintw(win, 0, 3, "%s", title);

	/* print message */
	(void) wattrset(prompt_win, attributes[INPUT_TEXT]);
	fill_window(prompt_win, prompt);

	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
	cursor_form_win = min(cursor_position, prompt_width-1);
	mvwprintw(form_win, 0, 0, "%s",
		  result + cursor_position-cursor_form_win);

	/* create panels */
	panel = new_panel(win);

	/* show the cursor */
	curs_set(1);

	touchwin(win);
	refresh_all_windows(main_window);
	while ((res = wgetch(form_win))) {
		int len = strlen(result);
		switch (res) {
		case 10: /* ENTER */
		case 27: /* ESCAPE */
		case KEY_F(F_HELP):
		case KEY_F(F_EXIT):
		case KEY_F(F_BACK):
			break;
		case 127:
		case KEY_BACKSPACE:
			if (cursor_position > 0) {
				memmove(&result[cursor_position-1],
						&result[cursor_position],
						len-cursor_position+1);
				cursor_position--;
				cursor_form_win--;
				len--;
			}
			break;
		case KEY_DC:
			if (cursor_position >= 0 && cursor_position < len) {
				memmove(&result[cursor_position],
						&result[cursor_position+1],
						len-cursor_position+1);
				len--;
			}
			break;
		case KEY_UP:
		case KEY_RIGHT:
			if (cursor_position < len) {
				cursor_position++;
				cursor_form_win++;
			}
			break;
		case KEY_DOWN:
		case KEY_LEFT:
			if (cursor_position > 0) {
				cursor_position--;
				cursor_form_win--;
			}
			break;
		case KEY_HOME:
			cursor_position = 0;
			cursor_form_win = 0;
			break;
		case KEY_END:
			cursor_position = len;
			cursor_form_win = min(cursor_position, prompt_width-1);
			break;
		default:
			if ((isgraph(res) || isspace(res))) {
				/* one for new char, one for '\0' */
				if (len+2 > *result_len) {
					*result_len = len+2;
					*resultp = result = realloc(result,
								*result_len);
				}
				/* insert the char at the proper position */
				memmove(&result[cursor_position+1],
						&result[cursor_position],
						len-cursor_position+1);
				result[cursor_position] = res;
				cursor_position++;
				cursor_form_win++;
				len++;
			} else {
				mvprintw(0, 0, "unknown key: %d\n", res);
			}
			break;
		}
		if (cursor_form_win < 0)
			cursor_form_win = 0;
		else if (cursor_form_win > prompt_width-1)
			cursor_form_win = prompt_width-1;

		wmove(form_win, 0, 0);
		wclrtoeol(form_win);
		mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
		mvwprintw(form_win, 0, 0, "%s",
			result + cursor_position-cursor_form_win);
		wmove(form_win, 0, cursor_form_win);
		touchwin(win);
		refresh_all_windows(main_window);

		if (res == 10) {
			res = 0;
			break;
		} else if (res == 27 || res == KEY_F(F_BACK) ||
				res == KEY_F(F_EXIT)) {
			res = KEY_EXIT;
			break;
		} else if (res == KEY_F(F_HELP)) {
			res = 1;
			break;
		}
	}

	/* hide the cursor */
	curs_set(0);
	del_panel(panel);
	delwin(prompt_win);
	delwin(form_win);
	delwin(win);
	return res;
}

/* refresh all windows in the correct order */
void refresh_all_windows(WINDOW *main_window)
{
	update_panels();
	touchwin(main_window);
	refresh();
}

/* layman's scrollable window... */
void show_scroll_win(WINDOW *main_window,
		const char *title,
		const char *text)
{
	int res;
	int total_lines = get_line_no(text);
	int x, y;
	int start_x = 0, start_y = 0;
	int text_lines = 0, text_cols = 0;
	int total_cols = 0;
	int win_cols = 0;
	int win_lines = 0;
	int i = 0;
	WINDOW *win;
	WINDOW *pad;
	PANEL *panel;

	/* find the widest line of msg: */
	total_lines = get_line_no(text);
	for (i = 0; i < total_lines; i++) {
		const char *line = get_line(text, i);
		int len = get_line_length(line);
		total_cols = max(total_cols, len+2);
	}

	/* create the pad */
	pad = newpad(total_lines+10, total_cols+10);
	(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
	fill_window(pad, text);

	win_lines = min(total_lines+4, LINES-2);
	win_cols = min(total_cols+2, COLS-2);
	text_lines = max(win_lines-4, 0);
	text_cols = max(win_cols-2, 0);

	/* place window in middle of screen */
	y = (LINES-win_lines)/2;
	x = (COLS-win_cols)/2;

	win = newwin(win_lines, win_cols, y, x);
	keypad(win, TRUE);
	/* show the help in the help window, and show the help panel */
	(void) wattrset(win, attributes[SCROLLWIN_BOX]);
	box(win, 0, 0);
	(void) wattrset(win, attributes[SCROLLWIN_HEADING]);
	mvwprintw(win, 0, 3, " %s ", title);
	panel = new_panel(win);

	/* handle scrolling */
	do {

		copywin(pad, win, start_y, start_x, 2, 2, text_lines,
				text_cols, 0);
		print_in_middle(win,
				text_lines+2,
				0,
				text_cols,
				"<OK>",
				attributes[DIALOG_MENU_FORE]);
		wrefresh(win);

		res = wgetch(win);
		switch (res) {
		case KEY_NPAGE:
		case ' ':
			start_y += text_lines-2;
			break;
		case KEY_PPAGE:
			start_y -= text_lines+2;
			break;
		case KEY_HOME:
			start_y = 0;
			break;
		case KEY_END:
			start_y = total_lines-text_lines;
			break;
		case KEY_DOWN:
		case 'j':
			start_y++;
			break;
		case KEY_UP:
		case 'k':
			start_y--;
			break;
		case KEY_LEFT:
		case 'h':
			start_x--;
			break;
		case KEY_RIGHT:
		case 'l':
			start_x++;
			break;
		}
		if (res == 10 || res == 27 || res == 'q'
		    || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
			break;
		}
		if (start_y < 0)
			start_y = 0;
		if (start_y >= total_lines-text_lines)
			start_y = total_lines-text_lines;
		if (start_x < 0)
			start_x = 0;
		if (start_x >= total_cols-text_cols)
			start_x = total_cols-text_cols;
	} while (res);

	del_panel(panel);
	delwin(win);
	refresh_all_windows(main_window);
}
