/************************************************
 **************    general.c   ******************
 ************************************************/

#define INTUI_V36_NAMES_ONLY

#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <workbench/startup.h>
#include <libraries/gadtools.h>
#include <graphics/gfxbase.h>
#include <devices/serial.h>

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

#include <string.h>

#include "windows.h"

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

extern prj_p prj;

/* Wait pointer */

#ifdef _DCC
__chip UWORD WaitPointer[] = {
#else
UWORD __chip WaitPointer[] = {
#endif
	0x0000, 0x0000,     /* reserved, must be NULL */

	0x0400, 0x07C0,
	0x0000, 0x07C0,
	0x0100, 0x0380,
	0x0000, 0x07E0,
	0x07C0, 0x1FF8,
	0x1FF0, 0x3FEC,
	0x3FF8, 0x7FDE,
	0x3FF8, 0x7FBE,
	0x7FFC, 0xFF7F,
	0x7EFC, 0xFFFF,
	0x7FFC, 0xFFFF,
	0x3FF8, 0x7FFE,
	0x3FF8, 0x7FFE,
	0x1FF0, 0x3FFC,
	0x07C0, 0x1FF8,
	0x0000, 0x07E0,

	0x0000, 0x0000,     /* reserved, must be NULL */
	};


/*
Function : void startup(int argc,char **argv)
Purpose : Sets up the program before start. Reads tooltypes from command line
	or icon.
*/

void startup(int argc,char **argv)
{
	WORD l;

	/* NULL pointers first */

	prj->serial_msg_port = NULL;
	prj->serialio = NULL;
	prj->serial_open = FALSE;

	for (l = 0; l < MAX_LISTVIEW_ENTRIES; l++)
		prj->listviewarray[l] = NULL;

	NewList(&prj->listviewlist);

	prj->zpath[0] = '\0';
	prj->zpathdepth = -1;

	prj->path_binary_get[0] = '\0';
	prj->path_binary_put[0] = '\0';

	prj->blocked = FALSE;

	/* Create the serial message port */

	prj->serial_msg_port = CreatePort(NULL,NULL);

	if (!prj->serial_msg_port)
		error("Can't create serial message port",ERROR_FATAL,
__LINE__,__FILE__);

	/* Set up the serial device */

	prj->serialio = (struct IOExtSer *)CreateExtIO(
prj->serial_msg_port,sizeof(struct IOExtSer));

	if (!prj->serialio)
		error("Can't set up serial device",ERROR_FATAL,__LINE__,
__FILE__);

	if (OpenDevice(SERIALNAME,0,(struct IORequest *)prj->serialio,NULL))
		error("Can't open serial device",ERROR_FATAL,__LINE__,
__FILE__);

	prj->serial_open = TRUE;

}


/*
Function : void error(const char *msg,error_e err_no,int line,const char *file);
Purpose : Pops up a requester informing user of an error. If err_no ==
	ERROR_WARN, a requester is displayed informing the user of the error.
	If err_no == ERROR_FATAL, the function calls cleanup() and the program
	will exit. err_no == ERROR_INTERNAL is like ERROR_FATAL, only the line
	and file of the error is also displayed. The user may split the error
	message into a terse and a verbose section with the use of the '|'
	character. The terse message has "More..." and "Continue" buttons.
*/

void error(const char *msg,error_e err_no,int line,const char *file)
{
	struct Window *window = NULL;

	struct EasyStruct easyreq_internal = {
		sizeof(struct EasyStruct),
		0,
		VERSION_SHORTNAME,
		NULL,
		"Quit"
	};

	struct EasyStruct easyreq_fatal = {
		sizeof(struct EasyStruct),
		0,
		VERSION_SHORTNAME,
		"FATAL ERROR :\n%s",
		"Quit"
	};

	struct EasyStruct easyreq_warn = {
		sizeof(struct EasyStruct),
		0,
		VERSION_SHORTNAME,
		NULL,
		"Continue"
	};
	
	struct EasyStruct easyreq_more = {
		sizeof(struct EasyStruct),
		0,
		VERSION_SHORTNAME,
		"%s",
		"More...|Continue"
	};

	struct EasyStruct easyreq_fatalmore = {
		sizeof(struct EasyStruct),
		0,
		VERSION_SHORTNAME,
		"%s",
		"More...|Quit"
	};

	BOOL unblock = TRUE;

	char reqtext[STRLEN_EASYREQ];

	char terse[STRLEN_ERRMSG];
	char *verbose = NULL;

	size_t terse_length;

	/* Don't unblock the main window after requester if it's */
	/* already blocked. */

	if (prj->blocked)
		unblock = FALSE;
	else
		win_block_set();

	/* Point the verbose pointer to the character after the '|' */

	verbose = strstr(msg,"|");

	if (verbose) {
		verbose++;

		/* Copy up to the '|' character into terse */

		terse_length = strcspn(msg,"|");
		strncpy(terse,msg,terse_length);
		terse[terse_length] = '\0';
	}

	/* If the main window is open, attatch requester to the open window. */

	if (mainwin)
		window = mainwin;

	switch (err_no) {
		case ERROR_WARNING:
			if (!verbose) {
				/* Create the text string */

				strncpy(reqtext,msg,STRLEN_EASYREQ);
	
				/* Connect the text to the requester */

				easyreq_warn.es_TextFormat = reqtext;

				EasyRequest(window,&easyreq_warn,NULL);
			}
			else {
				/* Create the text string */

				strncpy(reqtext,terse,STRLEN_EASYREQ);
	
				/* Connect the text to the requester */

				easyreq_more.es_TextFormat = reqtext;

				if(EasyRequest(window,&easyreq_more,NULL)) {
					/* Create the text string */

					strncpy(reqtext,verbose,STRLEN_EASYREQ);
	
					/* Connect the text to the requester */

					easyreq_warn.es_TextFormat = reqtext;

					EasyRequest(window,&easyreq_warn,NULL);
				}
			}
			break;
		case ERROR_FATAL:
			if (!verbose) {
				/* Create the text string */

				strncpy(reqtext,msg,STRLEN_EASYREQ);
	
				/* Connect the text to the requester */

				easyreq_fatal.es_TextFormat = reqtext;

				EasyRequest(window,&easyreq_fatal,NULL);
			}
			else {
				/* Create the text string */

				strncpy(reqtext,terse,STRLEN_EASYREQ);
	
				/* Connect the text to the requester */

				easyreq_fatalmore.es_TextFormat = reqtext;

				if(EasyRequest(window,&easyreq_fatalmore,NULL)){
					/* Create the text string */

					strncpy(reqtext,verbose,STRLEN_EASYREQ);
	
					/* Connect the text to the requester */

					easyreq_fatal.es_TextFormat = reqtext;

					EasyRequest(window,&easyreq_fatal,NULL);
				}
			}

			cleanup();
			break;
		case ERROR_INTERNAL:
			/* Create the text string */

			sprintf(reqtext,"INTERNAL ERROR :\n%s\n"
"Line %ld in file \"%s\"",msg,line,file);

			/* Connect the string to the requester */

			easyreq_internal.es_TextFormat = reqtext;

			EasyRequest(window,&easyreq_internal,NULL);

			cleanup();
			break;
		default:
			EasyRequest(window,&easyreq_internal,NULL,"Unknown error  "
"message",__LINE__,__FILE__);
			cleanup();
			break;
	}

	/* Only unblock window if req code blocked it */

	if (unblock)
		win_block_clear();
}
