/*  curses.c */

#include <ctype.h>

/* small curses 
	Bob Leivian -- some of the curses routines are here
	add to them as you see fit -- the basic I/O routines are from
	the micro EMACS routines from FISH disk # 23

	Bob Leivian
	2702 W. Curry
	Chandler Az 85224 
	602-820-6859   mot!dover!leivian
*/

/*
 * Name:	MicroEMACS
 *		AmigaDOS terminal I/O
 * Version:	31
 * Compiler:	Manx Aztec C
 * Created:	19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
 */
#include	<libraries/dos.h>
#include	<libraries/dosextens.h>
#undef TRUE
#undef FALSE

#define	NIBUF	128		/* Probably excessive.		*/
#define	NOBUF	512		/* Not too big for 750/730.	*/

struct	FileHandle	*tty;
struct	FileHandle	*Open();
char	obuf[NOBUF];	/* Output buffer		*/
int	nobuf;				/* # of bytes in above		*/
char	ibuf[NIBUF];	/* Input buffer			*/
int	nibuf;				/* # of bytes in above		*/
int	nrow;				/* Terminal size, rows.		*/
int	ncol;				/* Terminal size, columns.	*/

#ifdef	MANX
extern	int	Enable_Abort;
#endif
extern char version[];

/*
 * This routine gets called once, to set up the
 * terminal channel.
 */
ttopen()
{
	char WindowName[80];
	
	nrow = 23;
	ncol = 77;
	nobuf = nibuf = 0;
#ifdef	MANX
	Enable_Abort = 0;	/* Disable ^C during file I/O */
#endif
	strcpy(WindowName,"RAW:0/0/640/200/");
	strcat(WindowName, version);
	tty = Open(WindowName, MODE_NEWFILE);
	if (tty == (struct FileHandle *) 0) {
		printf("Can't open window!\n");
		exit(200);
	}
}

/*
 * This function gets called just
 * before we go back home to the command interpreter.
 * On the Amiga it closes up the virtual terminal window.
 */
ttclose()
{
	if (tty != (struct FileHandle *) 0L) {
		ttflush();
		Close(tty);
	}
	tty = /*(struct FileHandle *)*/ NULL;
#ifdef MANX
	Enable_Abort = 1;
#endif
}

/*
 * Write a character to the display.
 * On the Amiga, terminal output is buffered, and
 * we just put the characters in the big array,
 * after cheching for overflow.
 */
ttputc(c)
{
	if (nobuf >= NOBUF)
		ttflush();
	obuf[nobuf++] = c;
}

/*
 * This function does the real work of
 * flushing out buffered I/O on the Amiga. All
 * we do is blast out the block with a write call.
 */
ttflush()
{
	if (nobuf > 0) {
		Write(tty,obuf,(long) nobuf);
		nobuf = 0;
	}
}

/*
 * Read a character from the terminal,
 * performing no editing and doing conditional echo 
 */
int do_echo = 1; /* echo flag */

ttgetc()
{
	unsigned char c, ignore;	/* must be unsigned! */

	ttflush();

	Read(tty,&c,1L);
	if (c == '\x9b') {
		Read(tty, &c, 1L);

		/* was it a function key  */
		if (isdigit(c))
			Read(tty, &ignore, 1L);

		/* return the char with top bit set */
		c |= 0x80;
	} else 
		if (do_echo) 
			ttputc(c);

	return ((int) c);
}

/*
 * Write a string to the terminal 
 */
ttputs(s)
char *s;
{
	while(*s) ttputc(*s++);
	ttflush();
}

char scr_buf[24][80];
int scr_row, scr_col;


/* this is some the curses routines */

standout()
{
	/* standout (in this case by reverse vidio) */
	ttputs("\x9b7m");
}

standend()
{
	ttputs("\x9bm");
}

move(x,y)
{
	char buf[32];


	sprintf(buf, "\x9b%d;%dH", x+1, y+1);
	ttputs(buf);
	ttflush();

	scr_row = x;
	scr_col = y;
}

addstr(s)
char *s;
{
	while(*s) {
		ttputc(*s);
		if(*s == '\n') {
		   scr_row++;
		   scr_col = 0;
		}
		scr_buf[scr_row][scr_col++] = *s++;
		if(scr_col >= 78)
			break;
	}
	ttflush();
}

mvaddstr(x,y,s)
int x,y;
char *s;
{
	move(x,y);
	addstr(s);
}

addch(c)
char c;
{
	ttputc(c);
	scr_buf[scr_row][scr_col] = c;
	scr_col++;
}

mvaddch(x,y,c)
int x,y;
char c;
{
	move(x, y);
	addch(c);
}

inch()
{
	return scr_buf[scr_row] [scr_col];
}

refresh()
{
}

clrtobot()
{
	int i,j;

	ttputs("\x9bJ");
	for (j = scr_col; j < 79; j++)
		scr_buf[scr_row][j] = ' ';
	for (i = scr_row++; i < 23; i++)
		for (j = 0; j < 79; j++)
			scr_buf[i][j] = ' ';
}

clrtoeol()
{
	int i;

	ttputs("\x9bK");
	for (i = scr_col; i < 79; i++)
		scr_buf[scr_row][i] = ' ';
}

clear()
{
	int i,j;

	ttputc('\f');
	for (i = 0; i < 23; i++)
		for (j = 0; j < 79; j++)
			scr_buf[i][j] = ' ';
}

initscr()
{
	ttopen();
	clear();
}

crmode()
{
}

noecho()
{
	do_echo = 0;
}

echo()
{
	do_echo = 1;
}

endwin()
{
	ttclose();
}

printw(a,b,c,d,e)
char *a;
char *b;
{
	char buf[132];
	
	sprintf(buf, a,b,c,d,e);
	addstr(buf);
}

scanw(fmt, buf)
char *fmt;
char *buf;
{
   char temp[32];
   int i = 0;
   int c;
   
again:
   c = ttgetc();
   if(c == 8 ) { i--; if (i <= 0) i = 0; goto again;}
   if(c > 32 ) {
      temp[i++] = c;
      if ( i < 30) goto again;
   }   

   temp[i] = '\0';

   sscanf(temp, fmt, buf);
}

