/*
 * GLIB - a Generic LIBrarian and editor for synths
 *
 * Machine dependent stuff.
 */

#include "glib.h"
#include <ctype.h>

int Rows, Cols;

#define EscSeq(x) Cconout('\033');Cconout(x);
struct iorecinfo {
	char *ibuf;
	int ibufsiz;
	int ibufhd;
	int ibuftl;
	int ibuflow;
	int ibufhigh;
};
#define MIDIBUFSIZE 5000
char *Origbuf;
int Origsize;
struct iorecinfo *Ioptr;
int work_in[12], work_out[60];  /* GEM & VDI stuff */
int intin[128], ptsin[128];
int intout[128], ptsout[128];
int contrl[12];
int Handle, Vhandle;

/* These contain the raw voice data */
hello()
{
	int dummy, n;

	appl_init();

	/* Get the Midi Iorec and put in a bigger buffer */
	flushmidi();
	Ioptr = (struct iorecinfo *)(Iorec(2));
	Origbuf = Ioptr->ibuf;
	Origsize = Ioptr->ibufsiz;
	Ioptr->ibuf = alloc(MIDIBUFSIZ);
	Ioptr->ibufsiz = MIDIBUFSIZ;
	Ioptr->ibuftl = Ioptr->ibufhd = 0;
	Cursconf(2,0);		/* set non-blinking block cursor */
	mouseon();
}

bye()
{
	/* Restore the original Midi Iorec buffer */
	flushmidi();
	Ioptr->ibuf = Origbuf;
	Ioptr->ibufsiz = Origsize;
	Ioptr->ibuftl = Ioptr->ibufhd = 0;
	mouseoff();
	appl_exit();

	/* are these ever called? SAF */
	windgoto(23,0);
	windrefresh();
	windexit(0);
}

/* getmouse - get currect row and column of mouse */
getmouse(amr,amc)
int *amr;
int *amc;
{
#ifdef USEMOUSE
	int button, ret, keycode, tmp1, tmp2;
	char msgbuf[8];

	graf_mkstate(amc,amr,&tmp1,&tmp2);
	/* evnt_multi(MU_TIMER,
		0,0,0,
		0,0,0,0,0,
		0,0,0,0,0,
		msgbuf, 0, 0,
		amc, amr, &button, &ret, &keycode, &ret); */
	/* convert bitmap x,y coordinates to row,colum */
	*amr = (*amr)/16;
	*amc = (*amc)/8;
#else
	*amr = -1;
	*amc = -1;
#endif
}

/* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
statmouse()
{
#ifdef USEMOUSE
	int tmp1, tmp2, tmp3, buttons;
	char msgbuf[8];

	graf_mkstate(&tmp1,&tmp2,&buttons,&tmp3);
	/* evnt_multi(MU_TIMER,
		0,0,0,
		0,0,0,0,0,
		0,0,0,0,0,
		msgbuf, 0, 0,
		&tmp1, &tmp1, &buttons, &tmp1, &tmp1, &tmp1); */
	return(buttons);
#else
	return(-1);
#endif
}

int Mouseshown = 0;
mouseon()
{
#ifdef USEMOUSE
	if ( Mouseshown == 0 ) {
		Vsync();	/* wait until next VBI to ensure updating */
		Cursconf(1,0);		/* show block cursor */
		Vsync();	/* wait until next VBI to ensure updating */
		graf_mouse(257,NULL);	/* display mouse cursor */
		Mouseshown = 1;
		Vsync();
	}
#endif
}
mouseoff()
{
#ifdef USEMOUSE
	if ( Mouseshown == 1 ) {
		Vsync();	/* wait until next VBI to ensure updating */
		graf_mouse(256,NULL);	/* hide mouse cursor */
		Vsync();	/* wait until next VBI to ensure updating */
		Cursconf(0,0);		/* hide block cursor */
		Mouseshown = 0;
		Vsync();
	}
#endif
}

