/*  compiler directives to fetch the necessary header files */
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#include <devices/serial.h>
#include <stdio.h>
#include <ctype.h>
#include <libraries/dos.h>

extern struct Menu menu[];
extern struct IntuiText FileText[];
extern int fd;

#define INTUITION_REV 1
#define GRAPHICS_REV  1
#define RBUF 10240

/*   Intuition always wants to see these declarations */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

/* my window structure */
struct NewWindow NewWindow = {
   0,
   1,
   640,
   199,
   0,
   1,
   CLOSEWINDOW | RAWKEY | MENUPICK,
   WINDOWCLOSE | SMART_REFRESH | ACTIVATE
   | REPORTMOUSE | BORDERLESS | WINDOWDEPTH,
   NULL,
   NULL,
   "Aterm 2.2",
   NULL,
   NULL,
   100, 35,
   640,200,
   WBENCHSCREEN,
};


/* my window structure */
struct NewWindow New2Window = {
   1,
   1,
   639,
   199,
   0,
   1,
   CLOSEWINDOW | RAWKEY | MENUPICK,
   WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDRAG
   | REPORTMOUSE | WINDOWDEPTH | WINDOWSIZING,
   NULL,
   NULL,
   "Aterm 2.2",
   NULL,
   NULL,
   100, 35,
   640,200,
   WBENCHSCREEN,
};

struct Window *mywindow;             /* ptr to applications window */
struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */

/* bunches of gadget stuff */
struct IntuiText req_str = {2,2,JAM1, 10 , 10, NULL,
  (UBYTE *) "Save PhoneBook/Macro Keys", NULL};

struct IntuiText yes_str = {2,2,JAM1, 3, 3, NULL,
  (UBYTE *) " Yes ", NULL };
 
struct IntuiText no_str = {2,2,JAM1, 3, 3, NULL,
  (UBYTE *) " No ", NULL };

/* flags */
int ctextf = TRUE;
int crlf = TRUE;
int changed = FALSE;
int pchanged = FALSE;
int xstrip = TRUE;

/* macro keys and phone things */
char macro[10][82];
char pname[10][82];
char phone[10][82];

/* declarations for the serial stuff */
struct IOExtSer *Read_Request;
struct Port *Read_Port;
char rs_in[2];
struct IOExtSer *Write_Request;
struct Port *Write_Port;
char rs_out[2];


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

