#include "all.h"
#include "edt.h"
#ifdef __TURBOC__
#define DASHCHAR 249
#include <alloc.h>
#include "bios.h"
#include "conio.h"
#include "dir.h"
#else
#define DASHCHAR '.'
#include "vaxconio.h"
#endif

#define true (!false)
#define false 0
#define BCOLOR BLUE
#define FCOLOR MAGENTA
/* function prototypes */

/*
manip /com=a.a

	refresh screen.
	edit cell mode,
	command mode.
	arrow keys scroll screen.

	data cell:range
	cell:range = expression
	expressions,   	c,r,x,y,c1..cn,r1..rn,sum(range),
			c(x-1,y) = c(x,y)

*/
/* global stuff */
int gle_debug;
int moving_x,moving_y;
int data_x;
int data_y;
int changed;
extern int islogging;
extern int isating;
/* local stuff */
int iserr,dont_clear;
int scr_frow=1,scr_fcol=1;
int scr_width=76,scr_colwidth=8;
int scr_ncol;
int scr_nrow=18;
int curx,cury;
int max_x=0,max_y=0; 	/* change to 1,1 */

int scr_blackwhite;
int exit_manip;
char file_name[80];
int in_recover,single_step;
char gleroot[80];
extern char strmiss[];
/*---------------------------------------------------------------------------*/
main(int argc, char **argv)
{
	int i;
	char ans[90];
	int cmd;
	static char atfile[80];
	char *ss;
	strcpy(gleroot,argv[0]);
#ifdef __TURBOC__
	ss = strchr(gleroot,'\\');
	if (ss==NULL) {fner("Unable to locat help file, press key to continue\n"); getch();}
	for (;strchr(ss+1,'\\')!=NULL;) ss = strchr(ss+1,'\\');
	*(ss+1) = 0;
#endif

	if (strmiss[0]==0) strcpy(strmiss,"-");

	for (i=1;i<argc;i++) {
		strupr( argv[i] );
		if (strncmp( argv[i] , "-RECOVER",2)==0) in_recover = true;
		else if (strncmp( argv[i] , "-STEP",3)==0) single_step = true ;
		else if (strncmp( argv[i] , "-SIZE",4)==0) {
			data_setsize(atoi(argv[i+1]),atoi(argv[i+2]));
			i+=2;
		}
		else if (strncmp( argv[i] , "-COMMANDS",2)==0) strcpy(atfile,argv[++i]);
		else if (strncmp( argv[i] , "-DEBUG",2)==0) 		;
		else if (strncmp( argv[i] , "-FLOAT",2)==0)  set_usefloat();
		else if (strncmp( argv[i] , "-SINGLE",4)==0)  set_usefloat();
		else if (isalnum(*argv[i])) strcpy(file_name, argv[i]);
		else {
			printf("Unrecognized parameter {%s} \n",argv[i]);
			printf("Usage: MANIP infile.dat -recover -step -commands c.log -single -size x y\n");
			exit(0);
		}
	}
	init_logging(file_name);


	if (atfile[0]!=0) at_open(atfile);
	if (strlen(file_name)>0) cmd_load(file_name,"",2);
xx1:
	if (strlen(file_name)==0) strcpy(file_name,"mtest.dat");
	set_colwidth(10);
	changed = false;
	for (;exit_manip==false;) {
		top_line();
		hi_cell(curx,cury);
		mjl_flush();
		read_command(&cmd,ans,"% ");
		if (cmd==eescape || cmd==equit) break;
		if (cmd==0) 	do_command(ans);
		else if (cmd==eload) {
			pick_file(ans,"*.dat");
			refresh();
			clear_data();
			cmd_load(ans,"",2);
		} else if (cmd==ehelp) {
			do_help("MANIP","");
			refresh();
		} else if (cmd==esave) {
			text_save();
			refresh();
		} else if (cmd==eload) {
			refresh();
		} else	   do_arrow(cmd);
	}
	if (cmd==eescape) if (text_changed()) { exit_manip = false; goto xx1;}
	window_exit();
	if (islogging) log_close();
}
text_changed()
{
	int c;
	if (!changed) return false;
	for (;;) {
		fner("Save in {%s} ? (Y,N)",file_name);
		c = text_inkey();
		fner_clear();
		if (c==eescape) return true;
		if (tolower(c)=='n') return false;
		if (tolower(c)=='y') {text_save(); return false;}
	}
}
text_save()
{
	cmd_save(file_name,"","",2);
	changed = false;
}
fix_cur()
{
	if (curx<1) curx = 1;
	if (cury<1) cury = 1;
}
shift_window()
{
	int doit=false;
	fix_cur();
	if (curx<scr_fcol || curx >= scr_fcol + scr_ncol) {
		scr_fcol = curx - scr_ncol/2;
		if (scr_fcol<1) scr_fcol = 1;
		doit = true;
	}
	if (cury<scr_frow || cury >= scr_frow + scr_nrow) {
		scr_frow = cury - scr_nrow/2;
		if (scr_frow<1) scr_frow = 1;
		doit = true;
	}
	if (doit) refresh();
}
do_arrow(int k)
{
	char buff[80];
	show_cellwide(curx,cury);
	moving_x = moving_y = 0;
	switch (k) {
	case eup:	cury--; moving_y = -1;  break;
	case edown:     cury++; moving_y = 1; break;
	case eright:	curx++; moving_x = 1; break;
	case eleft:	curx--; moving_x = -1; break;
	}
	sprintf(buff,"goto %d %d ",curx,cury);
	if (islogging) log_write(buff);
	shift_window();
	hi_cell(curx,cury);
}
set_newxy(int x, int y)
{
	show_cellwide(curx,cury);
	curx = x;
	cury = y;
	shift_window();
	hi_cell(curx,cury);
}
window_norm()
{
	window(1,1,80,25);
}
window_exit()
{
	window(1,1,80,25);
	gotoxy(1,25);
	scr_norm();
	printf("\n");clreol();
}
set_colwidth(int n)
{
	scr_colwidth = n;
	scr_ncol = scr_width/scr_colwidth;
	shift_window();
	refresh();
}
set_ncol(int n)
{
	scr_ncol = n;
	scr_colwidth = scr_width/scr_ncol;
	scr_ncol;
	shift_window();
	refresh();
}
top_line()
{
	gotoxy(1,1); clreol();
	wprintf("Free=%ld  Used(%d,%d) MANIP 1.1    Current file={%s}"
		,coreleft(),max_x,max_y,file_name);
}
void refresh()
{
	int i,j;

	fix_cur();
	window_norm();
	scr_norm();
	clrscr();
	top_line();
	fner_clear();

	scr_menuhi();
	for (i=1;i<=scr_ncol;i++) {
		gotocell(i+scr_fcol-1,scr_frow-1);
		wprintf("c%d",i+scr_fcol-1);
	}
	for (i=1;i<=scr_nrow;i++) {
		gotocell(scr_fcol-1,i+scr_frow-1);
		wprintf("r%d",i+scr_frow-1);
	}
	scr_norm();

	for (j=0;j<scr_nrow;j++) {
	 for (i=0;i<scr_ncol;i++) {
		show_cell(i+scr_fcol,j+scr_frow);
	 }
	}
	iserr = true;
	fner_clear();
	hi_cell(curx,cury);
}
hi_cell(int x,int y)
{
	scr_menuhi();
	show_cellwide(x,y);
	scr_norm();
}
gotocell(int x,int y)
{
	if (x==scr_fcol-1) gotoxy( (x-scr_fcol+1)*scr_colwidth+1,(y-scr_frow)+3);
	else gotoxy( (x-scr_fcol)*scr_colwidth+6,(y-scr_frow)+3);
}
void show_ifcell(int x, int y)
{
	if (x>=scr_fcol && x<(scr_fcol+scr_ncol)) {
	if (y>=scr_frow && y<(scr_frow+scr_nrow)) {
		show_cellwide(x,y);
	}
	}
}
void show_cell(int x, int y)
{
	gotocell(x,y);
	cputs(scell(x,y));
}
void show_cellwide(int x, int y)
{
	char buff[80];
	gotocell(x,y);
	strcpy(buff,scell(x,y));
	if (strlen(buff)<(scr_colwidth-1)) ncpy(buff+strlen(buff),"                ",
			scr_colwidth-strlen(buff)-1);
	cputs(buff);
}
void wprintf(va_list arg_list, ...)
/* Prints to the window */
{
 	va_list arg_ptr;
 	char *format;
	char output[200];

 	va_start(arg_ptr, arg_list);
 	format = arg_list;
 	vsprintf(output, format, arg_ptr);
#ifdef __TURBOC__
	printf(output);
#else
	cputs(output);
#endif
}

