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

/* most of the code is borrowed from some John Toebes source */


#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"
#include "functions.h"

#define EOF	-1
#define	BACKSPACE 0x8
#define GRAPHICS_REV	29L
#define INTUITION_REV	29L

void myexit();
char *mygets();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

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
	| SIZEBBOTTOM | SMART_REFRESH | NOCAREREFRESH,
	NULL, NULL,
	(UBYTE *)"Amiga CoreWars 1.01w -- Ported by Chad 'The_Walrus' Netzer  02/28/88",
/* The "w" indicates it's my (The_Walrus's) version.  You can adopt a similar scheme (with a different letter or symbol) */
	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 libraries we will need to use */
		if ((IntuitionBase = (struct IntuitionBase *)
			OpenLibrary("intuition.library",INTUITION_REV)) == NULL) {
			puts("Oh shit!  I can't open Intuition!!");
			_exit(1);
		}
		
		if ((GfxBase = (struct GfxBase *)
			OpenLibrary("graphics.library",GRAPHICS_REV)) == NULL) {
			puts("Oh crap!  I can't do any graphics!");
			_exit(2);
		}
			
		/* Open up the window on the Workbench screen */
		if ((unixwindow = (struct Window *)OpenWindow(&NewWindow)) == NULL) {
			puts("Fucken A!  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("By Gosh, 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 */
		CloseDevice((struct IORequest *)&conrequest);
		CloseWindow(unixwindow);
		CloseLibrary((struct Library *)GfxBase);
		CloseLibrary((struct Library *)IntuitionBase);
		unixwindow = NULL;
	}
	_exit(code);
}