main()
{
ULONG class;
USHORT code,menunum,itemnum;
int KeepGoing,capture,send,duplex,i;
char c,name[32],ct;
FILE *tranr,*trans;
int rec,xoffed,sflags,freset;

IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
   {
   merrp("Can't open intuition\n");
   exit(22);
   }

GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
   {
   merrp("Can't open graphics library\n");
   exit(22);
   }

if((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
   {
   merrp("Can't open window\n");
   exit(22);
   }

if (!InitConsole(mywindow))
   {
   merrp("Can't open console device");
   goto error1;
   }
   
emits("\23312y");    /* new top margin */
SetAPen(mywindow->RPort,1);
Move(mywindow->RPort,28,8);
Draw(mywindow->RPort,588,8); /* make it look nice */
Move(mywindow->RPort,0,9);
Draw(mywindow->RPort,640,9); /* make it look nice */

   if ((trans=fopen("Macros","r")) != 0)
      {
      for (i=0; i<10; i++)
          fgets(macro[i], 82,trans);
      fclose(trans);
      }
   else
      {
      for (i=0; i<10; i++)
          strcpy(macro[i],"\n");
      }

   if ((trans=fopen("PhoneBook","r")) != 0)
      {
      for (i=0; i<10; i++)
          {
          fgets(pname[i], 82,trans);
          fgets(phone[i], 82,trans);
          }
      fclose(trans);
      }
   else
      {
      for (i=0; i<10; i++)
          {
          strcpy(pname[i],"\n");
          strcpy(phone[i],"\n");
          }
      }

Read_Port = CreatePort("Read_RS",0);    
Read_Request = (struct IOExtSer *)CreateExtIO(Read_Port,sizeof(struct IOExtSer));
Read_Request->io_SerFlags = SERF_SHARED;
if(OpenDevice(SERIALNAME,0,Read_Request,0))
   {
   merrp("Cant open Read device\n");
   goto error2;
   }
Read_Request->IOSer.io_Command = CMD_READ;
Read_Request->IOSer.io_Length = 1;
Read_Request->IOSer.io_Data = (APTR) &rs_in[0];

Write_Port = CreatePort("Write_RS",0);
Write_Request = (struct IOExtSer *)CreateExtIO(Write_Port,sizeof(struct IOExtSer));
Write_Request->io_SerFlags = SERF_SHARED;
if(OpenDevice(SERIALNAME,0,Write_Request,0))
   {
   merrp("Cant open Write device\n");
   goto error3;
   }
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length = 1;
Write_Request->IOSer.io_Data = (APTR) &rs_out[0];

Read_Request->io_Baud = 300;
Read_Request->io_ReadLen = 8;
Read_Request->io_WriteLen = 8;
Read_Request->io_StopBits = 1;
Read_Request->io_RBufLen = RBUF;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;

InitFileItems();
InitRSItems();
InitOptItems();
InitMenu();
initmgad();
initphonegad();

SetMenuStrip(mywindow,&menu[0]);

KeepGoing = TRUE;
capture = FALSE;
send = FALSE;
xoffed = FALSE;
freset = FALSE;
rec = 0;
duplex = 0;
emit(12);
emits("\nAterm 2.2\n");
emits("Copyright 1986 by Michael Mounier\n");
emits("This program may be freely distributed\n");
emits("Use the HELP key to see the macro key definitions\n\n");

BeginIO(Read_Request);

while(KeepGoing)
     {
     if (CheckIO(Read_Request))
       {
       GetMsg(Read_Port);
       c = rs_in[0] & 0x7f;
       if(freset)
         {
         Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
         Read_Request->io_SerFlags = sflags;
         DoIO(Read_Request);
         freset = FALSE;
         }
       Read_Request->IOSer.io_Command = CMD_READ;
       BeginIO(Read_Request);
       if (duplex == 2)
          sendcar(c);
       emit(c);
       if (capture)
          if (c > 31 && c < 127 || c == 13 || c == '\t')
             if (c == 13)
                putc(10, tranr);
             else
                putc(c , tranr);
       }

     while(NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort))
       {
       class = NewMessage->Class;
       code = NewMessage->Code;
       ReplyMsg( NewMessage );
       switch(class)
         {
         case CLOSEWINDOW:
           /*   User is ready to quit, so indicate
           *   that execution should terminate
           *   with next iteration of the loop.
           */
           KeepGoing = FALSE;
         break;

         case RAWKEY:
           /*  User has touched the keyboard */
           switch( code )
             {
             case 95: /* help key */
               for (i = 0; i < 10; i++)
                 emits(macro[i]);
             break;
             default:
               if (code <= 89 && code >= 80) /* macro keys */
                 {
                 for (i = 0; macro[code-80][i+1] != 0; i++)
                   {
                   ct = macro[code-80][i];
                   if (ct == '|')
                     ct = 13;
                     sendchar(ct);
                     if ((duplex == 1) || (duplex == 2))
                        emit(ct);
                   }
                 break;
                 }
               c = toasc(code); /* get in into ascii */
               if (c != 0)
                 {
                 sendcar(c);
                 if ((duplex == 1) || (duplex == 2))
                    emit(c);
                 }
             break;
             }
         break;

         case MENUPICK:
           if ( code != MENUNULL )
             {
             menunum = MENUNUM( code );
             itemnum = ITEMNUM( code );
             switch( menunum )
               {
               case 0:
                 switch( itemnum )
                   {
                   case 0:
                   if (capture)
                     {
                     ClearMenuStrip( mywindow );
                     FileText[0].IText = (UBYTE *)"Ascii Capture";
                     SetMenuStrip(mywindow,&menu[0]);
                     capture=FALSE;
                     fclose(tranr);
                     emit(7);
                     }
                   else
                     {
                     ClearMenuStrip( mywindow );
                     if (filename(name))
                       if ((tranr=fopen(name,"w")) == 0)
                         {
                         capture=FALSE;
                         emit(7);
                         }
                       else
                         {
                         capture=TRUE;
                         FileText[0].IText = (UBYTE *)"Abort Capture";
                         }
                     SetMenuStrip(mywindow,&menu[0]);
                     }
                   break;
                   case 1:
                     if (send)
                       {
                       ClearMenuStrip( mywindow );
                       FileText[1].IText = (UBYTE *)"Ascii Send";
                       SetMenuStrip(mywindow,&menu[0]);
                       send=FALSE;
                       fclose(trans);
                       emit(7);
                       }
                     else
                       {
                       ClearMenuStrip(mywindow);
                       if (filename(name))
                         if ((trans=fopen(name,"r")) == 0)
                           {
                           send=FALSE;
                           emit(7);
                           }
                         else
                           {
                           send = TRUE;
                           FileText[1].IText = (UBYTE *)"Abort Send";
                           }
                         SetMenuStrip(mywindow,&menu[0]);
                       }
                   break;
                   case 2:
                     ClearMenuStrip(mywindow);
                     sabort();
                     Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
                     sflags = Read_Request->io_SerFlags;
                     Read_Request->io_SerFlags |= SERF_RAD_BOOGIE;
                     DoIO(Read_Request);
                     Read_Request->IOSer.io_Command = CMD_READ;
                     BeginIO(Read_Request);
                     if (filename(name))
                       if (XMODEM_Read_File(name))
                         {
                         emits("\nRecieved File\n");
                         emit(7);
                         }
                       else
                         {
                         close(fd);
                         emits("\nXmodem Receive Failed\n");
                         emit(7);
                         }
                     SetMenuStrip(mywindow,&menu[0]);
                     freset = TRUE;
                   break;
                   case 3:
                     ClearMenuStrip(mywindow);
                     sabort();
                     Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
                     sflags = Read_Request->io_SerFlags;
                     Read_Request->io_SerFlags |= SERF_RAD_BOOGIE;
                     DoIO(Read_Request);
                     Read_Request->IOSer.io_Command = CMD_READ;
                     BeginIO(Read_Request);
                     if (filename(name))
                       if (XMODEM_Send_File(name))
                          {
                          emits("\nSent File\n");
                          emit(7);
                          }
                        else
                          {
                          close(fd);
                          emits("\nXmodem Send Failed\n");
                          emit(7);
                          }
                     SetMenuStrip(mywindow,&menu[0]);
                     freset = TRUE;
                   break;
                   }
               break;

               case 1: /* rs232 */
                 sabort();
                 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;
                   case 5:
                     Read_Request->io_ReadLen = 7;
                     Read_Request->io_WriteLen = 7;
                   break;
                   case 6:
                     Read_Request->io_WriteLen = 8;
                     Read_Request->io_ReadLen = 8;
                   break;
                   case 7:
                     duplex = 0;
                   break;
                   case 8:
                     duplex = 1;
                   break;
                   case 9:
                     duplex = 2;
                    break;
                    case 10:
                      Read_Request->io_SerFlags |= SERF_PARTY_ODD | SERF_PARTY_ON;
                    break;
                    case 11:
                      Read_Request->io_SerFlags &= ~SERF_PARTY_ODD;
                      Read_Request->io_SerFlags |= SERF_PARTY_ON;
                    break;
                    case 12:
                      Read_Request->io_SerFlags &= ~SERF_PARTY_ON;
                    break;
                    }
                 Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
                 DoIO(Read_Request);
                 Read_Request->IOSer.io_Command = CMD_READ;
                 BeginIO(Read_Request);
                 break;

                 case 2: /* options menu */
                   switch( itemnum )
                     {
                     case 0:
                       ClearMenuStrip(mywindow);
                       changed = editmacro();
                       SetMenuStrip(mywindow,&menu[0]);
                     break;
                     case 1:
                       ClearMenuStrip(mywindow);
                       pchanged = dophone();
                       SetMenuStrip(mywindow,&menu[0]);
                     break;
                     case 2:
                       ctextf = TRUE;
                     break;
                     case 3:
                       ctextf = FALSE;
                     break;
                     case 4:
                       crlf = FALSE;
                     break;
                     case 5:
                       crlf = TRUE;
                     break;
                     case 6:
                       xstrip = TRUE;
                     break;
                     case 7:
                       xstrip = FALSE;
                     break;
                     case 8:
                       /* window 80 column */
                       ClearMenuStrip(mywindow);
                       CloseConsole(1);
                       CloseWindow(mywindow);
                       if((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
                         {
                         merrp("Can't open window\n");
                         goto error4;
                         }
                       if (!InitConsole(mywindow))
                         {
                         CloseWindow(mywindow);
                         merrp("Can't open console device");
                         goto error4;
                         }
                       SetMenuStrip(mywindow,&menu[0]);
                       emits("\23312y");
                       SetAPen(mywindow->RPort,1);
                       Move(mywindow->RPort,28,8);
                       Draw(mywindow->RPort,588,8);
                       Move(mywindow->RPort,0,9);
                       Draw(mywindow->RPort,640,9);
                     break;
                     case 9:
                       /* window 76 column */
                       ClearMenuStrip(mywindow);
                       CloseConsole(1);
                       CloseWindow(mywindow);
                       if((mywindow = (struct Window *)OpenWindow(&New2Window)) == NULL)
                         {
                         merrp("Can't open window\n");
                         goto error4;
                         }
                       if (!InitConsole(mywindow))
                         {
                         CloseWindow(mywindow);
                         merrp("Can't open console device\n");
                         goto error4;
                         }
                       SetMenuStrip(mywindow,&menu[0]);
                       break;
                     }
                 break;
                 } /* end of switch ( menunum ) */
             }    /*  end of if ( not null ) */
           }   /* end of switch (class) */
        }   /* end of while ( newmessage )*/
     if (send)
       {
       if ((c = getc(trans)) != EOF)
         {
         if (c == 10)
           {
           if (crlf)
             {
             sendcar(13);
             if (duplex == 1 || duplex == 2)
               emit(13);
             }
           else
             c = 13;
           }
           sendcar(c);
           if (duplex == 1 || duplex == 2)
             emit(c);
         }
       else
         {
         fclose(trans);
         send=FALSE;
         ClearMenuStrip( mywindow );
         FileText[1].IText = (UBYTE *)"Ascii Send";
         SetMenuStrip(mywindow,&menu[0]);
         emit(7);
         }
     }
   else
     if (KeepGoing)
     Wait((1 << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | ( 1 << mywindow->UserPort->mp_SigBit));

  }  /* end while ( keepgoing ) */

/*   It must be time to quit, so we have to clean
*   up and exit.
*/
if (send)
   fclose(trans);
if (capture)
   fclose(tranr);

if (changed || pchanged)
   if (!AutoRequest(0,&req_str,&yes_str,&no_str,0,0,300,60))
      changed = pchanged = FALSE;

if (changed)
   if ((trans=fopen("Macros","w")) != 0)
      {
      for (i=0; i<10; i++)
          fputs(macro[i], trans);
      fclose(trans);
      }
    
if (pchanged)
   if ((trans=fopen("PhoneBook","w")) != 0)
      {
      for (i=0; i<10; i++)
          {
          fputs(pname[i], trans);
          fputs(phone[i], trans);
          }
      fclose(trans);
      }

CloseConsole(1);
sabort();
CloseDevice(Read_Request);
error3:
DeletePort(Read_Port);
DeleteExtIO(Read_Request);
CloseDevice(Write_Request);
error2:
DeletePort(Write_Port);
DeleteExtIO(Write_Request);
ClearMenuStrip(mywindow);
error1:
CloseWindow(mywindow);
exit(0);

error4:
sabort();
CloseDevice(Read_Request);
DeletePort(Read_Port);
DeleteExtIO(Read_Request);
CloseDevice(Write_Request);
DeletePort(Write_Port);
DeleteExtIO(Write_Request);
exit(22);
} /* end of main */

/******************************************************************
*  routine to go to if a major error is encountered by the program
******************************************************************/
merrp(mstring)

char *mstring;
{
printf(mstring);
return(0);
}

/* routine to abort serial request */
sabort()
{
while (AbortIO(Read_Request) != 0)
  printf("");        /* I don't know why this is here but it works */
}

sendcar(c)
char c;
{
int sent = FALSE;

while (!sent)
{
rs_out[0] = c;
BeginIO(Write_Request);

Wait((1 << Write_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | ( 1 << mywindow->UserPort->mp_SigBit));

if (CheckIO(Write_Request)) /* non zero if i/o completed  */
  {
  GetMsg(Write_Port);
  sent = TRUE;
  }
else  /* our write must not be done but something happened */
  {
  while (AbortIO(Write_Request) != 0)
    printf("");
  Write_Request->IOSer.io_Command = SDCMD_QUERY;
  DoIO(Write_Request);
  if ((Write_Request->IOSer.io_Flags && (1 << 11)) != 0) /* xoffed */
    {
    printf("");
    Write_Request->IOSer.io_Command = CMD_START;
    DoIO(Write_Request);
    }
  Write_Request->IOSer.io_Command = CMD_WRITE;
  }
} /* end while !sent */
} /* end of function */
   
