//
//	ManOpenApp Class
//
//	Harald Schlangmann, 19.7.93
//

#import "ManOpenApp.h"
#import "ManPageWindow.h"
#import <defaults/defaults.h>

@implementation ManOpenApp

- printManPage:sender {

	if( [[NXApp mainWindow] respondsTo:@selector(printManPage:)] )
		[[NXApp mainWindow] printManPage:sender];
	else
		NXBeep();

	return self;
}

- info:sender {

	static id infoPanel = nil;
	
	if( !infoPanel )
		infoPanel = [NXApp loadNibSection:"InfoPanel.nib"
				owner:NXApp withNames:NO];
	
	[infoPanel makeKeyAndOrderFront:sender];
	
	return self;
}

+ new {

	ManOpenApp	*theApp = [super new];
	
	theApp->manPageList = [[List alloc] init];
	
	return theApp;
}

- (const char *)nroffCmd {

	return [nroffCmd stringValue];
}

- appDidInit:sender {

	NXDefaultsVector ManOpenDefaults = {
			{"QuitWhenLastClosed","NO"},
			{"NroffCmd","/usr/bin/nroff -man %s"},
			{NULL,NULL}
		};

	NXRegisterDefaults("ManOpen",ManOpenDefaults);

	[quitWhenLastClosed setState:
		strcmp(NXGetDefaultValue("ManOpen","QuitWhenLastClosed"),
			"YES")==0];
	[nroffCmd setStringValue:NXGetDefaultValue("ManOpen","NroffCmd")];

	[[self appListener] setServicesDelegate:self];

	return self;
}

- open:(const char *)filename {

	int	count = [manPageList count];
	
	while( --count>=0 ) {
		if( strcmp([[manPageList objectAt:count] getFile],
			filename)==0 ) {
			[[manPageList objectAt:count] 
				makeKeyAndOrderFront:self];
			break;
		}
	}
	
	if( count<0 ) {
	
		//	Not yet opened

		id	aManPage = [NXApp loadNibSection:"ManPage.nib"
					owner:NXApp withNames:NO];
	
		[aManPage loadManPage:filename];
		
		[manPageList addObject:aManPage];
	}
	
	return self;
}

- (BOOL)appAcceptsAnotherFile:sender {

	return YES;
}

- (int)app:sender openFile:(const char *)filename type:(const char *)aType {

	[self open:filename];

	return YES;
}

//	Open in ManOpen service

- openService:(id)pasteboard
	userData:(const char*)userData
	error:(char**)msg {

	const NXAtom	*t;
	
	fprintf(stderr,"openService called...\n");
	
	t = [pasteboard types];
	
	while( t&&*t ) {
		if( *t==NXFilenamePboardType )
			break;
		t++;
	}
	
	if( *t==NXFilenamePboardType ) {
	
		char	*data;
		char	filename[FILENAME_MAX];
		int	length;
		
		if( [pasteboard readType:NXFilenamePboardType 
                        data:&data length:&length] ) {
	
			int	scanIndex = 0;
			
			//	Allow multi-file open:
			
			while( scanIndex<length ) {
			
				char	*write = filename;
				
				while( data[scanIndex]!='\t'
					&&scanIndex<length )
					*write++ = data[scanIndex++];
				
				//	Skip TAB?
				
				if( scanIndex<length )
					scanIndex++;
				
				*write = '\0';
				[self open:filename];
			}	
				
			[pasteboard deallocatePasteboardData:data 
				length:length];
			
		} else
			NXBeep();
	}
	
	return self;
}

- openMan:sender {

	id			openPanel;
	const char *const 	*files;

	openPanel = [[OpenPanel new] allowMultipleFiles:YES];

        if( [openPanel runModal] ) {

		files = [openPanel filenames];

		if( files&&*files ) {

			//	At least one file was selected

			while( *files ) {

				char	tmpFileName[FILENAME_MAX];
				
				sprintf(tmpFileName,"%s/%s",
					[openPanel directory],
					*files);
				[self open:tmpFileName];

				files++;
			}
		}
	}

	return self;
}

- manPageClosed:sender {

	//	Remove sender from List
	
	[manPageList removeObject:sender];
	
	if( [quitWhenLastClosed state]&&[manPageList count]==0 )
		[self terminate:self];
	
	return self;
}

- terminate:sender {

	NXWriteDefault("ManOpen","QuitWhenLastClosed",
		[quitWhenLastClosed state]?"YES":"NO");
	NXWriteDefault("ManOpen","NroffCmd",[nroffCmd stringValue]);
	
	return [super terminate:sender];
}

//	Find Panel implementation

- firstResponderValidFind {

	id 	obj = [[NXApp mainWindow] firstResponder];
	
	return (obj&&[obj respondsTo:
			@selector(findText:ignoreCase:backwards:wrap:)])?
			obj:nil;
}

- search:sender backwards:(BOOL)flag {

	id	obj = [self firstResponderValidFind];
	
	if( !obj )
		NXBeep();
	else if( !*[findText stringValue] )
		NXBeep();
	else if( ![obj findText:[findText stringValue]
			ignoreCase:[ignoreCase state]
			backwards:flag wrap:YES] )
		NXBeep();

	return self;
}

- searchNext:sender {

	return [self search:sender backwards:NO];
}

- searchPrevious:sender {

	return [self search:sender backwards:YES];
}

- firstResponderValidSelection {

	id 	obj = [[NXApp mainWindow] firstResponder];
	
	return (obj&&[obj respondsTo:@selector(getSel::)]&&
		[obj respondsTo:@selector(getSubstring:start:length:)])?
			obj:nil;
}

- enterSelection:sender {

	id 	obj = [self firstResponderValidSelection];

    	if( !obj )
		NXBeep();
	else {
		char 		*str;
		NXSelPt 	from, to;
		int 		bufLen; 
    
		[obj getSel:&from :&to];
		bufLen = to.cp-from.cp;
	    
	    	str = alloca(bufLen+1);
	    
		[obj getSubstring:str start:from.cp length:bufLen];
		str[bufLen] = '\0';
		[findText setStringValue:str];
    	}

	return self;
}

- searchLibrarianLike:sender {
	
	id 	obj = [self firstResponderValidSelection];

    	if( !obj )
		NXBeep();
	else {
		char 		*str;
		NXSelPt 	from, to;
		int 		bufLen; 
    
		[obj getSel:&from :&to];
		bufLen = to.cp-from.cp;
		
		if( bufLen!=0 ) {
	    		str = alloca(bufLen+1);
			[obj getSubstring:str start:from.cp length:bufLen];
			str[bufLen] = '\0';
			[findText setStringValue:str];
		}
		
		[self searchNext:sender];
    	}

	return self;
}

- findPanelComeUp:sender {
	
	[findPanel makeKeyAndOrderFront:sender];
	[findText selectText:sender];

	return self;
}

@end
