/********************************************************************
*   DrvErrors.c
*
*   Macintosh driver error message handlers.
*
*   Copyright (c) 1995-1997, Willows Software Inc.  All rights reserved.
*
********************************************************************/

#include <stdio.h>
#include <string.h>
#include <Dialogs.h>
#include <Errors.h>
#include <LowMem.h>

#include "DrvGlobals.h"
#include "DrvSystem.h"
#include "DrvErrors.h"
#include "Log.h"

/* External prototype */
extern void DrvUpdateCursor(BOOL inWindow);

static char *SysErr = "SystemError";
static char gErrorMsg[1024];			/* Make sure we have already allocated this memory */



/********************************************************************
*   DisplayAlert
*
*	Wraps the alert dialogs to use the resource file of the shared library.
********************************************************************/
static short DisplayAlert(short alertType, short alertID, ModalFilterUPP modalFilter)
{
short dItem;
short rfRefNum;

	/* Setup to use the shared libraries resources */
	rfRefNum = FSpOpenResFile(&gMyFileSpec, fsCurPerm);	
	UseResFile(rfRefNum);
	
	switch (alertType) {
	case CAUTIONALERT:
		dItem = CautionAlert(alertID, modalFilter);
		break;
	case NOTEALERT:
		dItem = NoteAlert(alertID, modalFilter);
		break;
	case STOPALERT:
		dItem = StopAlert(alertID, modalFilter);
		break;
	default:
		dItem = Alert(alertID, modalFilter);
		break;
	}

	/* Reset to the normal resource file */
	CloseResFile(rfRefNum);
	
	return(dItem);
}

/********************************************************************
*   AlertMsg.c
*
*	Puts up an alert box with the message.
********************************************************************/
short AlertMsg(char *msg, short kind)
{
	ParamText(C2PStr(msg),nil,nil,nil);

	DrvUpdateCursor(FALSE);

	return DisplayAlert(kind, SIMPLEALERT_ID, NULL);
	
}

/********************************************************************
*   ErrMsgCode.c
*
*	Puts up an alert box with the message and error code.
********************************************************************/
void ErrMsgCode(Str255 msg, short code)
{ 
Str31	codeStr;
Str31	memErrStr;
Str31	resErrStr;
short	disposition;
	
	NumToString(code, codeStr);

	NumToString(LMGetMemErr(), memErrStr);
	NumToString(LMGetResErr(), resErrStr);
	
	ParamText(msg, codeStr, memErrStr, resErrStr);

	DrvUpdateCursor(FALSE);

	disposition = DisplayAlert(CAUTIONALERT, COMPLEXALERT_ID, NULL);
	
	/* What does the user want to do? */
	switch(disposition)	{
	case	DEBUGGER:
		DropIntoDebugger(NULL);		break;
	case	EXITTOSHELL:
		DrvFatalExit(1);					break;
	case	KEEP_GOING:		
	default:										break;
	}
}


/********************************************************************
*   ErrMsg.c
*
*	Puts up an alert box with the message and no error code.
********************************************************************/
void ErrMsg(Str255 msg)
{
	ErrMsgCode(msg, 0);
}


/********************************************************************
*   SystemError
*
*
********************************************************************/
void SystemError(UINT action,DWORD errorcode,DWORD wParam,DWORD lParam)
{
int exitcode = -1;
char param1[256];
#ifndef DEBUGGERENABLED
	int dItem;
#endif
	
	switch(errorcode) {
		case SYSERR_CONNECT:
			logstr(LF_ERR,CONNECTSTR);
			sprintf(gErrorMsg, "%S", "TWIN Library connect error.");
			exitcode = -errorcode;
			break;

		case SYSERR_DISPLAY:
			sprintf(gErrorMsg, "%S", "TWIN Library cannot connect to server.");
			logstr(LF_ERR,"%s: Cannot connect to server %s\n",SysErr,lParam);
			exitcode = -errorcode;
			break;

		case SYSERR_SERVER:
			sprintf(gErrorMsg, "%S", "Fatal server I/O error.");
			logstr(LF_ERR,"%s: Fatal X I/O Error %x\n",SysErr,lParam);
			exitcode = -errorcode;
			break;

		case SYSERR_XIO:
			sprintf(gErrorMsg, "%S", "Fatal server I/O error.");
			logstr(LF_ERR,"%s: Fatal X I/O Error on %s\n",SysErr,lParam);
			exitcode = -errorcode;
			break;

		case SYSERR_MEMORY:
			strcpy(gErrorMsg, "Out of memory.  Try increasing the application memory size in the finder.");
			logstr(LF_ERR,"%s: Memory Allocation Failure %x %x\n",SysErr,wParam,lParam);
			exitcode = -errorcode;
			break;
		default:
			sprintf(gErrorMsg, "TWIN System error.  Action: %d", action);
			logstr(LF_ERR,"%s: %x %x %x %x\n",SysErr,action,errorcode,wParam,lParam);
			exitcode = -errorcode;
			break;
	}

	if (gLastHandle) {
		DisposeHandle(gLastHandle);		/* Free up the saved memory reserve */
		gLastHandle = NULL;
	}
	
#ifdef DEBUGGERENABLED
	sprintf(param1, "Tried to allocate %d bytes of memory.", lParam);
//	sprintf(param1, "wParam: %d  lParam: %d", wParam, lParam);
	strcat(gErrorMsg, param1);
	ErrMsgCode(C2PStr(gErrorMsg), errorcode);
#else
	sprintf(param1, "Tried to allocate %d bytes of memory.", lParam);
	ParamText(C2PStr(gErrorMsg), C2PStr(param1), NULL, NULL);
	dItem = DisplayAlert(STOPALERT, SIMPLEALERT_ID, NULL);	
	DrvFatalExit(1);
#endif	
}

