/*********************************************
 **************    main.c   ******************
 *********************************************/

#define INTUI_V36_NAMES_ONLY

#include <exec/exec.h>
#include <workbench/startup.h>
#include <graphics/gfxbase.h>
#include <graphics/displayinfo.h>
#include <intuition/screens.h>
#include <libraries/amigaguide.h>
#include <workbench/workbench.h>
#include <devices/serial.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/alib_protos.h>
#include <clib/amigaguide_protos.h>

#include <stdio.h>
#include <stdlib.h>

#include "windows.h"

#include "consts.h"
#include "structs.h"
#include "protos.h"

/* Set up the version string */

char *versionstring="$VER:"VERSION_SHORTNAME" "VERSION_NUMBER" "VERSION_NUMDATE;

struct Library *IntuitionBase = NULL;
struct Library *IconBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *AslBase = NULL;
struct Library *CxBase = NULL;
struct Library *WorkbenchBase = NULL;

prj_p prj = NULL;

int main(int argc, char **argv)
{
	struct IntuiMessage *imsg;
	struct IntuiMessage curr_imsg;
	struct Message *msg;

	ULONG signal_main;
	ULONG signal_serial;

	ULONG signals_returned;

	BOOL done = FALSE;

	/***   Open Libraries   ***/

	if (!(IntuitionBase = OpenLibrary("intuition.library",VERSION_OS)))
		cleanup();

	if (!(IconBase = OpenLibrary("icon.library",VERSION_OS)))
		error("Can't open v37+ of the icon library",ERROR_FATAL,
__LINE__,__FILE__);

	if (!(GadToolsBase = OpenLibrary("gadtools.library",VERSION_OS)))
		error("Can't open v37+ of the gadtools library",ERROR_FATAL,
__LINE__,__FILE__);

	/* Try and open version 38 of the ASL library first. */

	if (!(AslBase = OpenLibrary("asl.library",VERSION_OS)))
		error("Can't open v37+ of the ASL library",ERROR_FATAL,
__LINE__,__FILE__);

	if (!(WorkbenchBase = OpenLibrary("workbench.library",VERSION_OS)))
		error("Can't open v37+ of the Workbench library",ERROR_FATAL,
__LINE__,__FILE__);

	/***   Allocate main project structure ***/

	prj = (prj_p)AllocMem(sizeof(struct project),MEMF_CLEAR);

	if (!prj)
		error("Can't allocate main project structure",ERROR_FATAL,
__LINE__,__FILE__);

	/***   Set up defaults etc...   ***************************************/

	/* Set up project structure and read tooltypes */

    	startup(argc,argv);

	/***   Main program   *************************************************/

	/* Open main window */

	if (OpenWindowmainwin())
		error("Can't open main window",ERROR_FATAL,__LINE__,__FILE__);

	/***   Main events loop   *********************************************/

	/* Construct the signals */

	signal_main = 1L << mainwin->UserPort->mp_SigBit;
	signal_serial = 1L << prj->serial_msg_port->mp_SigBit;

	while (!done) {

		/* Wait for a message from the correct ports */

		signals_returned = Wait(signal_main | signal_serial);

		/* Window message */

		if (signals_returned & signal_main) {
			/* Process message */

			while (imsg = (struct IntuiMessage *)GT_GetIMsg(
mainwin->UserPort)) {
				CopyMem(imsg,&curr_imsg,
sizeof(struct IntuiMessage));

				GT_ReplyIMsg((struct IntuiMessage *)imsg);

				done = win_idcmphandler(&curr_imsg);
			}
		}

		/* Serial message */

		if (signals_returned & signal_main) {
			/* Throw away serial stuff here */

			while (msg = GetMsg(prj->serial_msg_port))
				ReplyMsg(msg);
		}
	}

	/***   Exit and cleanup   *********************************************/

	cleanup();

	return(0);
}

/*
Function : void cleanup()
Purpose : Deallocates all memory, closes all libraries etc...
*/

void cleanup()
{
	/* Close window */

	CloseWindowmainwin();

	if (prj) {
		/* Closedown serial device */

		if (prj->serial_open)
			CloseDevice((struct IORequest *)prj->serialio);

		if (prj->serialio)
			DeleteExtIO((struct IORequest *)prj->serialio);

		/* Remove serial message port */

		if (prj->serial_msg_port)
			DeletePort(prj->serial_msg_port);

		/* Last of all, deallocate project structure */

		FreeMem((void *)prj,sizeof(struct project));
	}

	if (WorkbenchBase)
		CloseLibrary((struct Library *)WorkbenchBase);

	if (AslBase)
		CloseLibrary((struct Library *)AslBase);

	if (GadToolsBase)
		CloseLibrary((struct Library *)GadToolsBase);

	if (IconBase)
		CloseLibrary((struct Library *)IconBase);

	if (IntuitionBase)
		CloseLibrary((struct Library *)IntuitionBase);

	exit(0);
}

