/*  contains I/O information for use with the Amiga */

#include <libraries/arpbase.h>
#include <arpfunctions.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <exec/exec.h>
#include <exec/io.h>
#include <exec/ports.h>
#include <exec/types.h>
#include <clib/macros.h>
#include <ctype.h>
/* This is out for testing */
/* #define EOF    -1 */
#define    BACKSPACE 0x8

void myexit();
char *mygets();

extern char *code;
extern short *arga;
extern short *argb;

static struct IOStdReq conrequest;
struct Window *unixwindow;
/* window of operations */
static struct NewWindow NewWindow = {
   0, 1, 640, 199, -1, -1,
   CLOSEWINDOW | VANILLAKEY,
   WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | ACTIVATE | WINDOWSIZING
       | SMART_REFRESH | NOCAREREFRESH | RMBTRAP,
   NULL,
   NULL,
   (UBYTE *)"Amiga CoreWars 1.04d -- By David Wright 08/23/89",
   NULL,
   NULL,
   60,
   20,
   -1,
   -1,
   WBENCHSCREEN
};
   
/* Initialize the window so we can read and write to it */
void mysetup()
{
   /* If we haven't already initialized, then do so now */
   if (unixwindow == NULL)
   {
       /* Open up the window on the Workbench screen */
       if ((unixwindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
       {
           puts("The damn window won't open!!");
           exit(3);
       }
           
       /* And attach a console.device to it for output */
       conrequest.io_Data = (APTR)unixwindow;
       conrequest.io_Length = sizeof(*unixwindow);
       if(OpenDevice("console.device",0L,(struct IORequest *)&conrequest,0))
       {
           puts("You're console.device won't open.");
           myexit(6);
       }
   }
   return;
}

int mygetc() /* read a character from our special window (wait if no event) */
{
   register int c;
   struct IntuiMessage *Message;
   
   if(unixwindow == NULL)
       mysetup();  /* make sure we are initialized */
       
   /* wait until something happens */
   while((Message = (struct IntuiMessage *)GetMsg(unixwindow->UserPort)) == NULL)
       Wait(1L<<unixwindow->UserPort->mp_SigBit);

   switch(Message->Class)
   {
       case CLOSEWINDOW:
           c = EOF;
           break;
           
       case VANILLAKEY:
           if((c = Message->Code)== 0x1c)  /* CTRL - \ */
               c = EOF;
           else if (c == 0x03)     /* CTRL - C */
               c = EOF;
           else if (c == 0x1B)     /* ESC key */
               c = EOF;
           else if(c == 0x0d)      /* carriage return */
               c = '\n';
           break;      /* just a key, nothing special */
           
       default:
           c = EOF;
           break;
   }
   ReplyMsg((struct Message *)Message);
   if (EOF==c)
   {
       myexit(0);
   }
   return(c);
}


int mygetchar() /* read a character from our special window (don't wait if no event) */
{
   register int c;
   struct IntuiMessage *Message;
   
   if(unixwindow == NULL)
       mysetup();  /* make sure we are initialized */
       
   while((Message = (struct IntuiMessage *)GetMsg(unixwindow->UserPort)) == NULL)
       return(NULL);

   switch(Message->Class)
   {
       case CLOSEWINDOW:
           c = EOF;
           break;
           
       case VANILLAKEY:
           if((c = Message->Code)== 0x1c)  /* CTRL - \ */
               c = EOF;
           else if (c == 0x03)     /* CTRL - C */
               c = EOF;
           else if (c == 0x1B)     /* ESC key */
               c = EOF;
           else if(c == 0x0d)      /* carriage return */
               c = '\n';
           else if(c == 0x13 || c == ' ')  /* Pause on CTRL-S or SPACE */
               while(!((c = mygetc()) == 0x11 || (c == ' ')))
                   ;   /* CTRL-Q or SPACE to restart */
           break;
           
       default:
           c = EOF;
           break;
   }
   ReplyMsg((struct Message *)Message);
   if (EOF==c)
   {
       myexit(0);
   }
   return(c);
}

void   myputc(c)
char c;
{
   
   if(unixwindow == NULL)
       mysetup();  /* make sure we are initialized */

   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)&c;
   conrequest.io_Length = 1;
   /* send write request to console.device */
   DoIO((struct IORequest *)&conrequest);
}

void myputs(str)   /* write a string to our window */
char *str;
{
   if(unixwindow == NULL)
       mysetup();  /* make sure we are initialized */
   
   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)str;
   conrequest.io_Length = strlen(str);
   DoIO((struct IORequest *)&conrequest);
}  

/* write a formatted string to our window */
void myprintf(str, v1, v2, v3, v4, v5, v6, v7, v8, v9)
char *str;
long v1, v2, v3, v4, v5, v6, v7, v8, v9;
{
   char buff[256];
   
   if(unixwindow == NULL)
       mysetup();  /* make sure we are initialized */

   conrequest.io_Length = sprintf(buff,str,v1,v2,v3,v4,v5,v6,v7,v8,v9);
   conrequest.io_Command = CMD_WRITE;
   conrequest.io_Data = (APTR)buff;
   DoIO((struct IORequest *)&conrequest);
}

char   *mygets(buffer, length)
char   buffer[];
int    length;
{
   int count;
   for (count = 0; count < length; count++)
   {
       do
       {
           buffer[count] = (char)mygetc();
           if (buffer[count] == EOF)
               return(NULL);
       }
       while (!isascii(buffer[count])); /* skip over garbage characters */
       myputc(buffer[count]);

       if ('\n' == buffer[count])
       {
           buffer[count] = '\0';
           return(&buffer[0]);
       }

       /* could add better line editing/stripping here */
       if (BACKSPACE == buffer[count]) /* allow for backspace deleting */
           count = count - 2;
   }
}


/* close up everything and leave the program */
void myexit(code)
int code;
{
   if(unixwindow != NULL)
   {
       /* shut down in the opposite order we came up */
       free(code);
       free(arga);
       free(argb);
       CloseDevice((struct IORequest *)&conrequest);
       CloseWindow(unixwindow);
       unixwindow = NULL;
   }
   exit(code);
}