void fner(va_list arg_list, ...)
/* Prints to the window */
{
 	va_list arg_ptr;
 	char *format;
	char output[200];

 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	if (strchr(output,'\n')!=NULL) *strchr(output,'\n') = 0;
	fnerx(output);
}
void printmess(va_list arg_list, ...)
/* Prints to the window */
{
 	va_list arg_ptr;
 	char *format;
	char output[200];

 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	if (strchr(output,'\n')!=NULL) *strchr(output,'\n') = 0;
	fnerxx(output);
}
d_tidyup()
{}
gle_abort(char *s)
{
	fner("ABORT {%s}\n",s);
	exit(1);
}

char *function_bar(void);
void fner_clear(void)
{
	if (iserr==false) return;
	if (dont_clear) return;
	scr_savexy();
	window_norm();
	gotoxy(1,25);
	scr_grey();
	clreol();
	gotoxy(2,25);
	cputs(function_bar());
	scr_norm();
	iserr = false;
	window_norm();
	scr_restorexy();
}
fnerx(char *s)
{
	if (dont_clear) return;
	scr_savexy();
	iserr = true;
	window_norm();
	gotoxy(1,25);
	scr_inv();
	clreol();
	gotoxy(2,25);
	cputs(s);
	scr_norm();
	scr_restorexy();
	scr_refresh();
}
fnerxx(char *s)
{
	scr_savexy();
	command_scroll_up();
	iserr = true;
	window_norm();
	gotoxy(1,23);
	scr_inv();
	clreol();
	gotoxy(2,23);
	cputs(s);
	scr_norm();
	scr_restorexy();
	scr_refresh();
}
int read_command(int *cmd,char *ans,char *ques)
{
	static char *lastline[22];
	int cl=0;
	int rr,i;
	int direc=0;

	if (isating) {
		if (!at_read(ans)) goto contxx;
		window(1,21,80,24);
		gotoxy(1,4);
		scr_inv();
		clreol();
		gotoxy(2,4);
		clreol(); *cmd = 0;
		cputs(ques); cputs(ans);  rr = false;
		goto xxend;
	}
contxx:;
	*ans = 0;
	iserr = true;
	window(1,21,80,24);
	gotoxy(1,4);
	scr_inv();
	clreol();
xxxx:	gotoxy(2,4);
	clreol();
	cputs(ques);
	rr = read_str(cmd,ans);
	if (*cmd == epageup) {
		if (direc==-1) cl++;
		if (lastline[cl]!=NULL) {
			strcpy(ans,lastline[cl]);
			cl++;
		}
		if (cl>18) cl = 0;
		direc = 1;
		goto xxxx;
	}
	if (*cmd == epagedown) {
		if (direc==1) cl--;
		cl--;
		direc = -1;
		if (cl<0) {cl = -1; *ans = 0; goto xxxx;}
		if (lastline[cl]!=NULL) strcpy(ans,lastline[cl]);
		goto xxxx;
	}
xxend:
	gotoxy(1,4);
	if (strlen(ans)>0) {
		if (lastline[20]!=NULL) free(lastline[20]);
		for (i=20;i>0;i--) lastline[i] = lastline[i-1];
		lastline[0] = sdup(ans);
		command_scroll_up();
	}
	scr_norm();
	clreol();
	window_norm();
	return rr;
}
int read_str(int *cmd, char *s)
{
	int c,cx=0;
	char mbuff[80];
	*cmd = 0;
	cputs(s); cx = strlen(s);
	for (;;) {
	 c = text_inkey();
	 if (iserr) fner_clear();
	 if (strlen(s)==0) {
		switch (c) {
		  case eup:
		  case edown:
		  case eleft:
		  case eright:
		  case equit:
		  case eescape:
		  case eload:
		  case esave:
		  case ehelp:
		     *cmd = c;
		     return false;
		}
	 }
	 switch (c) {
	   case ebackline:
		c = epageup;
	  case eload:
	  case esave:
	  case ehelp:
	   case epagedown:
	   case epageup:
		*cmd = c;
		return false;
	   case eescape: /* ESCAPE */
	   case equit: /* control c */
		return true;
	   case eleft: /* left */
		if (cx <= 0) break;
		cx--;
		scr_left(1);
		break;
	   case eright: /* right */
		if (cx >= strlen(s)) break;
		cx++;
		scr_right(1);
		break;
	   case eup: /* arrow up */
	   case edown: /* arrow down */
		break;
	  case ereturn: /* carriage return */
		return false;
	  case edelete: /* delete */
		if (strlen(s)==0) break;
		if (cx<1) break;
		ncpy(mbuff,s,cx-1);
		strcat(mbuff,s + cx);
		strcpy(s,mbuff);
		cx--;
		scr_left(1);
		cputs(s + cx);
		putch(' ');
		scr_left(strlen(s+cx)+1);
		break;
	  case eshowerror:
	  case edrawit:
		break;
	  default: /* normal key */
		if (c<26  && c!=9) {fner("Key has no affect"); break;}
		if (c>200)  fner("Unimplemented command");
		else {
			ncpy(mbuff,s,cx);
			mbuff[cx] = c; mbuff[cx+1] = 0;
			strcat(mbuff,s + cx);
			strcpy(s,mbuff);
			cputs(s + cx);
			cx++;
			scr_left(strlen(s+cx));
		}
		break;
	   }
	 }
}
command_scroll_up()
{
	window(1,21,80,24);
	gotoxy(1,1);
	delline();
}
char *gle_top()
{
	char *s;
#ifdef __TURBOC__
	return gleroot;
#else
	return "cgle_top:";
#endif
}
char *gledir(char *fname)
{
	static char fbuff[80];
#ifdef __TURBOC__
	strcpy(fbuff,gle_top());
#else
	strcpy(fbuff,"cgle_top:");
#endif
	strcat(fbuff,fname);
	return &fbuff[0];
}
