#import "Preferences.h"
#import "ArchieServer.h"
#import "InspectorManager.h"
#import "MOPathString.h"
#import "Object_Document.h"

#import <appkit/appkit.h>
#import <pfs.h>
#import <archie.h>

/* The string for the custom host browser entry */
#define CUSTOM_STRING "Custom Server"

/* The Prospero debugging level */
int pfs_debug = 2;

/* Sort enums */
enum {ByName, ByDate, NoSort};
/* Niceness level enums */
enum {LowNice = 0, MedNice = 10000, HighNice = 32765};
/* Notification sound default names */
static const char *soundNameDefaults[] = {"DirNotifySnd", "QueryNotifySnd",
	"FTPNotifySnd"
};

@implementation Preferences

/*\ ---------------------- Class Methods ---------------------- \*/
+ (const char *) notificationDefault:(int) type
{
const char *name = 0;

	if( type >= DirLoaded && type <= FTPTransfer )
		name = soundNameDefaults[type];
	return name;
}

/*\ ---------------------- Initialization Methods ---------------------- \*/
- init
{
	[super init];

	/* Load the current default values */
	[self loadDefaults];

	/* Allocate the inspector manager and assign the preferences groups */
	inspectorMgr = [[InspectorManager alloc] init];
	if( [inspectorMgr panel] == nil )
	{
		[self error: INTERNAL_SORRY method:_cmd key: PREF_PANEL_FAILED];
		return nil;
	}
	[inspectorMgr setDelegate: self];
	[inspectorMgr showRevertOK];

	/* Flag that all preferences panel views are out of sync with defaults */
	resetPrefPanel = ALL_PREFS_BITS;

	return self;
}

/*\ ---------------------- Display Methods ---------------------- \*/
- display
{
	[[inspectorMgr panel] orderFront: self];
	if( archieBoxID == nil )
	{	// Load all of the Nibs and setup the inspector manager
	NXStringTable *serverTable;
		generalPrefsGrp = [inspectorMgr addGroup: "General Prefs"];
		archiePrefsGrp = [inspectorMgr addGroup: "Archie Prefs"];
		queryPrefsGrp = [inspectorMgr addGroup: "Query Prefs"];
		ftpPrefsGrp = [inspectorMgr addGroup: "FTP Prefs"];
		/* Load the nib for the offscreen windows and add 
			the Box views to the inspector */
		[NXApp loadNibSection: "GeneralPrefs.nib" owner: self withNames: NO];
		if( generalBoxID == nil )
			return [self error: INTERNAL_ALERT method:_cmd
				key: "Failed to load GeneralPrefs.nib"];
		[inspectorMgr addInspector: generalBoxID title: "General Preferences"
			atLocation: 10 : 40 cached: YES
			cacheWindow: [generalBoxID window]];
		[NXApp loadNibSection: "ArchiePrefs.nib" owner: self withNames: YES];
		if( archieBoxID == nil )
			return [self error: INTERNAL_ALERT method:_cmd
				key: "Failed to load ArchiePrefs.nib"];
		// Initialize the ArchieServer class
		serverTable = NXGetNamedObject("ArchieServersTable", self);
		[ArchieServer initArchieServers: serverTable];
		[inspectorMgr addInspector: archieBoxID title: "Archie Preferences"
			atLocation: 10 : 40 cached: YES
			cacheWindow: [archieBoxID window]];
		[NXApp loadNibSection: "QueryPrefs.nib" owner: self withNames: NO];
		if( queryBoxID == nil )
			return [self error: INTERNAL_ALERT method:_cmd
				key: "Failed to load QueryPrefs.nib"];
		[inspectorMgr addInspector: queryBoxID title: "Query Preferences"
			atLocation: 10 : 40 cached: YES
			cacheWindow: [queryBoxID window]];
		[NXApp loadNibSection: "FTPPrefs.nib" owner: self withNames: NO];
		if( ftpBoxID == nil )
			return [self error: INTERNAL_ALERT method:_cmd
				key: "Failed to load FTPPrefs.nib"];
		[inspectorMgr addInspector: ftpBoxID title: "FTP Preferences"
			atLocation: 10 : 40 cached: YES
			cacheWindow: [ftpBoxID window]];
		[self groupChanged: inspectorMgr to: [inspectorMgr group]];
	}

	return self;
} // End display

