/*

/usr/src/ext2ed/win.c

A part of the extended file system 2 disk editor.

--------------------------------------------------------
Window management - Interfacing with the ncurses library
--------------------------------------------------------

First written on: April 17 1995
Modified on : April 05 2001 Christian.Bac@int-evry.fr
it looks like readline does not like that initscr decides to set the tty to
noecho.

Copyright (C) 1995 Gadi Oxman

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include "ext2ed.h"
#include "../version.h"

struct struct_pad_info show_pad_info;
WINDOW *title_win,*show_win,*command_win,*mt_win1,*mt_win2,*show_pad;

/* to remember configuration after initscr 
 * and modify it
 */
struct termios termioInit, termioCurrent;

void draw_title_win (void)
{
	char title_string [128];

	werase(title_win);
	box (title_win,0,0);
	sprintf (title_string,"EXT2ED - Extended-2 File System editor ver %s (%s)", E2FSPROGS_VERSION, E2FSPROGS_DATE);
	wmove (title_win,TITLE_WIN_LINES/2,(COLS-strlen (title_string))/2);
	wprintw (title_win,title_string);
	wrefresh(title_win);
}

void setup_show_win(void)
{
	wbkgdset (show_win,A_REVERSE);werase (show_win);
	show_pad_info.line=0;
	show_pad_info.col=0;
	show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
	show_pad_info.display_cols=COLS;
	show_pad_info.max_line=show_pad_info.display_lines-1;show_pad_info.max_col=show_pad_info.display_cols-1;
	show_pad_info.disable_output=0;
}	

void init_windows (void)
{
	initscr ();
	tcgetattr(0,&termioInit); /* save initial config */
	termioCurrent = termioInit;
	termioCurrent.c_lflag |= ECHO; /* set echo on */
	tcsetattr(0,TCSANOW,&termioCurrent);
	
	if (LINES<TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3) {
		printf ("Sorry, your terminal screen is too small\n");
		printf ("Error - Can not initialize windows\n");
		exit (1);
	}

	title_win=newwin (TITLE_WIN_LINES,COLS,0,0);
	show_win=newwin (SHOW_WIN_LINES,COLS,TITLE_WIN_LINES,0);
	show_pad=newpad (SHOW_PAD_LINES,SHOW_PAD_COLS);
	mt_win1=newwin (1,COLS,TITLE_WIN_LINES+SHOW_WIN_LINES,0);
	mt_win2=newwin (1,COLS,LINES-COMMAND_WIN_LINES-1,0);
	command_win=newwin (COMMAND_WIN_LINES,COLS,LINES-COMMAND_WIN_LINES,0);

	if (title_win==NULL || show_win==NULL || show_pad==NULL || command_win==NULL) {
		printf ("Error - Not enough memory - Can not initialize windows\n");exit (1);
	}

	draw_title_win();

	setup_show_win();

	scrollok (command_win,TRUE);

	refresh_title_win ();
	refresh_show_win ();
	refresh_show_pad();
	refresh_command_win ();
	wrefresh(mt_win1);
	wrefresh(mt_win2);
}

void refresh_title_win (void)
{
	wrefresh (title_win);
}

void refresh_show_win (void)
{
	int current_page,total_pages;
	
	current_page=show_pad_info.line/show_pad_info.display_lines+1;
	if (show_pad_info.line%show_pad_info.display_lines)
		current_page++;
	total_pages=show_pad_info.max_line/show_pad_info.display_lines+1;

	wmove (show_win,2,COLS-18);
	wprintw (show_win,"Page %d of %d\n",current_page,total_pages);

	wmove (show_win,2,COLS-18);
	wrefresh (show_win);
}


void refresh_show_pad (void)

{
	int left,top,right,bottom,i;
	
	if (show_pad_info.disable_output)
		return;
		
	if (show_pad_info.max_line < show_pad_info.display_lines-1) {
		for (i=show_pad_info.max_line+1;i<show_pad_info.display_lines;i++) {
			wmove (show_pad,i,0);wprintw (show_pad,"\n");
		}
	}
	left=0;right=show_pad_info.display_cols-1;
	top=TITLE_WIN_LINES+SHOW_WIN_LINES+1;bottom=top+show_pad_info.display_lines-1;

	if (show_pad_info.line > show_pad_info.max_line-show_pad_info.display_lines+1)
		show_pad_info.line=show_pad_info.max_line-show_pad_info.display_lines+1;

	if (show_pad_info.line < 0)
		show_pad_info.line=0;

#ifdef OLD_NCURSES
	prefresh (show_pad,show_pad_info.line,show_pad_info.col,top,left,show_pad_info.display_lines-1,show_pad_info.display_cols-1);
#else
	prefresh (show_pad,show_pad_info.line,show_pad_info.col,top,left,top+show_pad_info.display_lines-1,left+show_pad_info.display_cols-1);
#endif
}

void refresh_command_win (void)
{
	wrefresh (command_win);
}

void close_windows (void)
{
//	echo ();
	tcsetattr(0,TCSANOW,&termioInit);
	
	delwin (title_win);
	delwin (command_win);
	delwin (show_win);
	delwin (show_pad);
	
	endwin ();
}

void show_info (void)
{
	int block_num,block_offset;
	
	block_num=device_offset/file_system_info.block_size;
	block_offset=device_offset%file_system_info.block_size;

	wmove (show_win,0,0);
	wprintw (show_win,"Offset %-3ld in block %ld. ",block_offset,block_num);
	if (current_type != NULL)
		wprintw (show_win,"Type: %s\n",current_type->name);
	else
		wprintw (show_win,"Type: %s\n","none");

	refresh_show_win ();
}


void redraw_all (void)
{
	int min_lines = TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3;
	struct winsize ws;
	int	save_col, save_lines;

	/* get the size of the terminal connected to stdout */
	ioctl(1, TIOCGWINSZ, &ws);
	/*
	 * Do it again because GDB doesn't stop before the first ioctl
	 * call, we want an up-to-date size when we're
	 * single-stepping.
	 */
	if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
		if (ws.ws_row < min_lines)
			ws.ws_row = min_lines;
		if ((ws.ws_row != LINES) || (ws.ws_col != COLS)) {
			wmove (show_win,2,COLS-18);
			wclrtoeol(show_win);
			wrefresh(show_win);
			resizeterm(ws.ws_row, ws.ws_col);
			wresize(title_win, TITLE_WIN_LINES,COLS);
			wresize(show_win, SHOW_WIN_LINES,COLS);
			wresize(command_win, COMMAND_WIN_LINES,COLS);
			wresize(mt_win1, 1,COLS);
			wresize(mt_win2, 1,COLS);
			mvwin(mt_win2, LINES-COMMAND_WIN_LINES-1,0);
			mvwin(command_win, LINES-COMMAND_WIN_LINES,0);
			draw_title_win();
			show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2;
			show_pad_info.display_cols=COLS;
		}
	}
	clearok(title_win, 1);
	clearok(show_win, 1);
	clearok(command_win, 1);
	clearok(mt_win1, 1);
	clearok(mt_win2, 1);
	wrefresh(mt_win1);
	wrefresh(mt_win2);
	refresh_show_pad();
	refresh_show_win();
	refresh_title_win ();
	refresh_command_win ();
}
