// CRegex.cp
// CRegex.h
// ----------------------------------------------------------------------------------
// Finds regular expressions in the dictionary class.
//
//
// Note: This file is proprietary and confidential to Art Pollard
//	and Lextek Internation.  
// Copyright 1994 Art Pollard / LexTek International
//
//
// ----------------------------------------------------------------------------------
// History:
// 		Art Pollard			June 94
//			Original
//		Clark Goble			08/14/94
//			Checked it over and made a few modifications as part of the
//			C++ conversion.
// ----------------------------------------------------------------------------------


#include "CRegex.h"
#include "TSpell.h"
#include "UError.h"

#define EOS (0)


//#define TEST


// ----------------------------------------------------------------------------------
//	Same	- Returns the number of identical characters
// ----------------------------------------------------------------------------------
// This function returns the number of characters that are the same between
// Word One and Word Two.

short 
CRegex::Same(char *Word1,char *Word2)
{
	short Index=0;

    while((Word1[Index] == Word2[Index]) && 
    	(Word1[Index] != EOS) && 
    	(Word2[Index] !=EOS) )
	{
		Index++;
	}
    
    return Index;

} // Same

// ----------------------------------------------------------------------------------
//	FindFirstMatch	- Finds first expression in the dictionary
// ----------------------------------------------------------------------------------
// This function return DONE if it finds that there are no matches for the
// given pattern.  If there is a possibility for more matches, it returns
// NOTDONE.  To access these (possible) matches, you need to call FindNextWord.
short 
CRegex::FindFirstMatch(CMainDict *Dict, char *Word, CallBackProc CallBack)
{
	char  SeparatorString[]={'[',']','*','?','!','^','-','\\',0};

	NumWordsFound = 0;
	strcpy(TempWord,Word);
	strtok(TempWord,SeparatorString);
	
	if ( strlen(TempWord) == 0 ) 
		return 0; 	// make sure that there is at least
				 	// one character before expression.
				 	// i.e., a* not *a*.  This prevents
				 	// it from having to go through the
				 	// entire dictionary by accident.

	// find the first word which matches the left hand part of the pattern.
	// I.e., the first word which matches "a*" is "a".
	Dict->Find(TempWord);
	
	if ((CallBack != NULL) && (*CallBack)())
		ErrorFunc(eCancel, SET);

	
	if (ErrorFunc(0, GET) < eNo_Err)
	{	return DONE;
	}
	
	// get a copy of this word	
	Dict->Current(CurrentWordBuff);
	if (ErrorFunc(0, GET) < eNo_Err)
	{	return DONE;
	}
	
	NumCharsSame = Same(Word,TempWord);
	
	
	#ifdef _MACINTOSH_
	//SystemTask();		// let the system have some time
	#endif

	do {

	
		if( UMatch::match(Word,CurrentWordBuff) == TRUE) {
			/* ADD THE WORD TO THE LIST */
		  #ifdef TEST
			printf("\n%s",CurrentWordBuff);
		  #else
			strcpy(Word, CurrentWordBuff);
		  #endif
		  return (NOTDONE);
		}
		
		if( Dict->Next(CurrentWordBuff) == EOI )
			return(DONE);
			
		if ((CallBack != NULL) && (*CallBack)())
			ErrorFunc(eCancel, SET);
			
		if (ErrorFunc(0, GET) < eNo_Err)
		{	return DONE;
		}
	
	} while ( ( Same(Word,CurrentWordBuff) >= NumCharsSame) );
	
	return (DONE);
}

// This function will check to see if there is another word which will match
// the pattern given in Word.  If it finds a pattern, it will return NOTDONE
// and add the pattern to the wordlist or return it somehow.  (However we 
// have it set up at the time....)  Otherwise, if there are no more words
// to be found which will match the pattern, it will return DONE.  Cheers!