/*\ ---------------------- General Actions ---------------------- \*/
- setShowNewQueries: sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.showNewQueries = [[sender selectedCell] state];
	return self;
}
- setAudioNotification: sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.audioNotification = [[sender selectedCell] state];
	return self;
}
- setUntitledFirstWindow : sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.untitledFirstWindow = [[sender selectedCell] state];
	return self;
}
- setDebuggingEnabled : sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.debuggingEnabled = [[sender selectedCell] state];
	if( prefs.debuggingEnabled == YES )
	{	/* Turn on debugging */
		[self setAppDebugLevel: prefs.appDebugLevel];
	}
	else
	{	/* Turn off debugging */
		[self setAppDebugLevel: NO_DEBUG];
	}

	return self;
}
- setNotificationSnd: sender
{
int type;
const char *sndType[] = {"snd", 0};
const char *currentFile;
MOPathString *sndFile, *tmp;
Sound *currentSnd;

[self debug: MAX_DEBUG method:_cmd, NULL];
	// Selected row is the notification type
	type = [sender selectedRow];
	currentSnd = [self notificationSnd: type];
	currentFile = [currentSnd name];
	currentFile = [self openFileTypes: sndType directory: 0
		file: currentFile forDirectory: NO];
	if( currentFile == 0 )
		return nil;
	sndFile = [[MOPathString alloc] initPath: currentFile];
	tmp = [sndFile fileBasename];
	currentFile = [tmp stringValue];
	currentSnd = [Sound findSoundFor: currentFile];
	if( currentSnd == nil )
	{	// No such named sound, create one from file
		currentSnd = [[Sound alloc] initFromSoundfile: [sndFile stringValue]];
		if( currentSnd == nil )
		{
			NXBeep();
			return nil;
		}
		// Set the sound name to its file base
		[currentSnd setName: currentFile];
	}

	// Replace the current sound
	[prefs.sounds[type] free];
	prefs.sounds[type] = currentSnd;
	[audioFormID setStringValue: [currentSnd name] at: type];
	[tmp free];
	[sndFile free];

	return self;
}
- setNotificationDefaults: sender
{
const char *names[3];

[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.sounds[DirLoaded] = [prefs.sounds[DirLoaded] free];
	prefs.sounds[QueryReceived] = [prefs.sounds[QueryReceived] free];
	prefs.sounds[FTPTransfer] = [prefs.sounds[FTPTransfer] free];
	names[DirLoaded] = [Preferences notificationDefault: DirLoaded];
	names[QueryReceived] = [Preferences notificationDefault: QueryReceived];
	names[FTPTransfer] = [Preferences notificationDefault: FTPTransfer];

	prefs.sounds[DirLoaded] = [Sound findSoundFor: names[DirLoaded]];
	prefs.sounds[QueryReceived] = [Sound findSoundFor: names[QueryReceived]];
	prefs.sounds[FTPTransfer] = [Sound findSoundFor: names[FTPTransfer]];
	[audioFormID setStringValue: names[DirLoaded] at: DirLoaded];
	[audioFormID setStringValue: names[QueryReceived] at: QueryReceived];
	[audioFormID setStringValue: names[FTPTransfer] at: FTPTransfer];

	return self;
}

/*\ ---------------------- Archie Actions ---------------------- \*/
- setQueryType: sender
{
	switch([sender selectedRow])
	{
		case 0 :
			prefs.queryType = 'C';
			break;
		case 1 :
			prefs.queryType = 'S';
			break;
		case 2 :
			prefs.queryType = 'R';
			break;
		case 3 :
		default:
			prefs.queryType = '=';
			break;
	}
[self debug: MAX_DEBUG method:_cmd, "type = %c", prefs.queryType];
	return self;
}
- setExactMode: sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.exactMode = [sender state];
	return self;
}
- setMaxReplies: sender
{
[self debug: MAX_DEBUG method:_cmd, NULL];
	prefs.maxReplies = [sender intValue];
	return self;
}
- setSortType: sender
{
[self debug: MAX_DEBUG method:_cmd, "sort = %d", [sender selectedRow]];
	prefs.sortFlag = [sender selectedRow];
	switch( prefs.sortFlag )
	{
		case 0 :
			cmpProc = AQ_DEFCMP;
			break;
		case 1 :
			cmpProc = AQ_INVDATECMP;
			break;
		case 2 :
			cmpProc = NULL;
			break;
		default :
			cmpProc = AQ_DEFCMP;
			break;
	}
	return self;
}
- setNiceLevel: sender
{
void SetNiceLevel(int nice);
[self debug: MAX_DEBUG method:_cmd, "sort = %d", [sender selectedCol]];
	switch([sender selectedCol])
	{
		case 0 :
			prefs.niceLevel = LowNice;
			break;
		case 1 :
			prefs.niceLevel = MedNice;
			break;
		case 2 :
			prefs.niceLevel = HighNice;
			break;
		default :
			prefs.niceLevel = LowNice;
			break;
	}
	SetNiceLevel(prefs.niceLevel);

	return self;
}

