/* $Id: mac-mach.c,v 1.6 89/05/06 17:13:32 lee Exp $
 * GLIB - a Generic LIBrarian and editor for synths
 *
 * Machine dependent stuff.
 *
 * macintosh version  -  Steven A. Falco  8/24/87
 * $Log:	mac-mach.c,v $
 * Revision 1.6  89/05/06  17:13:32  lee
 * rel. to comp.sources.misc
 * 
 */

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

int Rows, Cols;

hello()
{

#ifdef MPW
	/* Substitute our vt driver for the standard console driver.
	 * Use slot 1 since that is where the standard driver lives.
	 * This will magically hook in printf, etc.  We could do dups
	 * and closes which might be more portable, but we'd still need
	 * the _addDevHandler() call.  This is all subject to change when
	 * MPW 2.0 rolls around.
	 *
	 * NOTE: vt_read is unused in keynote.  Vt_getch and vt_peekch are
	 * used instead to avoid all system buffering.
	 */
	_addDevHandler(1, 'CONS', vt_faccess, vt_close, vt_read, vt_write, vt_ioctl);
	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
	vt_raw(); /* want ^D to work as vanilla character */
#endif

	midi_init();
}

bye()
{
	{ int waste_time;
	while(midi_txst == MIDI_NE) /* wait for all notes to drain */
		;
	for(waste_time = 0; waste_time < (1 << 14); waste_time++)
		; /* hardware fifo has to drain too */
	midi_reset(); /* now we can shut it down */
	}
	windgoto(23,0);
	windrefresh();
	exit(0);
}

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

statconsole()
{
	fflush(stdout);	/* make sure we see prompts */
	return(vt_peekch());
}

getconsole()
{
	fflush(stdout); /* flush any prompts */
	return(vt_getch());
}

getmidi()
{
	int i;
	
	while((i = midi_rx()) == -1)
		; /* wait for something good */
	
	return(i);
}

sendmidi(c)
{
	while(STATTXBF) /* it is easy to overrun on bulk dumps - slow down to uart rate */
		; /* wait till last character goes to uart */
		
	midi_tx(c);
}

flushmidi()
{
	while ( STATMIDI )
		getmidi(); /* flush any and all characters */
}

/* return relative time in 1mS steps */
long milliclock()
{
	/* relative, free-running millisecond counter (5mS granularity) */
	return(midi_time);
}

millisleep(i)
int i;
{
	long j = milliclock();
	
	while(i + j > milliclock())
		;
	
	return;
}

int Paw;
FileParam pblock;
VolumeParam dblock;
FInfo *fp;
Str255 dummystr;

/* Establish a "working directory reference number" for the user-specified
 * directory (path) in character array "pre".  This only affects
 * those calls that explicitly use the reference number - namely, the 
 * PBGetFInfo() call below.  In particular, none of this has any effect
 * whatsoever on fopen() calls.  For those, a full path name must be used.
 */
openphr(pre)
char *pre; /* the path prefix */
{
	strcpy(&dummystr, pre);	/* make a copy 'cause we change it */
	c2pstr(&dummystr);	/* we need a pascal string */
	dblock.ioCompletion = 0;
	dblock.ioNamePtr = &dummystr;	/* this is the directory path in pascal */
	dblock.ioVRefNum = 0;	/* start at the root */
	
	if(*((short *) FSFCBLen) > 0) {	/* we are running HFS */
		((WDPBRec *) &dblock)->ioWDProcID = SIGNATURE;	/* our ID */
		((WDPBRec *) &dblock)->ioWDDirID = 0;
		if(PBOpenWD(&dblock, false) != noErr) {
			printf("No such directory! (%s)\n", pre);
			dblock.ioVRefNum = 0; /* force back to current directory */
			pre[0] = 0; /* nuke the path or we'll get in trouble! */
			/* we could also use a return code to abort the whole
			 * thing if desired.
			 */
		}
	} else {
		dblock.ioVolIndex = -1;
		if(PBGetVInfo(&dblock, false) != noErr) {
			printf("No such directory! (%s)\n", pre);
			dblock.ioVRefNum = 0; /* force back to current directory */
			pre[0] = 0; /* nuke the path or we'll get in trouble! */
			/* we could also use a return code to abort the whole
			 * thing if desired.
			 */	
		}
	}
	
	Paw = 0;
	fp = &(pblock.ioFlFndrInfo);
	pblock.ioCompletion = 0;
	pblock.ioVRefNum = dblock.ioVRefNum;	/* use new directory number */
	pblock.ioFVersNum = 0;
}

/* Return JUST THE FILENAME COMPONENT of the next phrase file we find. */
char *
nextphr()
{
	static char fname[36];
	char *p, *strrchr();

    retry:
	Paw++;

	/* this is a little complicated... */
	/* we go through the whole directory in sequence */
	pblock.ioNamePtr = &dummystr;
	pblock.ioFDirIndex = Paw;
	if(PBGetFInfo(&pblock, false) != noErr) {
		/* no such file - we hit the end of the directory */
		return(NULL);
	}

	/* OK - we have some file info */
	p2cstr(pblock.ioNamePtr); /* convert from Pascal to C format */
	/* NOTE - '' rather than "" is correct! */
	if(fp->fdType != 'TEXT') {
		goto retry; /* not one of ours */
	}
	/* make it available as a static string */
	strncpy(fname, pblock.ioNamePtr, 35); /* the file name */
	fname[35] = 0; /* insist on a null - really can't happen :-) */
	return(fname);
}
closephr()
{
}

/* getmousepos - get currect row and column of mouse */
getmousepos(amr,amc)
int *amr;
int *amc;
{
	*amr = -1;
	*amc = -1;
}

/* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
statmouse()
{
	return(-1);
}

mouseon()
{
}

mouseoff()
{
}

/* Return when either a console key or mouse button is pressed. */
mouseorkey()
{
	return(getconsole());
}

char *
alloc(n)
	unsigned n;
{
	char *p;

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

windinit()
{
	Rows = 24;
	Cols = 80;
	
	return;
}

windgoto(r,c)
int r,c;
{
	printf("\033[%d;%dH",r+1,c+1);
}

windeeol()
{
	printf("\033[K");
}

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

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

windclear()
{
	printf("\033[H");
	printf("\033[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;
{
	putchar(c);
}

windrefresh()
{
}

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

windhigh()
{
}

windnorm()
{
}

char *
openls()
{
	/* this should be a whole lot fancier to take care of the path
	 * problems on the mac.  But glib currently has no path
	 * variables.  The current directory (just ":") will do for now... SAF
	 */
	openphr(":");
	return("");
}

char *
nextls()
{
	return(nextphr());
}

closels()
{
}
