/************************************************************************
 *  vt100 terminal emulator with xmodem transfer capability
 *
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *  use <esc> to abort xmodem or kermit transfers
 *
 *  written by Michael Mounier
 *  new version by Dave Wecker
 ************************************************************************/

/*  all includes defines and globals */
#define MODULE_MAIN 1
#include "vt100.h"

/******************************************************/
/*                   Main Program                     */
/*                                                    */
/*      This is the main body of the program.         */
/******************************************************/

char lookahead[2048];
FILE *tranr = NULL;
FILE *trans = NULL;
int capture,send;
char name[256];

main(argc,argv)
int	argc;
char	**argv;
    {
    ULONG class;
    unsigned int code,menunum,itemnum;
    int KeepGoing,i,j,la,dola,xonflg,rxonflg,actual;
    char c;

    InitDefaults(argc,argv);
    InitDevs();
    InitFileItems();
    InitRSItems();
    InitXFItems();
    InitScriptItems();
    InitMenu();
    SetMenuStrip(mywindow,&menu[0]);

    KeepGoing =	    TRUE;
    capture   =	    FALSE;
    send      =	    FALSE;
    xonflg    =	    FALSE;
    rxonflg   =	    FALSE;
    maxcol    =	    MAXX / 8;
    la	      =	    0;
    x	      =	    MINX ; 
    y	      =	    MINY; 
    curmode   =	    0;
    script_on =     FALSE;
    script_wait=    TRUE;
    SetAPen(mywindow->RPort,1L);
    cursoron();
    cursoroff();    
    emit(12);
    BeginIO(Read_Request);

    while( KeepGoing )
	    {
	    /* wait for window message or serial port message */
	    cursoron();
	    if (script_wait)	/* if script ready dont wait here */
		Wait(
		 (1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
		 (1L << mywindow->UserPort->mp_SigBit) |
		 (1L << Script_Timer_Port->mp_SigBit));
	    cursoroff();
	    
	    /* do ascii file send */
	    if (send)
		{
		if ((c=getc(trans)) != EOF) {
		    if (c == '\n') c = '\r';
		    sendchar(c);
		    }
		else {
		    fclose(trans);
		    emits("\nFile Sent\n");
		    send=FALSE;
		    }
		}

	    /* see if there are any characters from the host */
	    if (CheckIO(Read_Request)) {
		WaitIO(Read_Request);
		c = rs_in[0] & 0x7F;
		doremote(c);
		if (script_on) chk_script(c);
	        if (capture && c != 10) {
	      	    if (c == 13) c = 10;
		    putc(c , tranr);
		    }
		Read_Request->IOSer.io_Command = SDCMD_QUERY;
		BeginIO(Read_Request);
		WaitIO(Read_Request);
		Read_Request->IOSer.io_Command = CMD_READ;
		actual = (int)Read_Request->IOSer.io_Actual;
		if (actual > 0) {
		    if (inesc   <  0 &&
			inctrl  <  0 &&
			a[alt]  == 0 &&
			capture == FALSE) dola = 1;
		    else dola = 0;
		    Read_Request->IOSer.io_Length =
			Read_Request->IOSer.io_Actual;
		    BeginIO(Read_Request);
		    WaitIO(Read_Request);
		    Read_Request->IOSer.io_Length = 1;

		    /* if too many use XON/XOFF */
		    if (p_xon && actual > 1536 && xonflg == FALSE) {
			sendchar(19);
			xonflg = TRUE;
			}
		    for (i = 0; i < actual; i++) {
			c=rs_in[i] & 0x7f;
			if (script_on) chk_script(c);

			/* handle host request for flow control */
			if (p_xon) {
			    if (rxonflg) {
				if (c == 17) {
				    rxonflg = FALSE;
				    }
				continue;
				}
			    else if (c == 19) {
				rxonflg = TRUE;
				continue;
				}
			    }
			if (dola == 1) {
			    if (c >= ' ' && c <= '~') lookahead[la++] = c;
			    else {
				if (la > 0) {
				    emitbatch(la,lookahead);
				    la = 0;
				    }
				doremote(c);
				dola = 0;
				}
			    }
			else {
			    doremote(c);
			    if (p_xon && xonflg == FALSE && i == 1023) {
				Read_Request->IOSer.io_Command = SDCMD_QUERY;
				BeginIO(Read_Request);
				WaitIO(Read_Request);
				Read_Request->IOSer.io_Command = CMD_READ;
				j = (int)Read_Request->IOSer.io_Actual;
				if (j > 1023) {
				    sendchar(19);
				    xonflg = TRUE;
				    }
				}
			    if (inesc   <  0 &&
				inctrl  <  0 &&
				a[alt]  == 0 &&
				capture == FALSE) dola = 1;
			    if (capture && c != 10) {
				if (c == 13) c = 10;
				putc(c , tranr);
				}
			    }
			}

		    /* dump anything left in the lookahead buffer */
		    if (la > 0) {
			emitbatch(la,lookahead);
			la = 0;
			}

		    /* tell host to resume transmission */
		    if (xonflg == TRUE) {
			sendchar(17);
			xonflg = FALSE;
			}
		    }

		BeginIO(Read_Request);

		/* wait for host to tell us to resume */
		while (rxonflg == TRUE) {
		    WaitIO(Read_Request);
		    if ((rs_in[0] & 0x7F) == 17) rxonflg = FALSE;
		    BeginIO(Read_Request);
		    }
		}

	    while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
		{
		class = NewMessage->Class;
		code = NewMessage->Code;
		ReplyMsg( NewMessage );
		switch( class )
		    {
		    case CLOSEWINDOW:
		    KeepGoing = FALSE;
		    break;

		    case RAWKEY:
		    c = toasc(code,0);
		    break;

		    case NEWSIZE:
		    emit(12);
		    break;

		    case MENUPICK:
		    if ( code != MENUNULL )
			{
			menunum = MENUNUM( code );
			itemnum = ITEMNUM( code );
			switch( menunum )
			    {
			    case 0:
			    switch( itemnum )
				{
				case 0:
				do_capture(NULL);
				break;

				case 1:
				do_send(NULL);
				break;

				case 2:
				emits("\nXmodem Receive:");
				filename(name);
				multi_xfer(name,XMODEM_Read_File,0);
				break;

				case 3:
				emits("\nXmodem Send:");
				filename(name);
				multi_xfer(name,XMODEM_Send_File,1);
				break;

				case 4:
				server = TRUE;
				itemnum = 5;

				case 5:
				emits("\nKermit Receive local name:");
				filename(name);
				multi_xfer(name,dokreceive,0);
				break;

				case 6:
				server = TRUE;
				emits("\nKermit Send local name:");
				filename(name);
				multi_xfer(name,doksend,1);
				break;

				case 7:
				saybye();
				break;
				}
			    break;

			    case 1:
			    AbortIO(Read_Request);
			    switch( itemnum )
				{
				case 0:
				Read_Request->io_Baud = 300;
				break;
				case 1:
				Read_Request->io_Baud = 1200;
				break;
				case 2:
				Read_Request->io_Baud = 2400;
				break;
				case 3:
				Read_Request->io_Baud = 4800;
				break;
				case 4:
				Read_Request->io_Baud = 9600;
				break;
				}
			    Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
			    DoIO(Read_Request);
			    Read_Request->IOSer.io_Command = CMD_READ;
			    BeginIO(Read_Request);
			    break;

			    case 2:
			    p_mode = itemnum;
			    break;

			    case 3:
			    if (!itemnum && !script_on) {
			    	emits("Script file name: ");
			    	filename(name);
			    	script_start(name);
			        }
			    if (itemnum && script_on) {
			    	exit_script();
			    	}
			    break;
			    
			    } /* end of switch ( menunum ) */
			}    /*  end of if ( not null ) */
		    }   /* end of switch (class) */
		}   /* end of while ( newmessage )*/

            if (!script_wait || 
                 (CheckIO(&Script_Timer) && script_wait == WAIT_TIMER)) 
               do_script_cmd(NEXTCOMMAND);

	    }  /* end while ( keepgoing ) */
		
    /*   It must be time to quit, so we have to clean
    *   up and exit.
    */

    CloseDevice(&Timer);
    DeletePort(Timer_Port);
    CloseDevice(&Script_Timer);
    DeletePort(Script_Timer_Port);
    CloseDevice(Read_Request);
    DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
    FreeMem(Read_Request,(long)sizeof(*Read_Request));
    CloseDevice(Write_Request);
    DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
    FreeMem(Write_Request,(long)sizeof(*Write_Request));
    ClearMenuStrip( mywindow );
    CloseWindow( mywindow );
    if (p_screen != 0) CloseScreen( myscreen );
    exit(FALSE);
    } /* end of main */


do_capture(file)
char *file;
{
    if (capture == TRUE)
        {
        capture=FALSE;
        fclose(tranr);
        emits("\nEnd File Capture\n");
        }
    else
        {
        if (file == NULL) {
            emits("\nAscii Capture:");
            filename(name);
	    } 
	else strcpy(name, file);
        if ((tranr=fopen(name,"w")) == 0)
  	    {
	    capture=FALSE;
	    emits("\nError Opening File\n");
	    return(FALSE);
	    }
	capture=TRUE;
        }
}

do_send(file)
char *file;
{
    if (send == TRUE)
	{ 
        send=FALSE;
        fclose(trans);
        emits("\nFile Send Cancelled\n");
        }
    else
        {
        if (file == NULL) {
            emits("\nAscii Send:");
            filename(name);
            }
	else strcpy(name, file);
        if ((trans=fopen(name,"r")) == 0)
   	    {
   	    send=FALSE;
	    emits("\nError Opening File\n");
	    return(FALSE);
	    }
	send=TRUE;
	}
}