- setHostname: sender
{
	/* See if this is a custom host request */
	if( prefs.isCustomHost == YES )
	{
		prefs.serverHost = prefs.customHost;
		[customHostID setStringValue: prefs.serverHost];
		[customHostID setEnabled: YES];
		[customTitleID setStringValue: "Custom Hostname:"];
	}
	else
	{
	ArchieServer *server;
		prefs.serverHost = [[sender selectedCell] stringValue];
		server = [ArchieServer archieServerFor: prefs.serverHost];
		[customHostID setStringValue: [server serverInfo]];
		[customHostID setEnabled: NO];
		[customTitleID setStringValue: "Server Info:"];
	}
[self debug: MAX_DEBUG method:_cmd, "%s", prefs.serverHost];

	return self;
}

/* The target of the "Custom Server" TextField */
- setCustomHost: sender
{
	prefs.serverHost = [sender stringValue];
	strcpy(prefs.customHost, prefs.serverHost);
[self debug: MAX_DEBUG method:_cmd, "%s", prefs.serverHost];

	return self;
}
- setDebugLevel: sender
{
ButtonCell *cell;
[self debug: MAX_DEBUG method:_cmd, NULL];
	cell = [sender selectedCell];
	pfs_debug = [cell tag];
	return self;
}

// Validate the custom host and max replies fields
- (BOOL) textWillEnd: textObject
{
	if( [textObject charLength] == 0 )
		return YES;
	return NO;
}

/*\ ---------------------- Query Actions ---------------------- \*/
- setModalAQueries:(Button *) sender
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.modalArchieQueries = [sender state];
	return self;
} // End setModalAQueries

- setModalDQueries:(Button *) sender 
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.modalDirQueries = [sender state];
	return self;
} // End setModalDQueries

- setServerTimeout:(TextField *) sender 
{
void SetServerTimeout(int timeout);
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender intValue]];
	prefs.serverTimeout = [sender intValue];
	SetServerTimeout(prefs.serverTimeout);

	return self;
} // End setServerTimeout

- setServerRetries:(TextField *) sender 
{
void SetServerRetries(int count);
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender intValue]];
	prefs.serverRetries = [sender intValue];
	SetServerRetries(prefs.serverRetries);

	return self;
} // End setServerRetries

/* We have to implement this text delegate method so that
	when one tabs between the timeout & retries fields the
	value is updated */
- textDidEnd: textObject endChar:(unsigned short) whyEnd
{
	if( whyEnd == NX_TAB || whyEnd == NX_BTAB )
		if( [textObject superview] == serverTimeoutID )
			prefs.serverTimeout = [serverTimeoutID intValue];
		else
			prefs.serverRetries = [serverRetriesID intValue];
	return self;
}

- setMaxThreadCount:(Matrix *) sender 
{
int tag;
[self debug: MAX_DEBUG method:_cmd, "val = %d", [[sender selectedCell] tag]];

	/* The tags of the max threads matrix are equal to
		the button values with the exception of the 'inf' btn 
		which has a tag value of 0 */
	tag = [[sender selectedCell] tag];
	if( tag == 0 )
		prefs.maxThreadCount = MAXINT;
	else
		prefs.maxThreadCount = tag;

	return self;
} // End setMaxThreadCount

/*\ ---------------------- FTP Actions ---------------------- \*/

- setRetrieveSubDirs:(Button *) sender 
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.retrieveSubDirs = [sender state];
	return self;
} // End setRetrieveSubDirs

- setCollisionWarnings:(Button *) sender 
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.collisionWarnings = [sender state];
	return self;
} // End setCollisionWarnings