/* Return when either a console key or mouse button is pressed. */
mouseorkey()
{
#ifdef USEMOUSE
	int evnt, ret, keycode, button, mx, my, tmp1, tmp2, tmp3;
	char msgbuf[8];

	mouseon();
	for ( ;; ) {
		graf_mkstate(&tmp1,&tmp2,&button,&tmp3);
		/* evnt = evnt_multi(MU_TIMER,
			0,0,0,
			0,0,0,0,0,
			0,0,0,0,0,
			msgbuf, 0, 0,
			&mx, &my, &button, &ret, &keycode, &ret); */
		if ( button != 0 ) {
			return(MOUSE);
		}
		if ( statmouse() > 0 )
			return(MOUSE);
		if ( statconsole() )
			return(getconsole());
	}
#else
	return(getconsole());
#endif
}

flushconsole()
{
	while ( statconsole() )
		getconsole();
}

statconsole()
{
	/* return(Bconstat(CONSOLE)); */
	return(Cconis());
}

getconsole()
{
	/* return(Bconin(CONSOLE)); */
	return(Crawcin());
}

getmidi()
{
	return(Bconin(MIDI));
}

/*ARGSUSED*/
sendmidi(c)
{
	Bconout(MIDI,c);
}

flushmidi()
{
	while ( STATMIDI )
		getmidi();
}

long milliclock()
{
	register long save_ssp=Super(0L);
	register long uhz200= *(long *)0x4ba;
	Super(save_ssp);
	return(uhz200 * 5);
}

millisleep(n)
{
	long first = milliclock();
	while ( milliclock() < (first+n) )
		;
}

char *
alloc(n)
{
	char *p;

	if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
		printf("*** Whoops *** alloc has failed?!?  No more memory!\n");
		fflush(stdout);
		bye();
	}
	return(p);
}

windinit()
{
	Cols=80;
	Rows=25;
	Cursconf(1,NULL);
}

windgoto(r,c)
int r,c;
{
	mouseoff();
	EscSeq('Y');
	Cconout(r+040);
	Cconout(c+040);
}

windeeol()
{
	mouseoff();
	EscSeq('K');
}

winderaserow(r)
{
	windgoto(r,0);
	windeeol();
}

windexit(r)
int r;
{
	exit(r);
}

windclear()
{
	mouseoff();
	EscSeq('H');
	EscSeq('J');
}

/* windgets - get a line of input from the console, handling backspaces */
windgets(s)
char *s;
{
	char *origs = s;
	int c;

	while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
		if ( c == '\b' ) {
			if ( s > origs ) {
				windstr("\b \b");
				s--;
			}
		}
		else {
			windputc(c);
			*s++ = c;
		}
		windrefresh();
	}
	*s = '\0';
}

windstr(s)
char *s;
{
	int c;

	while ( (c=(*s++)) != '\0' )
		windputc(c);
}

windputc(c)
int c;
{
	mouseoff();
	Cconout(c);
}

windrefresh()
{
}

beep()
{
	Cconout('\007');
}

windhigh()
{
}

windnorm()
{
}

/****************
 * openls(), nextls(), and closels() are used to scan the current directory.
 ***************/

char Dtabuff[44];
long Origdta;
int Atarifirst = 0;

char *
openls()
{
	int n, c;

	Origdta = Fgetdta();
	Fsetdta(Dtabuff);
	Atarifirst = 1;
}
char *
nextls()
{
	static char fname[17];
	int n, c;

	if ( Atarifirst ) {
		if ( Fsfirst("*.*",0x10) < 0 )
			return(NULL);
	}
	else {
		if ( Fsnext() < 0 )
			return(NULL);
	}
	Atarifirst = 0;
	for ( n=0; n<14; n++ ) {
		c = fname[n] = Dtabuff[30+n];
		/* ALL phrase names are lower case */
		if ( c >= 'A' && c <= 'Z' )
			fname[n] = c - 'A' + 'a';
	}
	fname[14] = '\0';
	return(fname);
}
closels()
{
	Fsetdta((char *)Origdta);
}

