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

#define INTUI_V36_NAMES_ONLY

#include <exec/exec.h>
#include <exec/libraries.h>
#include <intuition/intuition.h>
#include <graphics/rastport.h>
#include <libraries/commodities.h>
#include <dos/dos.h>
#include <workbench/startup.h>
#include <libraries/gadtools.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>

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

#include <string.h> /* <-------- Remove this later */

#include "stickit2.h"

#include "consts.h"
#include "structs.h"
#include "proto.h"

/* Set up the version string */

char *versionstring = VERSION_STRING;

struct IntuitionBase  *IntuitionBase = NULL;
struct Library *GfxBase = NULL;
struct Library *CxBase = NULL;
struct Library *IconBase = NULL;
struct Library *DiskfontBase = NULL;
struct Library *UtilityBase = NULL;
struct Library *AslBase = NULL;
struct Library *IFFParseBase = NULL;
struct Library *GadToolsBase = NULL;

struct Library *ConsoleDevice = NULL; 	/* <--- For cursor keys !!! */
struct IOStdReq ioreq; 			/* <--- For cursor keys !!! */

prj_p prj = NULL;

BOOL fromwb = FALSE;

long _stack_fudge = 10000;		/* Let's have a decent stack */

/* Started from Workbench ? */

int wbmain(struct WBStartup *wbmsg)
{
	/* Show that we started from workbench */

	fromwb = TRUE;

	/* Make it look like an SAS call */

	main(0,(char **)wbmsg);

	return(0);
}

int main(int argc, char **argv)
{
	int l;

	/***   Open Libraries   ***/

	if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary
						("intuition.library",OS_VER)))
		cleanup();

	if (!(GfxBase = OpenLibrary("graphics.library",OS_VER)))
		error("Can't open v37+ of graphics library",ERR_FATAL,
__LINE__,__FILE__);

	if (!(CxBase = OpenLibrary("commodities.library",OS_VER)))
		error("Can't open v37+ of commodities library",ERR_FATAL,
__LINE__,__FILE__);

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

	if (!(DiskfontBase = OpenLibrary("diskfont.library",36)))
		error("Can't open v36+ of diskfont library",ERR_FATAL,
__LINE__,__FILE__);

	if (!(UtilityBase = OpenLibrary("utility.library",OS_VER)))
		error("Can't open v37+ of utility library",ERR_FATAL,
__LINE__,__FILE__);

	if (!(AslBase = OpenLibrary("asl.library",OS_VER)))
		error("Can't open v37+ of asl library",ERR_FATAL,
__LINE__,__FILE__);

	if (!(IFFParseBase = OpenLibrary("iffparse.library",OS_VER)))
		error("Can't open v37+ of iffparse library",ERR_FATAL,
__LINE__,__FILE__);

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

	/***   Open devices   ***/

	if (!(OpenDevice("console.device",-1,(struct IORequest *)&ioreq,0)))
		ConsoleDevice = (struct Library *)ioreq.io_Device;
	else
		error("Can't open console device",ERR_FATAL,__LINE__,__FILE__);
 
	/***   Allocate main project structure ***/

	prj = (prj_p)malloc(sizeof(struct project));

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

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

	startup(argc,argv);

	/* Set up program as a commodity */

	commod_startup();

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

	/* Startup delay to stop disk thrashing */

	Delay(prj->prefs.delay * 50);

	/* Read notefile */

	file_readnotes();

	/* If we haven't read in any notes and the user wants to quit */

	if ((prj->prefs.emptyquit) && (next_free_note() == 0))
		cleanup();

	/* Open all the notes */

	for (l = NO_NOTES -1; l >= 0; l--) {
		if (prj->notes[l]) {
			note_open(prj->notes[l]);
			note_refresh(prj->notes[l]);
		}
	}

	/* If user wants the Cx window */

	if (prj->prefs.cx_popup)
		openwindowcommod();

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

	events_mainloop();

	/**********************************************************************/

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

	cleanup();

	return(0);
}

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

void cleanup()
{
	CxMsg *cxmsg;

	int l;

	if (prj) {
		/* Close the commodities window */

		closewindowcommod();

		/* Close all notes */

		for (l = 0; l < NO_NOTES; l++) {
			if (prj->notes[l])
				note_close(prj->notes[l],TRUE);
		}

		/* Remove the commodities broker and all attached objects */

		if (prj->broker)
			DeleteCxObjAll(prj->broker);

		/* Remove messages from broker port */

		if (prj->broker_msg_port) {
			while(cxmsg = (CxMsg *)GetMsg(prj->broker_msg_port))
				ReplyMsg((struct Message *)cxmsg);
		}

		if (prj->broker_msg_port)
			DeleteMsgPort(prj->broker_msg_port);

		if (prj->main_msg_port)
			DeleteMsgPort(prj->main_msg_port);

		/* If font opened */

		if (prj->prefs.font)
			CloseFont(prj->prefs.font);

		/* Last of all, deallocate project structure */

		free((void *)prj);
	}

	/* Close devices */

	if (ConsoleDevice)
		CloseDevice((struct IORequest *)&ioreq);

	/* Close libraries */

	if (GadToolsBase)
		CloseLibrary(GadToolsBase);

	if (IFFParseBase)
		CloseLibrary(IFFParseBase);

	if (AslBase)
		CloseLibrary(AslBase);

	if (UtilityBase)
		CloseLibrary(UtilityBase);

	if (DiskfontBase)
		CloseLibrary(DiskfontBase);

	if (IconBase)
		CloseLibrary(IconBase);

	if (CxBase)
		CloseLibrary(CxBase);

	if (GfxBase)
		CloseLibrary(GfxBase);

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

	exit(0);
}

