// Wed Nov 13 12:19:35 MET 1996 by Daniel Bðhringer

#import "AppDelegate.TreeSearching.h"

@implementation AppDelegate(SearchableText)

- renewSearchHashtable
{	if(searchHash) [self invalidateSearchHashtable];
	searchHash=[[HashTable alloc] initKeyDesc:"*" valueDesc:"@"];
	return self;
}
- invalidateSearchHashtable
{	if(searchHash) searchHash=[[searchHash freeObjects] free];
	return self;
}

- (int)searchFor:(const char *)pattern
			mode:(SearchMode)mode
		 reverse:(BOOL)rev
		 regexpr:(BOOL)regexpr
		   cases:(BOOL)cases
		position:(out int *)pos
			size:(out int *)size
{	int			 found=NO;
	MiscList	*cashedSearch;
	if(!strlen(pattern)) return NO;
	if(cashedSearch=[searchHash valueForKey:pattern])
	{	if(rev) found=!![self selectEntry:[cashedSearch setPreviousObject]];
		else {	found=!![self selectEntry:[cashedSearch setNextObject]];
				if(!found && [cashedSearch currentPosition]+1 == [cashedSearch count])
				{	[cashedSearch setTo:0];		// cycle¼
					found=!![self selectEntry:[cashedSearch objectAt:0]];
				}
			 }
	} else
	{	MiscList *foundLetters;
		MiscString *searchPattern=[[MiscString alloc] initString:pattern];
		MiscTreeCmpMode_t	cmp=cases? MiscTreeCmp_casestrcmp:MiscTreeCmp_strcmp;	
		if(regexpr)			cmp=cases? MiscTreeCmp_caseregex:MiscTreeCmp_regex;
		if(foundLetters=[[self root] listOfOccurence:searchPattern useLabel:YES cmp:cmp])
		{	[searchHash insertKey:NXCopyStringBuffer(pattern) value:foundLetters];
			found=!![self selectEntry:[foundLetters objectAt:0]];
		} searchPattern=[searchPattern free];
	}
	return found;
}
- (int)replaceAll:(const char *)pattern with:(const char *)replacement 
			mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases
{	return SEARCH_UNIMPLEMENTED;
}
- (oneway void)makeSelectionVisible {}
// although required these methods make no sense here
- (oneway void)replaceSelection:(const char *)replacement	{}
- (oneway void)selectTextFrom:(int)start to:(int)end {}
- (void)writeSelectionToPasteboard:(in Pasteboard *)pboard asType:(in NXAtom)type {}
@end