- setPrefixCaseSensitive:(Button *) sender
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.prefixCaseSensitive = [sender state];
	return self;
}
- setSuffixCaseSensitive:(Button *) sender
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender state]];
	prefs.prefixCaseSensitive = [sender state];
	return self;
}
- setMaxFileSize:(TextField *) sender
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender intValue]];
	prefs.maxFileSize = [sender intValue];
	return self;
}
- setTransferPriority: sender
{
[self debug: MAX_DEBUG method:_cmd, "val = %d", [sender intValue]];
	prefs.transferPriority = [sender intValue];
	return self;
}

- addFileType:(Button *) sender 
{
	
	return self;
} // End addFileType

- removeFileType:(Button *) sender 
{
	
	return self;
} // End removeFileType

- setAnonLogin:(TextField *) sender
{
	prefs.anonPasswd = [sender stringValue];
[self debug: MAX_DEBUG method:_cmd, "%s", prefs.anonPasswd];

	return self;
}

- setTransferDir:(TextField *)  sender
{
	prefs.transferDir = [sender stringValue];
[self debug: MAX_DEBUG method:_cmd, "%s", prefs.transferDir];

	return self;
}

/*\ ---------------------- General Values ---------------------- \*/
- (BOOL) showNewQueries
{
	return prefs.showNewQueries;
}
- (BOOL) audioNotification
{
	return prefs.audioNotification;
}
- (BOOL) untitledFirstWindow
{
	return prefs.untitledFirstWindow;
}
- (BOOL) debuggingEnabled
{
	return prefs.debuggingEnabled;
}
- (const char *) sndName:(int) type
{
	return [prefs.sounds[type] name];
}
- notificationSnd:(int) type
{
	return prefs.sounds[type];
}

/*\ ---------------------- Archie Values ---------------------- \*/
- (const char *) serverHost
{
	return prefs.serverHost;
} // End serverHost

- (char) queryType
{
	return 	prefs.queryType;
} // End queryType

- (int) maxReplies
{
	return prefs.maxReplies;
} // End maxReplies

- (int) sortFlag
{
	return prefs.sortFlag;
} // End sortFlag

- (int) niceLevel
{
	return prefs.niceLevel;
} // End niceLevel

- (BOOL) exactMode
{
	return prefs.exactMode;
}
- (int (*)()) cmpProc
{
	return cmpProc;
}

/*\ ---------------------- Query Values ---------------------- \*/
- (BOOL) modalArchieQueries
{
	return prefs.modalArchieQueries;
} // End modalArchieQueries

- (BOOL) modalDirQueries
{
	return prefs.modalDirQueries;
} // End modalDirQueries

- (int) serverTimeout
{
	return prefs.serverTimeout;
} // End serverTimeout

- (int) serverRetries
{
	return prefs.serverRetries;
} // End serverRetries

- (int) maxThreadCount
{
	return prefs.maxThreadCount;
} // End maxThreadCount


/*\ ---------------------- FTP Values ---------------------- \*/
- (BOOL) retrieveSubDirs
{
	return prefs.retrieveSubDirs;
} // End retrieveSubDirs

- (BOOL) prefixCaseSensitive
{
	return prefs.prefixCaseSensitive;
}
- (BOOL) suffixCaseSensitive
{
	return prefs.suffixCaseSensitive;
}
- (int) maxFileSize
{
	return prefs.maxFileSize;
}
- (int) transferPriority
{
	return prefs.transferPriority;
}

- (const char *) anonPasswd
{
	return prefs.anonPasswd;
}

- (const char *) transferDir
{
	return prefs.transferDir;
}

- (BOOL) collisionWarnings
{
	return prefs.collisionWarnings;
} // End collisionWarnings

- (BOOL) canOpenFileType: (const char *) ext 
{
	return NO;
} // End canOpenFileType


/*\ -------------------- Browser Delegate Methods -------------------- \*/
- (int)browser: sender  fillMatrix: matrix inColumn:(int) column
{
	if( sender == hostBrowserID )
		return [self loadArchieServers: sender fillMatrix: matrix
			inColumn: column];
	else if( sender == fileBrowserID )
		return [self loadFileTypes: sender fillMatrix: matrix
			inColumn: column];
	return 0;
}

