/*+++
 *  title:      MailCrashTrap.m
 *  abstract:   Implementation of MailCrashTrap class for PROJECT.
 *  author:     Tom Hageman <mailapp-utilities@basil.icce.rug.nl>
 *  created:    December 1998
 *  modified:   January 1999
 *  copyleft:
 *
 *		Copyright (C) 1998, 1999  Tom R. Hageman.
 *
 *	This is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This software is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this software; see the file COPYING.  If not, write to
 *	the Free Software Foundation, 59 Temple Place - Suite 330,
 *	Boston, MA 02111-1307, USA.
 *
 *  description:
 *      (see corresponding *.h file)
 *---*/

static const char * const RCSid = ((void)&RCSid,
	"@(#)MailCrashTrap.m,v 1.7 1999/01/10 17:28:47 tom Exp");
#define RCS_MailCrashTrap_ID

#import <appkit/appkit.h>
#import "MailCrashTrap.h"
#import "TRHCrashTrap.h"
#import "version.h"

// Localizables.
#define CRASH_ALERT	NXLocalizedStringFromTableInBundle(NULL, bundle, "CRASH_ALERT", "Crash Alert!", Error alert header)
#define CRASH_MESSAGE_FORMAT NXLocalizedStringFromTableInBundle(NULL, bundle, "CRASH_MESSAGE_FORMAT", "%s\n\nAn internal error has occurred.  Try to save work, then quit and restart Mail Ð or continue at your own risk.\n(see the console for details)", Crash alert message format; %s is replaced with actual message)
#define CRASH_CONTINUE_BUTTON NXLocalizedStringFromTableInBundle(NULL, bundle, "Continue", NULL, Crash alert default [continue] button)
#define CRASH_EXIT_BUTTON NXLocalizedStringFromTableInBundle(NULL, bundle, "Exit", NULL, Crash alert alternate [crash] button)

static const char *crash_alert;
static const char *crash_message_format;
static const char *crash_continue_button;
static const char *crash_exit_button;


/* Support function to transmogrify class of existing instance. */

static void changeClassOfInstanceTo(id instance, Class class)
{
   /* Don't try this at home, kids */
   instance->isa = class;
}


@implementation MailCrashTrap

static NXBundle *bundle;

+ finishLoading:(struct mach_header *)header
{
	[self poseAs:[self superclass]];
	changeClassOfInstanceTo(NXApp, self);
	bundle = [NXBundle bundleForClass:self];
	[self setupCrashTrap];
	return self;
}

+ (void)setupCrashTrap
{
	// Preload localizable strings, to improve robustness.
	crash_alert = CRASH_ALERT;
	crash_message_format = CRASH_MESSAGE_FORMAT;
	crash_continue_button = CRASH_CONTINUE_BUTTON;
	crash_exit_button = CRASH_EXIT_BUTTON;

	[TRHCrashTrap setup];
	[TRHCrashTrap setContinueAfterError:YES];
	[self logNote:"%s (version %s, %s) installed", PACKAGE, VERSION, VERSION_DATE];
}

/* This is to update CrashTrap's signal handlers _after_ -appDidInit: has finished.
   Since -appDidInit: installs its own signal handlers after it loads bundles,
   we'd lose out otherwise.
   Also setup self as CrashTrap delegate, so we can use our own alert panel. */

- (void)finishSetupCrashTrap
{
	[TRHCrashTrap resumeHandlingCrashes];
	[TRHCrashTrap setDelegate:self];
}

- initialCheck:sender
{
	[self finishSetupCrashTrap];
	return [super initialCheck:sender];
}


// CrashTrap delegate method.

- (BOOL)crashTrap:sender shouldContinueAfterError:(const char *)anErrorMessage
{
	return NXRunAlertPanel(crash_alert,
						   crash_message_format,
						   crash_continue_button,
						   crash_exit_button,
						   NULL,
						   anErrorMessage) == NX_ALERTDEFAULT;

	// XXX should preallocate this alert panel to be more crashproof.
}

@end // MailCrashTrap
