#include "main.h"

unsigned long size;
extern int alignment;

int show_addr(address, force)
int address;
int force;
{
	int index;
	static unsigned long last_buf_size = 0;
	char ch;

	wmove(status_window, 0, 0);
	if (wdismode)
	    sprintf(out_string, "[%8d-%8d]", address, address + buf_size);
	else
	    sprintf(out_string, "[%08x-%08x]", address, address + buf_size);
	waddstr(status_window, out_string);
	wrefresh(status_window);
	
	if ((daddr != address) || (buf_size != last_buf_size)) {
		if (dirty) 
			save_changes();

		daddr = address;
		clear_buffer();
		(void) fseek(view_file, address, 0);
		if (!(size = fread(buffer, 1, buf_size, view_file)))
			if (!force)
				return(1);
		last_buf_size = buf_size;
	}

	wmove(status_window, 0, 0);
	if (wdismode)
		(void) sprintf(out_string, "[%8d-%8d]", address, address + buf_size);
	else
		(void) sprintf(out_string, "[%08x-%08x]", address, address + size);
	waddstr(status_window, out_string);
	wrefresh(status_window);
	
	if (chdis)
	    for (index = 0; index < buf_size; index++) {
		wmove(main_window, index / (wpline * 4),
		       addis * 10 + wpline * 9 * wdis + index % (wpline * 4));
		if (index < size) {
			ch = buffer[index];
			if ((((ch >= ' ') && (ch <= 'Z')) ||
			    ((ch >= 'a') && (ch <= 'z')) ||
			     (strchr(ACCEPT, ch) != NULL)) &&
			     (!strchr(DENY, ch) != NULL))
				if (strchr(REMAP, ch) != NULL)
					waddch(main_window, ' ');
				else
					waddch(main_window, ch);
			else
				waddch(main_window, '.');
		} else
			waddch(main_window, ' ');
	    }

	for (index = 0; index < (buf_size + 3) / 4; index++) {
		if (((index % wpline) == 0) && addis) {
			wmove(main_window, index / wpline, 0);
			if (index >= (size + 3) / 4)
			    waddstr(main_window, "          ");
			else {
			    if (wdismode)
				(void) sprintf(out_string, "%8d: ", index * 4 + address);
			    else
				(void) sprintf(out_string, "%08x: ", index * 4 + address);
			    waddstr(main_window, out_string);
			}
		}
		if (wdis) {
		    wmove(main_window, index / wpline, addis * 10 + (index % wpline) * 9 * wdis);
		    if (index < (size + 3) / 4)
			switch (wdismode) {
			    case 0:
				(void) sprintf(out_string, "%08x ", ibuffer[index]);
				waddstr(main_window, out_string);
				break;
			    case 1:
				(void) sprintf(out_string, "%8d ", ibuffer[index]);
/*
				out_string[8] = ' ';
*/
				out_string[8] = '\0';
				waddstr(main_window, out_string);
				break;
			    case 2:
				(void) sprintf(out_string, "%-9f ",
					    *((float *) &ibuffer[index]));
				out_string[8] = '\0';
				waddstr(main_window, out_string);
				break;
			    case 3:
				if ((index & 1) == 0) {
				    (void) sprintf(out_string, "%-18lf ",
					        *((double *) &ibuffer[index]));
				    out_string[17] = '\0';
				    waddstr(main_window, out_string);
				}
				break;
			}
		    else
			waddstr(main_window, "         ");
		}
	}
	wrefresh(main_window);
	return(0);
}

waddch_filt(ch)
char ch;
{
	if ((((ch >= ' ') && (ch <= 'Z')) ||
	    ((ch >= 'a') && (ch <= 'z')) ||
	     (strchr(ACCEPT, ch) != NULL)) &&
	     (!strchr(DENY, ch) != NULL))
		if (strchr(REMAP, ch) != NULL)
			waddch(main_window, ' ');
		else
			waddch(main_window, ch);
	else
		waddch(main_window, '.');
}

int init()
{
	initscr();
	if (LINES == 0) {
		fprintf(stderr, "Curses initialization failed.\n");
		exit(1);
	}

#ifdef sequent
	raw();
#else
	cbreak();
#endif
	noecho();
	nonl();
	clear();
	refresh();

	wpline  = (COLS - addis * 10) / (9 * wdis + chdis * 4);
	buf_size = (LINES - 1) * wpline * 4;

	main_window = newwin(LINES - 1, COLS, 1, 0);
	status_window = newwin(1, COLS, 0, 0);

	leaveok(main_window, TRUE);
	leaveok(status_window, TRUE);

	edit_mode();
}

int de_init()
{
        clear();
        refresh();
        echo();
        nl();
        endwin();
}