- (int) loadFileTypes: sender fillMatrix: matrix inColumn:(int) column
{
	return 0;
}
// Load the Archie server browser
- (int) loadArchieServers: sender fillMatrix: matrix inColumn:(int) column
{
int row, rows;
List *servers;
ArchieServer *server;
const char *name;
NXBrowserCell *cell;

	if( column == 0 )
	{	// Load the server hosts
		servers = [ArchieServer archieServers];
		if( servers == nil )
			return 0;
		rows = [servers count];
		for(row = 0; row < rows; row ++)
		{
			[matrix addRow];
			cell = [matrix cellAt: row : 0];
			server = [servers objectAt: row];
			[cell setStringValue: [server serverName]];
			[[[cell setLoaded: YES] setEnabled: YES] setLeaf: NO];
		}
	}
	else
	{	// Load this server's info
		name = [[sender selectedCell] stringValue];
		prefs.isCustomHost = NO;
		if( strcmp(name, CUSTOM_STRING) == 0 )
			prefs.isCustomHost = YES;
		server = [ArchieServer archieServerFor: name];
		rows = 0;
		if( server != nil )
		{
			if( prefs.isCustomHost == NO )
			{	// Load the dot decimal and info
				[matrix addRow];
				cell = [matrix cellAt: rows : 0];
				[cell setStringValue: [server serverDotAddr]];
				[[[cell setLoaded: YES] setEnabled: NO] setLeaf: YES];
				rows ++;
				[matrix addRow];
				cell = [matrix cellAt: rows : 0];
				[cell setStringValue: [server serverInfo]];
				[[[cell setLoaded: YES] setEnabled: NO] setLeaf: YES];
				rows ++;
			}
			else
			{	// Only load the server info
				[matrix addRow];
				cell = [matrix cellAt: rows : 0];
				[cell setStringValue: [server serverInfo]];
				[[[cell setLoaded: YES] setEnabled: NO] setLeaf: YES];
				rows ++;
			}
		}
	}

	return rows;
}

/*\ ---------------- InspectorManager Delegate Methods ---------------- \*/
- groupChanged: sender to: (int) newGroup 
{
/* --- MethodDescription
	ReturnValue: self;
	Description: This method is invoked by our inspectorMgr object when the
		user selects a new preferences group via the popup menu in the
		InspectorManager panel(Inspector.nib).

		If our resetPrefPanel variable is nonzero, it indicates that
		preferences view for which it has bits set should be reset to
		reflect the current prefs vales.;
	Args: 
		sender: The save button in the InspectorPanel(Inspector.nib);
*/
BOOL updateDisplay = NO;

	/* Check our update flag and reset the view objects if necessary. */
	if( resetPrefPanel & GENERAL_PREFS_BIT && newGroup == generalPrefsGrp )
	{
		[showQueryID setState: prefs.showNewQueries];
		[useAudioID setState: prefs.audioNotification];
		[newWindowID setState: prefs.untitledFirstWindow];
		[debugEnableID setState: prefs.debuggingEnabled];
		[audioFormID setStringValue: [prefs.sounds[DirLoaded] name]
			at: DirLoaded];
		[audioFormID setStringValue: [prefs.sounds[QueryReceived] name]
			at: QueryReceived];
		[audioFormID setStringValue: [prefs.sounds[FTPTransfer] name]
			at: FTPTransfer];
		resetPrefPanel ^= GENERAL_PREFS_BIT;
		updateDisplay = YES;
	}
	else if( resetPrefPanel & ARCHIE_PREFS_BIT && newGroup == archiePrefsGrp )
	{
	int nice,query;
		[hostBrowserID loadColumnZero];
		if( prefs.isCustomHost == YES )
		{
			[hostBrowserID setPath: CUSTOM_STRING];
			[customHostID setStringValue: prefs.serverHost];
		}
		else
			[hostBrowserID setPath: prefs.serverHost];
		[hostBrowserID sendAction];
		[sortMatrixID selectCellAt: prefs.sortFlag: 0];
		switch( prefs.queryType )
		{
			case 'C' :
				query = 0;
				break;
			case 'S' :
				query = 1;
				break;
			case 'R' :
				query = 2;
				break;
			case '=' :
				query = 3;
				break;
			default :
				query = 0;
				break;
		}
		[patternMatrixID selectCellAt: query : 0];
		[exactBtnID setState: prefs.exactMode];
		switch( prefs.niceLevel )
		{
			case LowNice :
				nice = 0;
				break;
			case MedNice :
				nice = 1;
				break;
			case HighNice :
				nice = 2;
				break;
			default :
				nice = 0;
				break;
		}
		[niceMatrixID selectCellAt: 0 : nice];
		[hitsFormID setIntValue: prefs.maxReplies];
		resetPrefPanel ^= ARCHIE_PREFS_BIT;
		updateDisplay = YES;
	}
	else if( resetPrefPanel & QUERY_PREFS_BIT && newGroup == queryPrefsGrp )
	{
	int tag;
		[modalArchieQueryID setState: prefs.modalArchieQueries];
		[modalDirQueryID setState: prefs.modalDirQueries];
		[serverTimeoutID setIntValue: prefs.serverTimeout];
		[serverRetriesID setIntValue: prefs.serverRetries];
		/* The tags of the max threads matrix are equal to
			the button values with the exception of the 'inf' btn 
			which has a tag value of 0 */
		tag = ( prefs.maxThreadCount < MAXINT ? prefs.maxThreadCount : 0 );
		[maxThreadsID selectCellWithTag: tag];
		resetPrefPanel ^= QUERY_PREFS_BIT;
		updateDisplay = YES;
	}
	else if( resetPrefPanel & FTP_PREFS_BIT && newGroup == ftpPrefsGrp )
	{
		[retrieveSubDirsID setState: prefs.retrieveSubDirs];
		[collisionWarnID setState: prefs.collisionWarnings];
		[transferPriorityID setIntValue: prefs.transferPriority];
		[maxFileSizeID setIntValue: prefs.maxFileSize];
		[prefixCaseID setState: prefs.collisionWarnings];
		[suffixCaseID setState: prefs.collisionWarnings];
		[anonPasswdID setStringValue: prefs.anonPasswd];
		[transferDirID setStringValue: prefs.transferDir];

		/* Since a large amount of entered info could be lost... */
		[fileBrowserID loadColumnZero];
		resetPrefPanel ^= FTP_PREFS_BIT;
		updateDisplay = YES;
	}

	/* Finally, ask the sending InspectorManager to display the panel
		for the newGroup */
	[sender switchToInspector: (newGroup + FIRSTADDEDINSPECTOR)];
	if( updateDisplay == YES )
		[[sender panel] display];

	return self;
} // End groupChangedTo

