/* error.c: routines for printing warning, error and fatal error messages */
#include <Xm/Xm.h>
#include <Xm/MessageB.h>

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "error.h"
#include "initerror.h"
#include "boolean.h"

static Widget warningDialog, errorDialog;

static void ErrorOkCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
	Widget dialog = (Widget)client_data;

	XtUnmanageChild(dialog);
}

void InitError(Widget topLevel, Arg *args, int nrargs)
{
	Widget temp;

	warningDialog = XmCreateWarningDialog(topLevel, "warningDialog", args, nrargs);
	temp = XmMessageBoxGetChild(warningDialog, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(temp);
	temp = XmMessageBoxGetChild(warningDialog, XmDIALOG_CANCEL_BUTTON);
	XtUnmanageChild(temp);

	XtAddCallback(warningDialog, XmNokCallback, ErrorOkCallback, (XtPointer)warningDialog);

	errorDialog = XmCreateErrorDialog(topLevel, "warningDialog", args, nrargs);
	temp = XmMessageBoxGetChild(errorDialog, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(temp);
	temp = XmMessageBoxGetChild(errorDialog, XmDIALOG_CANCEL_BUTTON);
	XtUnmanageChild(temp);

	XtAddCallback(errorDialog, XmNokCallback, ErrorOkCallback, (XtPointer)errorDialog);
}

static int errorOccurred = FALSE;

void ErrorReset(void)
{
	errorOccurred = FALSE;
}

/* returns FALSE if there were errors so far */
int ErrorOccurred(void)
{
	return errorOccurred;
}

/* prints an error message, doesn't exit the program */
void Error(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[256];
	int n;

	n = 0;
	if (routine) sprintf(buf, "%s():%n", routine, &n);

	va_start(pvar, text);
	vsprintf(buf+n, text, pvar);
	va_end(pvar);

	XtVaSetValues(errorDialog,
		      XtVaTypedArg,
		         XmNmessageString, XmRString, buf, strlen(buf)+1,
		      NULL);

	XtManageChild(errorDialog);
	XFlush(XtDisplay(errorDialog));

	errorOccurred = TRUE;
}

/* prints a fatal error message and exits the program */
void Fatal(int errcode, char *routine, char *text, ...)
{
	va_list pvar;

	fprintf(stderr, "Fatal error");
	if (routine) fprintf(stderr, " (in subroutine %s)", routine);
	fprintf(stderr, ": ");

	va_start(pvar, text);
	vfprintf(stderr, text, pvar);
	va_end(pvar);

	if (errcode < 0) 
		fprintf(stderr, " (bug in the program)");

	fprintf(stderr, ".\n");
	fflush(stderr);
	exit(errcode); 

	errorOccurred = TRUE;
}

void Warning(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[256];
	int n;

	n = 0;
	if (routine) sprintf(buf, "%s():%n", routine, &n);

	va_start(pvar, text);
	vsprintf(buf+n, text, pvar);
	va_end(pvar);

	XtVaSetValues(warningDialog,
		      XtVaTypedArg,
		         XmNmessageString, XmRString, buf, strlen(buf)+1,
		      NULL);

	XtManageChild(warningDialog);
	XFlush(XtDisplay(warningDialog));
}