short 
CRegex::FindNextMatch(CMainDict *Dict, char *Word, CallBackProc CallBack)
{
   short Result;
	
	// Advance to the next word
	Result = Dict->Next(CurrentWordBuff);
	
	if(Result == EOI)
	  return (DONE);
	  
	
	#ifdef _MACINTOSH_
	//SystemTask();		// let the system have some time
	#endif

	do {
		if( UMatch::match(Word,CurrentWordBuff) == TRUE) {
			/* ADD THE WORD TO THE LIST */
			NumWordsFound++;
		  #ifdef TEST
			printf("\n%s",CurrentWordBuff);
		  #else
			strcpy(Word, CurrentWordBuff);
			return (NOTDONE);
		  #endif
		}

		if( Dict->Next(CurrentWordBuff) == EOI )
			return(DONE);

		if ((CallBack != NULL) && (*CallBack)())
			ErrorFunc(eCancel, SET);

		if (ErrorFunc(0, GET) < eNo_Err)
		{	return DONE;
		}

	} while ( ( Same(Word,CurrentWordBuff) >= NumCharsSame) );

	return (DONE);
}


/*

short
CRegex::Find(CMainDict *Dict, char *Word)
{
	short   NumWordsFound = 0;
	short   NumCharsSame  = 0;
	char  TempWord[MAXWORDLENGTH];
	char  CurrentWordBuff[MAXWORDLENGTH];
	char  SeparatorString[]={'[',']','*','?','!','^','-','\\',0};
	
	strcpy(TempWord,Word);
	strtok(TempWord,SeparatorString);
	
	if ( strlen(TempWord) == 0 ) 
		return 0; 	// make sure that there is at least
				 	// one character before expression.
				 	// i.e., a* not *a*.  This prevents
				 	// it from having to go through the
				 	// entire dictionary.
				 	
	if (Done == DONE) 
		Dict->Find(Word);
	else 
	{
		strcpy(CurrentWordBuff,Cursor);
		Dict->Find(Word);
	}
	
	Dict->Current(CurrentWordBuff);
	NumCharsSame = Same(Word,TempWord);
	
	do {
		if( UMatch::match(Word,CurrentWordBuff) == TRUE) {
			// ADD THE WORD TO THE LIST 
		  #ifdef TEST
			printf("\n%s",CurrentWordBuff);
		  #else
			RegexWordList->Append( (TItemtype)CurrentWordBuff );
		  #endif
		  NumWordsFound++;
		}
		
		if( Dict->Next(CurrentWordBuff) == EOI )
			return(NumWordsFound);
	
	} while ( ( Same(Word,CurrentWordBuff) >= NumCharsSame) );
	
	return (NumWordsFound);
}


*/
	


CRegex::CRegex()
{
	Done = DONE;
	// RegexWordList = new ULinkedList;
}


CRegex::~CRegex()
{
	// delete RegexWordList;
}


#ifdef TEST


void main()
{
	CMainDict *Dict;
	
	char DictName[20];
	char UserDictName[20];
	short  DocWordSize;
	short  UserWordSize;
	short  SkipWordSize;
	long  NumBuffers;
	short  Page;
	short  CurrentNibble;
	
	char Choice[20];
	short  Result;
	char Word[MAXWORDLENGTH];
	short  ReturnValue;
	Uio *File;
	
	CRegex	*RegularExpression;
	
	
	RegularExpression = new CRegex;
	
	for(;;) 
	{
		printf("\n\n1) Open Index File ");
		printf("\n2) Find a Pattern ");
		printf("\n0) Quit ");
		gets(Choice);
		Result = atoi(Choice);
		switch (Result) 
		{
			case 1:
				printf("\nDictionary Name :");
				gets(DictName);
				printf("\nUser Dictionary Name :");
				gets(UserDictName);
				printf("\nDocument Word Cache Size :");
				gets(Choice);
				DocWordSize = atoi(Choice);
				printf("\nUser Word Cache Size :");
				gets(Choice);
				printf("\nSkip Word Cache Size :");
				gets(Choice);
				SkipWordSize = atoi(Choice);
				UserWordSize = atoi(Choice);
				printf("\nNumber of Buffers :");
				gets(Choice);
				NumBuffers = atoi(Choice);
			
				Dict = new CMainDict(NumBuffers, DictName);
				if(Dict == NULL) 
					printf("\n\a\aError Opening Dictionary....");
				break;
			case 2:
				printf("\nPattern to Find :");
				gets(Choice);
				RegularExpression->Find(Dict,Choice);
				break;
			case 0:
				exit(0);
				break;
		}
	}
	
	delete RegularExpression;
}

#endif

