/*
 * 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);
}