- inspectRevert: sender 
{
/* --- MethodDescription
	ReturnValue: self;
	Description: This method is invoked by our instpectorMgr object when the
		user selects the restore button in the preferences panel.  We hand off
		the job of updating the default values to -restoreDefaults:;
	Args: 
		sender: The restore button in the InspectorPanel(Inspector.nib);
*/
	[self restoreDefaults: sender];

	return self;
} // End inspectRevert

#define print(x, f) fprintf(stderr, "\t" #x " = " #f "\n", prefs.x);
- inspectOK: sender 
{
/* --- MethodDescription
	ReturnValue: self;
	Description: This method is invoked by our instpectorMgr object when the
		user selects the save button in the preferences panel.  We hand off
		the job of updating the default values to -saveDefaults:;
	Args: 
		sender: The save button in the InspectorPanel(Inspector.nib);
*/
	[[sender panel] endEditingFor: self];
	[self saveDefaults: sender];

if( [self appDebugLevel] > MAX_DEBUG )
{
print(showNewQueries,%d);
print(audioNotification,%d);
print(untitledFirstWindow,%d);
print(debuggingEnabled,%d);
print(appDebugLevel,%d);

print(serverHost,%s);
print(queryType,%d);
print(maxReplies,%d);
print(sortFlag,%d);
print(exactMode,%d);
print(niceLevel,%d);

print(modalArchieQueries,%d);
print(modalDirQueries,%d);
print(serverTimeout,%d);
print(serverRetries,%d);
print(maxThreadCount,%d);

//print(maxFileSize,%d);
//print(prefixCaseSensitive,%d);
//print(suffixCaseSensitive,%d);
print(retrieveSubDirs,%d);
print(collisionWarnings,%d);
print(anonPasswd,%s);
print(transferDir,%s);
}

	return self;
} // End inspectOK

@end
/* RCS Information:
	$Author: me $;
	$Date: 94/01/08 14:40:56 $;
	$Source: /usr1/me/NeXTSrc/Archie/RCS/Preferences.m,v $;
	$Revision: 1.1 $;
	$Log:	Preferences.m,v $
Revision 1.1  94/01/08  14:40:56  me
Check point of 2.09a version.

Revision 1.2  93/03/29  02:02:50  me
Added calls to routines which set prospero/archie globals which have preferences.

Revision 1.1  93/02/23  02:11:19  me
Version 2.01a of the project.
;
*/