#define RHELP_SIZ 23
#define txtlin(x, y) { wmove(help_window, x, 1); waddstr(help_window, y); }
help_me2()
{
	WINDOW *help_window;
	help_window = newwin(RHELP_SIZ, 38, (LINES-RHELP_SIZ) / 2, COLS/2 - 19);
	(void) box(help_window, '|', '-');

	wmove(help_window, 1, 16);
	waddstr(help_window, "FV Help:");
	
	txtlin(3, "  /? = Hex Search      (For, Rev)");
	txtlin(4, "  +- = Columns    (Add, Subtract)");
	txtlin(5, "  0G = Position      (Start, End)");
	txtlin(6, "  m' = Marks       (Set, Jump to)");
	txtlin(7, "^u^d = Half Page       (Up, Down)");
	txtlin(8, "^b^f = Full Page       (Up, Down)");
	txtlin(9, " acw = Address/Char/Word Display");
	txtlin(10, "   B = Power of 2 buffer");
	txtlin(11, "   r = Reread file");
	txtlin(12, "  ^l = Redisplay text");
	txtlin(13, "   t = Word Display type  Hex/Dec");
	txtlin(14, "  qx = Quit fv");
	txtlin(15, "<space> = Last position visited");
	txtlin(16, "<tab>   = Mode       (Hex/String)");
	txtlin(17, "<hjkl>  = Scrolling");
	txtlin(18, "? in search is any byte");

/*
	wmove(help_window, 3, 3);
	waddstr(help_window, "  /? = Hex Search      (For, Rev)");
	wmove(help_window, 4, 3);
	waddstr(help_window, "  +- = Columns    (Add, Subtract)");
	wmove(help_window, 5, 3);
	waddstr(help_window, "  0G = Position      (Start, End)");
	wmove(help_window, 6, 3);
	waddstr(help_window, "  m' = Marks       (Set, Jump to)");
	wmove(help_window, 7, 3);
	waddstr(help_window, "^u^d = Half Page       (Up, Down)");
	wmove(help_window, 8, 3);
	waddstr(help_window, "^b^f = Full Page       (Up, Down)");
	wmove(help_window, 9, 3);
	waddstr(help_window, " acw = Address/Char/Word Display");
	wmove(help_window, 10, 3);
	waddstr(help_window, "   B = Power of 2 buffer");
	wmove(help_window, 11, 3);
	waddstr(help_window, "   r = Reread file");
	wmove(help_window, 12, 3);
	waddstr(help_window, "  ^l = Redisplay text");
	wmove(help_window, 13, 3);
	waddstr(help_window, "   t = Word Display type  Hex/Dec");
	wmove(help_window, 14, 3);
	waddstr(help_window, "  qx = Quit fv");
	wmove(help_window, 16, 3);
	waddstr(help_window, "<space> = Last position visited");
	wmove(help_window, 17, 3);
	waddstr(help_window, "<tab>   = Mode       (Hex/String)");
	wmove(help_window, 18, 3);
	waddstr(help_window, "<hjkl>  = Scrolling");
	wmove(help_window, 19, 3);
	waddstr(help_window, "? in search is any byte");
*/

	wmove(help_window, RHELP_SIZ - 2, 10);
	waddstr(help_window, "Press any key...");

	wrefresh(help_window);
	wgetch(help_window);
	delwin(help_window);
}

#define HELP_SIZE 20
help_me()
{
	WINDOW *help_window;
	help_window = newwin(HELP_SIZE, 49, (LINES-HELP_SIZE) / 2, COLS/2 - 24);
	(void) box(help_window, '|', '-');

	wmove(help_window, 1, 16);
	waddstr(help_window, "FV Editor Help:");

	txtlin(3, "0G()   = Start/End/Top/Bottom");
	txtlin(4, "<hjkl> = Scrolling, <HJKL> moves buffer view");
	txtlin(5, "{Enter}= Edit string or hex");
	txtlin(6, "{Tab}  = Toggle string/hex edit mode");
	txtlin(7, "wq^X   = Finished editing");
	txtlin(8, "m'     = Set/goto mark");
	txtlin(9, "twc    = Toggle hex/dec,word,character modes");
	txtlin(10, "a+-    = Toggle address mode,change columns");
	txtlin(11, "/?nN   = Search forward/backward/next");
	txtlin(12, "g      = Goto (jump) to hex address");
	txtlin(13, "HL     = Buffer window left/right");
	txtlin(14, "AC     = Append/Create file from cursor to mark");
	txtlin(15, "udfb   = Half Up/Down, Full Forward/Back page");
	txtlin(16, "t<>    = Type (hex,dec,flt,dbl) Alignment up/dn");

	wmove(help_window, HELP_SIZE - 2, 16);
	waddstr(help_window, "Press any key...");

	wrefresh(help_window);
	wgetch(help_window);
	delwin(help_window);
}

#define SHELP_SIZ 17
help_me_str()
{
	WINDOW *help_window;
	help_window = newwin(SHELP_SIZ, 44, (LINES-SHELP_SIZ) / 2, COLS/2 - 22);
	(void) box(help_window, '|', '-');

	wmove(help_window, 1, 14);
	waddstr(help_window, "FV String Editor:");

	txtlin(3, "aiAI = add/insert, add/insert at start/end");
	txtlin(4, "cd   = change/delete w=word t=to (char)");
	txtlin(5, "hkjl = cursor left/left/right/right");
	txtlin(6, "rs   = substitute single character");
	txtlin(7, "0^$  = start/start/end of line");
	txtlin(8, "uU   = undo last/all change(s)");
	txtlin(9, "^H   = delete left of cursor");
	txtlin(10, "^U   = erase line");
	txtlin(11, "^V   = next character is raw");
	txtlin(12, "ESC  = escape (command mode) from insert");

	wmove(help_window, SHELP_SIZ - 2, 14);
	waddstr(help_window, "Press any key...");

	wrefresh(help_window);
	wgetch(help_window);
	delwin(help_window);
}

clear_buffer()
{
	int index;

	for (index = 0; index < buf_size / 4; index++)
		ibuffer[index] = 0;
}
