#include "SPELLWRI.H"
#include "SPELL.H"

#include <Carbon/Carbon.h>

//#define FuncType  __declspec( dllexport )

extern "C" {

#define CheckValid  ( ((SpellClass*)Speller)->magic == DICTMAGIC )

short FuncType isNumber(char *word)
{
	while ( (*word != '\0') && (*word >= '0') && (*word <= '9')  )
		word++;
	return (*word == '\0');
}

short FuncType CheckNum( char *word)
{
	while ( (*word != '\0') && ( isalpha(*word) ) )
	{	word++;
	}

	return ( isalpha(*word) );
}

void FuncType *StartSpellCheckSession()
{ 
	ErrorFunc(0, SET);

	void *temp =  (void *) new SpellClass;
	if (ErrorFunc(0, GET) < eNo_Err)
	{	delete temp;
		return NULL;
	}
	return temp;
}


void FuncType EndSpellCheckSession(void *Speller)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{ ErrorFunc(eGeneral, SET);
		return;
	}
	delete Speller;
}


short FuncType DictOpen(void *Speller, unsigned long *DictNum, short DictType, long Size, FioParam * theFile)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return 0;
	}

	((SpellClass*)Speller)->AddDict(DictNum, DictType, Size, theFile);
	return (*DictNum != 0);
}


void FuncType DictClose(void *Speller, unsigned long DictNum)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return;
	}

	((SpellClass*)Speller)->DeleteDict(DictNum);
}

short	FuncType  SelectWord(void *Speller, char *Word, char *Suggestion )
{
	// Dummy use of *Suggestion to get rid of warning....
	// This will be fixed on further releases.
	Suggestion = Suggestion;

	ErrorFunc(0, SET);
	CDocDict *docDict = ((SpellClass*) Speller)->theDocDict;

	if (docDict != NULL)
		return (docDict->Add(Word));
	return FALSE;
}

short FuncType CheckWord(void *Speller, unsigned long DictNum, short DictType, char *Word, WordInfo *Info)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}

	((SpellClass*) Speller)->DictTypeFound = 0;

	// Check for case style
	Info->Case = ((SpellClass*) Speller)->CaseCheckWord(Word);
	Info->Replace = FALSE;

	// make word lowercase
	((SpellClass*) Speller)->WordLower(Word);


	// Check for duplicate word
	if (((SpellClass*)Speller)->EStrCmp(((SpellClass*) Speller)->LastWord, Word) == 0)
		Info->Duplicate = WORD_DUPLICATED;
	else
		Info->Duplicate = WORD_NOT_DUPLICATED;

	// Update LastWord
	strcpy(((SpellClass*) Speller)->LastWord,Word);

	// first find the dictionaries
	short			aType = DictType;
	unsigned long		aNum = DictNum;
	unsigned long 		theNums = aNum;

	// check doc dict (if specified)
	CDocDict *docDict = ((SpellClass*) Speller)->theDocDict;
	if ((docDict != NULL) && (((SpellClass*) Speller)->theDocNum & DictNum))
		if (docDict->Check(Word) == FOUND)
			return FOUND;

	CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);

	if (aNum == 0)
		return NOTFOUND;


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

	while ( aDict != NULL )
	{
		if ( (aType == AUTO_DICT) || ( aType == SUGGEST_DICT) ) {
			if ( ((CSugDict*) aDict)->Check(Word) == FOUND)  {
				// was the word in the dict?
				// for these dicts the word is wrong if it is in the dict
				((SpellClass*) Speller)->DictTypeFound = aType;
				Info->Replace = (aType == AUTO_DICT);
				return NOTFOUND;
			} else {
				((SpellClass*) Speller)->DictTypeFound = 0;
			}
		}
		else if ( aType == SKIP_DICT )
		{	if ( ((CSkipDict*) aDict)->Check(Word) == FOUND )
			{	if (docDict != NULL)
					docDict->Add(Word);
				((SpellClass*) Speller)->DictTypeFound = aType;
				return FOUND;
			}
		}
		else if ( aType == USER_DICT )
		{	if ( ((CQCUser*) aDict)->Check(Word) == FOUND)
			{	if (docDict != NULL)
					docDict->Add(Word);
				return FOUND;
			}
		}
		else if ( aType == MAIN_DICT )
		{
			if ( ((CMainDict*) aDict)->Check(Word) == FOUND)
			{	if (docDict != NULL)
						docDict->Add(Word);
					return FOUND;
			} else
			{	// check for numeric values
				if (isNumber(Word))
					return FOUND;
			}
		}
		theNums = theNums & (~aNum);	// remove this dict from being searched

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

		if ( theNums == 0)
			return NOTFOUND;
		// Find the next dict
		aType = DictType;
		aNum = theNums;

		aDict = ((SpellClass*)Speller)->FindDict(&aNum, &aType);
	}
	
	return NOTFOUND; // should never get here.
}


short FuncType  FindFirstSuggestion(void *Speller, unsigned long DictNum, short DictType, char *Word,
				char *Suggestion, char *Comment, short *AutoReplace, CallBackProc CallBack)
{
	ErrorFunc(0, SET);

	CDict 	*aDict;

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}

	if(strlen(Word) < 2)
		return FALSE;

	// make word lowercase
	((SpellClass*) Speller)->WordLower(Word);

	((SpellClass*) Speller)->ClearDup();

	Suggestion[0] = '\0';
	Comment[0] = '\0';
	*AutoReplace = FALSE;
	((SpellClass*) Speller)->DictsSearched = 0;
	
	// check to see if it was flagged by the Suggestion Dictionary or AutoDict
	unsigned long aNum = 0;
	unsigned long theNum = DictNum;
	short aType = ((SpellClass*) Speller)->DictTypeFound;
	
	if (aType)
	{	// in a suggest or auto dict
		aDict =  ((SpellClass*) Speller)->FindDict(&aNum, &aType);

		if ( ((CSugDict *) aDict)->Find(Word) )  // it had better find it!
		{	((SpellClass*) Speller)->CheckDup(Word);
			((SpellClass*) Speller)->DictSearching = aNum;
			*AutoReplace = (aType == AUTO_DICT);
			return ((CSugDict *) aDict)->Current(Word, Suggestion, Comment);
	
		}
	} 
	
	if ( ErrorFunc(0, GET) < eNo_Err )
	{	return ErrorFunc(0, GET);
	}

	short Found = FALSE;
	aNum = DictNum;
	aType = DictType;
	aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);

	while (!Found && (aDict != NULL))
	{
		if (aType == USER_DICT)
		{
			Found = ((CQCUser*)aDict)->QCFind(Word, Suggestion, CallBack);
			if (!Found)	// no suggestions
			{
				// Mark this dictionary as having been searched by adding it's bit to the list
				((SpellClass*) Speller)->DictsSearched = 
					((SpellClass*) Speller)->DictsSearched | aNum;
			} else
			{	((SpellClass*) Speller)->CheckDup(Suggestion);	// won't be a dupe
			
				// Mark this dictionary as currently being searched
				((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
		} else if (aType == MAIN_DICT)
		{	// main dict uses the call back routine
			Found = ((CQCheck*)aDict)->QCFind(Word, Suggestion, CallBack);
			
			if (!Found)
			{	// do a phonetical test
				if ( ((SpellClass*) Speller)->FirstSuggestion( (CMainDict*)aDict, Word, 
						Suggestion, CallBack) != FOUND )
				{	// Mark this dictionary as having been searched by adding it's bit to the list
					((SpellClass*) Speller)->DictsSearched = 
						((SpellClass*) Speller)->DictsSearched | aNum;
					((SpellClass*) Speller)->Phonetic = FALSE; // reset phonetic flag
				} else
				{	// Mark this dictionary as currently being phonetically searched
					((SpellClass*) Speller)->CheckDup(Suggestion);
					((SpellClass*) Speller)->Phonetic = TRUE;
					((SpellClass*) Speller)->DictSearching = aNum;
					return FOUND;
				} 
			} else
			{	// Mark this dictionary as currently being quickchecked searched
				((SpellClass*) Speller)->CheckDup(Suggestion);
				((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
		}
		
		if ( ErrorFunc(0, GET) < eNo_Err )
		{	return ErrorFunc(0, GET);
		}


		theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
		if (theNum == 0)
			return NOTFOUND;
		aNum = theNum;
		aType = DictType;
		aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		
	}

	return NOTFOUND;
	
}

short FuncType FindNextSuggestion(void *Speller, unsigned long DictNum, short DictType, char *Word,
		 char *Suggestion, char *Comment, short *AutoReplace, CallBackProc CallBack)
{
	ErrorFunc(0, SET);

	short	isDuped = FALSE;

	CDict 	*aDict;

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	// make word lowercase
	((SpellClass*) Speller)->WordLower(Word);

	short Found = FALSE;
	unsigned long aNum;
	unsigned long theNum = DictNum;
	
	Suggestion[0] = '\0';
	Comment[0] = '\0';
	short aType = DictType;
	
	// Check to see if the 'check' was flagged by a Suggest Dict
	short fSugDict = ((SpellClass*) Speller)->DictTypeFound;
	
	// in a suggest or auto dict?
	if (fSugDict)
	{	
		aType = fSugDict;		// only search the type (Auto or Suggest)
		
		// found initially false
		
		while (!Found)
		{	// get the first available dictionary
			aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);

			if (aDict == NULL) // no more dictionaries
				return NOTFOUND;
			
			// check to see if we are in a new dictionary or one previously
			// searched -- to see if we use current or next
			if (fSugDict)
			{	Found = ((CSugDict *) aDict)->Next(Word, Suggestion, Comment);
				if (Found)
				{	((SpellClass*) Speller)->CheckDup(Suggestion);	// add to dupe list
					*AutoReplace = (aType == AUTO_DICT);
					return FOUND;
				} else
				{	fSugDict = 0;	// in new dictionary
				
					// don't search this dict twice
					((SpellClass*) Speller)->DictsSearched = 
						((SpellClass*) Speller)->DictsSearched | aNum;
					aNum = DictNum & (~aNum);
					aType = DictType;	
				} // if/else found
			} else
			{	// is the word in this dictionary
				Found = ((CSugDict *) aDict)->Find(Word);
				if (Found)
				{
					*AutoReplace = (aType == AUTO_DICT);
					return ((CSugDict *) aDict)->Current(Word, Suggestion, Comment);
				} else
				{	// don't search this dict twice
					((SpellClass*) Speller)->DictsSearched = 
						((SpellClass*) Speller)->DictsSearched | aNum;
					aNum = DictNum;
					aType = DictType;	
				} // if/else found
				
			} // if/else in dict
		} // while not found
	} // if auto/sug dict
	
	aNum = DictNum;
	aType = DictType;

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

	aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);


	
	while (!Found && (aDict != NULL))
	{
		if (aType == USER_DICT)
		{
			if (aNum == ((SpellClass*) Speller)->DictSearching)
			{	// we have already gotten the first element
				Found = ((CQCUser*)aDict)->QCNext(Word, Suggestion, CallBack);
				if (!Found)	// no suggestions
				{	
					// Mark this dictionary as having been searched by adding it's bit to the list
					((SpellClass*) Speller)->DictsSearched =
						((SpellClass*) Speller)->DictsSearched | aNum;
				} else
				{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
					if (!isDuped)
						return FOUND;
               // We try this and see what happens
               else
               	return NOTFOUND;
                 	//aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
				}
			} else
			{ 	// we haven't gotten the first element yet.
				Found = ((CQCUser*)aDict)->QCFind(Word, Suggestion, CallBack);
				if (!Found)
				{
					// Mark this dictionary as being searched by adding it's bit to the list
					((SpellClass*) Speller)->DictsSearched =
						((SpellClass*) Speller)->DictsSearched | aNum;

				} else
				{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
					if (!isDuped)
					{	((SpellClass*) Speller)->DictSearching = aNum;
						return FOUND;
					}
               // We try this and see what happens
               else
               	return NOTFOUND;
                 	//aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
				}
			}
		} else if (aType == MAIN_DICT)
		{
			if (aNum == ((SpellClass*) Speller)->DictSearching)
			{	// we have already gotten the first element
				if (((SpellClass*) Speller)->Phonetic == TRUE)
				{
					// do a phonetical test
					if (((SpellClass*) Speller)->NextSuggestion( (CMainDict*)aDict,
						Word, Suggestion, CallBack) != FOUND)
					{	// Mark this dictionary as having been searched by adding it's bit
						((SpellClass*) Speller)->DictsSearched =
							((SpellClass*) Speller)->DictsSearched | aNum;
						((SpellClass*) Speller)->Phonetic = FALSE; // reset flag

					} else
					{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
						((SpellClass*) Speller)->Phonetic = TRUE;
						if (!isDuped)	
						{	// Mark this dictionary as currently being phonetically searched
							// (already marked)
							return FOUND;
						}
					} 
				} else 
				{	
					// we are in the process of doing a quickcheck
					Found = ((CQCheck*)aDict)->QCNext(Word, Suggestion, CallBack);
					if (!Found)
					{	
						// do a phonetical test
						if (((SpellClass*) Speller)->FirstSuggestion( (CMainDict*)aDict,
							Word, Suggestion, CallBack) != FOUND)
						{	// Mark this dictionary as having been searched by adding it's bit
							((SpellClass*) Speller)->DictsSearched = 
								((SpellClass*) Speller)->DictsSearched | aNum;
							// flag already reset
						} else
						{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
							// Mark this dictionary as currently being phonetically searched
							((SpellClass*) Speller)->Phonetic = TRUE;
							if (!isDuped)
							{	
								return FOUND;
							}
						}
					} else
					{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
						if (!isDuped)
						{	// This dictionary is still being quickchecked (we found one)
							return FOUND;
						}
					}
				} // phonetic if
			} else
			{	// searching new dictionary
				Found = ((CQCheck*)aDict)->QCFind(Word, Suggestion, CallBack);
				if (!Found)
				{	// do a phonetical test
					if (((SpellClass*) Speller)->FirstSuggestion( (CMainDict*)aDict,
						Word, Suggestion, CallBack) != FOUND)
					{	// Mark this dictionary as having been searched by adding it's bit
						((SpellClass*) Speller)->DictsSearched =
							((SpellClass*) Speller)->DictsSearched | aNum;
						// flag already reset
					} else
					{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
						if (!isDuped)
						{	// Mark this dictionary as currently being phonetically searched
							((SpellClass*) Speller)->Phonetic = TRUE;
							((SpellClass*) Speller)->DictSearching = aNum;
							return FOUND;
						}
					}
				} else
				{	isDuped = ((SpellClass*) Speller)->CheckDup(Suggestion);
					if (!isDuped)
					{	// This dictionary is being quickchecked (we found one)
						((SpellClass*) Speller)->DictSearching = aNum;
						return FOUND;
					}
				}
			}
		}

		if ( ErrorFunc(0, GET) < eNo_Err )
		{	return ErrorFunc(0, GET);
		}
		
		if (!isDuped)
		{
			theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
			if (theNum == 0)
				return NOTFOUND;
			aNum = theNum;
			aType = DictType;
			aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		} else
		{	isDuped = FALSE;
			Found = FALSE;
		}

	}

	return NOTFOUND;
}

short FuncType  AddToDictionary(void *Speller, unsigned long DictNum, char *Word, char *Suggestion, char *Comment)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	unsigned long	aNum = DictNum;
	short	aType = 0;
	CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	
	if (aDict == NULL)
		return FALSE;

	if ((aType == AUTO_DICT) || (aType == SUGGEST_DICT))
	{
		return ((CSugDict*)aDict)->Add(Word, Suggestion, Comment);
		
	} else if (aType == SKIP_DICT)
	{
		return ((CSkipDict*)aDict)->Add(Word);
		
	} else if (aType == USER_DICT)
	{
		return ((CQCUser*)aDict)->Add(Word);
	} else if (aType == MAIN_DICT)
	{
		ErrorFunc(eIllegalCmd, SET);
		return eIllegalCmd;
	}
	return FALSE;

}

short FuncType FindFirstRegex(void *Speller, unsigned long DictNum, short DictType,
 		char *Word, CallBackProc CallBack)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	unsigned long aNum = DictNum;
	unsigned long theNum = DictNum;
	short aType = DictType;
	
	((SpellClass*) Speller)->DictsSearched = 0;
	
	CSugDict *aDict = (CSugDict *) ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	
	short Found = FALSE;
	while (!Found && (aDict != NULL))
	{
		if (aType == MAIN_DICT)
		{	Found = (((SpellClass*) Speller)->FindFirstMatch( (CMainDict*)aDict, Word, CallBack ));
			if (Found == DONE)
			{	// Mark this dictionary as being searched by adding it's bit
				((SpellClass*) Speller)->DictsSearched = 
					((SpellClass*) Speller)->DictsSearched | aNum;
			} else
			{	((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
		} else {
			ErrorFunc(eIllegalCmd, SET);
			return eIllegalCmd;
		}
		
		if ( ErrorFunc(0, GET) < eNo_Err )
		{	return ErrorFunc(0, GET);
		}

		theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
		if (theNum == 0)
			return NOTFOUND;
		aNum = theNum;
		aType = DictType;
		// AP 6/25/95
//		CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		((SpellClass *) Speller) ->FindDict(&aNum,&aType);
	}
	
	return NOTFOUND;
}

short FuncType FindNextRegex(void *Speller, unsigned long DictNum, short DictType, char *Word,
			CallBackProc CallBack)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	unsigned long aNum = DictNum;
	short aType = 0;
	unsigned long theNum = DictNum;

	
	CSugDict *aDict = (CSugDict *) ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	
	short Found = FALSE;
	while (!Found && (aDict != NULL))
	{
		if (aType == MAIN_DICT)
		{	if ( aNum == ((SpellClass*) Speller)->DictSearching)
				Found = (((SpellClass*) Speller)->FindNextMatch( (CMainDict*)aDict, Word, CallBack ));
			else
				Found = (((SpellClass*) Speller)->FindFirstMatch( (CMainDict*)aDict, Word, CallBack ));
			
			if (Found == DONE)
			{	// Mark this dictionary as being searched by adding it's bit
				((SpellClass*) Speller)->DictsSearched = 
					((SpellClass*) Speller)->DictsSearched | aNum;
			} else
			{	((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
			
		} else {
			ErrorFunc(eIllegalCmd, SET);
			return eIllegalCmd;
		}

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

		theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
		if (theNum == 0)
			return NOTFOUND;
		aNum = theNum;
		aType = DictType;
		// AP 6/25/95
//		CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		((SpellClass *) Speller)->FindDict(&aNum,&aType);
	}

	return NOTFOUND;
}

short FuncType LocateWord(void *Speller, unsigned long DictNum, short DictType, char *Word)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	unsigned long aNum = DictNum;
	unsigned long theNum = DictNum;
	short aType = 0;
	
	((SpellClass*) Speller)->DictsSearched = 0;
	
	CSugDict *aDict = (CSugDict *) ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	
	short Found = FALSE;
	while (!Found && (aDict != NULL))
	{
		if (aType == MAIN_DICT)
		{	Found = ((CMainDict*)aDict)->Find(  Word );
			if (!Found)
			{	// Mark this dictionary as being searched
				((SpellClass*) Speller)->DictsSearched = 
					((SpellClass*) Speller)->DictsSearched | aNum;
			} else
			{	((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
		}
		
		if ( ErrorFunc(0, GET) < eNo_Err )
		{	return ErrorFunc(0, GET);
		}

		theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
		aNum = theNum;
		aType = DictType;
//		CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		// AP 6/25/95
		((SpellClass *) Speller)->FindDict(&aNum,&aType);
	
	}

	return NOTFOUND;
}

short FuncType  NextWord(void *Speller, unsigned long DictNum, short DictType, char *Word)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}
	
	unsigned long aNum = DictNum;
	unsigned long theNum = DictNum;
	short aType = 0;
	

	CSugDict *aDict = (CSugDict *) ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	
	short Found = FALSE;
	while (!Found && (aDict != NULL))
	{
		if (aType == MAIN_DICT)
		{	if ( aNum != ((SpellClass*) Speller)->DictSearching)
				Found = ((CMainDict*)aDict)->Find( Word );
			else
				Found = ((CMainDict*)aDict)->Next( Word );
			
			if (!Found)
			{	// Mark this dictionary as being searched
				((SpellClass*) Speller)->DictsSearched = 
					((SpellClass*) Speller)->DictsSearched | aNum;
			} else
			{	((SpellClass*) Speller)->DictSearching = aNum;
				return FOUND;
			}
			
		}
		
		if ( ErrorFunc(0, GET) < eNo_Err )
		{	return ErrorFunc(0, GET);
		}

		theNum = theNum & (~aNum);	// exclude last dict searched from dicts to search
		aNum = theNum;
		aType = DictType;
//		CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
		// AP 6/25/95
		((SpellClass *) Speller)->FindDict(&aNum,&aType);
	}

	return NOTFOUND;
}

short FuncType  CurrentWord(void *Speller, unsigned long DictNum, short DictType, char *Word)
{
	ErrorFunc(0, SET);

	if (!CheckValid)
	{	ErrorFunc(eNotSpeller, SET);
		return eNotSpeller;
	}

	short aType = DictType;
	unsigned long aNum = (((SpellClass*) Speller)->DictSearching & DictNum);
	// AP 6/25/95
//	CDict *aDict = ((SpellClass*) Speller)->FindDict(&aNum, &aType);
	//((SpellClass *) Speller)->FindDict(&DictNum,&aType); // Was aNum AP 9/23/96
	// AP 6/37/95 (was aDict == NULL)
	CDict *aDict = ((SpellClass*) Speller)->FindDict((unsigned long *)&DictNum, &aType);
	if (Speller == NULL)
		return FALSE;

	// AP 6/25/95
	//((CMainDict*)Speller)->Current(Word);
	((CMainDict*)aDict)->Current(Word);

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

	return TRUE;
}

short	FuncType GetSpellError()
{
	return  ErrorFunc(0, GET);
}

void FuncType FixCase(void *Speller, char *Word, short CaseCode)
{
	((SpellClass*) Speller)->FixCase(Word, CaseCode);
}

}	// extern "C"

#ifdef TEST

short	myCallBack()
{
#ifdef _MACINTOSH_
	return Button();
#endif
#ifdef _WINDOWS_
   return (0);
#endif

}


void main(void)
{
	char	Choice[80];
	char	Choice2[30];
	char	Suggestion[256];
	char	Comment[256];
	void	*Speller;
	short	Result;
	long	Size;
	unsigned long	DictNum;

	WordInfo	theInfo;
	short		Auto;
	short		DictType;

	long		lastDict;
	long		lastType;
	char		lastWord[60];

#ifdef _MACINTOSH_
	StandardFileReply	reply;
	SFTypeList	types = {'mnD '};
#endif


	Speller = StartSpellCheckSession();


	for(;;)
	{
		printf("API Test\n\n");
		printf("1.  Open Dictionary\n");
		printf("2.  Close Dictionary\n");
		printf("3.  Check Word\n");
		printf("4.  Get First Suggestion\n");
		printf("5.  Get Next Suggestion\n");
		printf("6.  Find First Regular Expression\n");
		printf("7.  Find Next Regular Expression\n");
		printf("8.  Find Word\n");
		printf("9.  Find Next Word\n");
		printf("10. Current Word\n");
		printf("11. Add Word\n");
		printf("12. Fix Case\n");
		printf("0.  Quit\n");
		printf("\nSelection: ");

		gets(Choice);
		Result = atoi(Choice);
		printf("\n\n");

		switch(Result)
		{
			case 1:
#ifdef _MACINTOSH_
				StandardGetFile(nil, 1, types, &reply);
#endif
#ifdef _WINDOWS_
				printf("\nName of the Dictionary File:");
				gets(Choice);
#endif

				printf("\nSize: ");
				gets(Choice2);
				Size = atoi(Choice2);

				printf("AUTO_DICT             (1)");
				printf("\n SUGGEST_DICT       (2)");
				printf("\n DOCUMENT_DICT      (4)");
				printf("\n SKIP_DICT          (8)");
				printf("\n USER_DICT          (16)");
				printf("\n MAIN_DICT          (32)");

				printf("\nDictionary Type Number: ");
				gets(Choice2);
				DictType = atoi(Choice2);

				if (Size == 0)
				{	Size = 15;
					printf("\n 15 Buffers by default");
				}


					#ifdef _MACINTOSH_
				if (!reply.sfGood)
					if (DictOpen(Speller, &DictNum, DictType, Size, nil) != 0)
					#endif
					#ifdef _WINDOWS_ 
				if(1)
					if (DictOpen(Speller, &DictNum, DictType, Size, Choice) != 0)
					#endif
					{
						printf("\nThe dictionary number is: %ld\n",DictNum);
					} else
					{	printf("Unable to open dictionary\n");
					}
				#ifdef _MACINTOSH_
				else
					if (DictOpen(Speller, &DictNum, DictType, Size, &reply.sfFile))
					{
						printf("\nThe dictionary number is: %ld\n",DictNum);
					} else
					{	printf("Unable to open dictionary\n");
					}
				#endif
				break;

			case 2:
				printf("Dictionary Number to Close: ");
				gets(Choice);
				DictNum = atoi(Choice);
				DictClose(Speller, DictNum);
				break;

			case 3: 
				printf("Word to Check: ");
				gets(lastWord);
				printf("Dictionaries to check: ");
				gets(Choice2);
				lastDict = atoi(Choice2);
				printf("Type to check (return for all): ");
				gets(Choice2);
				lastType = atoi(Choice2);

				Size = CheckWord(Speller, lastDict, lastType, lastWord, &theInfo);
				if (Size)
				{	printf("\nFOUND: %s\n", lastWord);
					printf("Case: %d\n", theInfo.Case);
					printf("Duplicate: %d\n", theInfo.Duplicate);
					printf("Replace: %d\n", theInfo.Replace);
					printf("Errors: %d\n", GetSpellError());
				} else
				{	printf("\nDIDN'T FIND: %s\n", lastWord);
					printf("Case: %d\n", theInfo.Case);
					printf("Duplicate: %d\n", theInfo.Duplicate);
					printf("Replace: %d\n", theInfo.Replace);
					printf("Errors: %d\n", GetSpellError());

				}
				break;

			case 4:

				Size = FindFirstSuggestion(Speller, lastDict, lastType, lastWord, Suggestion, Comment, &Auto, &myCallBack);
				if (Size != 0)
				{	printf("Suggestion: %s\n", Suggestion);
					printf("Comment: %s\n", Comment);
					printf("Auto: %d\n", Auto);
					printf("Errors: %d\n", GetSpellError());

				} else
				{ 	printf("No Suggestions\n");
					printf("Errors: %d\n", GetSpellError());
				}
				break;

			case 5:
				Size = FindNextSuggestion(Speller, lastDict, lastType, lastWord, Suggestion, Comment, &Auto, &myCallBack);
				if (Size)
				{	printf("Suggestion: %s\n", Suggestion);
					printf("Comment: %s\n", Comment);
					printf("Auto: %d\n", Auto);
					printf("Errors: %d\n", GetSpellError());
				} else
				{ 	printf("No Suggestions\n");
					printf("Errors: %d\n", GetSpellError());
				}
				break;

			case 6:
				printf("Expression to Search: ");
				gets(Choice);
				printf("Dictionaries to check: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				printf("Type to check (0 for just number): ");
				gets(Choice2);
				DictType = atoi(Choice2);
				Size = FindFirstRegex(Speller, DictNum, DictType, Choice, &myCallBack);
				if (Size)
				{	printf("Suggestion: %s\n", Choice);
				} else
				{ 	printf("No Suggestions\n");
				}
				break;

			case 7:
				printf("(Make sure this is the same word as used on get first suggestion)\n");
				printf("Expression to Search: ");
				gets(Choice);
				printf("Dictionaries to check: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				printf("Type to check (0 for just number): ");
				gets(Choice2);
				DictType = atoi(Choice2);
				Size = FindNextRegex(Speller, DictNum, DictType, Choice, &myCallBack);
				if (Size)
				{	printf("Suggestion: %s\n", Choice);
				} else
				{ 	printf("No Suggestions\n");
				}
				break;

			case 8:
				printf("Word to Search for: ");
				gets(Choice);
				printf("Dictionaries to check: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				printf("Type to check (0 for just number): ");
				gets(Choice2);
				DictType = atoi(Choice2);
				Size = LocateWord(Speller, DictNum, DictType, Choice);
				if (Size)
				{	printf("Suggestion: %s\n", Choice);
				} else
				{ 	printf("No Suggestions\n");
				}
				break;

			case 9:
				printf("(Make sure this is the same word as used on get first suggestion)\n");
				printf("Word to Search for: ");
				gets(Choice);
				printf("Dictionaries to check: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				printf("Type to check (0 for just number): ");
				gets(Choice2);
				DictType = atoi(Choice2);
				Size = NextWord(Speller, DictNum, DictType, Choice);
				if (Size)
				{	printf("Suggestion: %s\n", Choice);
				} else
				{ 	printf("No Suggestions\n");
				}
				break;

			case 10:
				printf("Dictionaries to check: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				printf("Type to check (0 for just number): ");
				gets(Choice2);
				DictType = atoi(Choice2);
				Size = CurrentWord(Speller, DictNum, DictType, Choice);
				if (Size)
				{	printf("Suggestion: %s\n", Choice);
				} else
				{ 	printf("No Suggestions\n");
				}
				break;
			case 11:
				printf("Dictionary to add to: ");
				gets(Choice2);
				printf("Word to add: ");
				gets(Choice);
				DictNum = atoi(Choice2);
				printf("Suggestion: ");
				gets(Suggestion);
				printf("Comment: ");
				gets(Comment);
				Size = AddToDictionary(Speller, DictNum, Choice, Suggestion, Comment);
				break;
			case 12:
				printf("Word to convert: ");
				gets(Choice);
				printf("Case code: ");
				gets(Choice2);
				DictNum = atoi(Choice2);
				FixCase(Speller, Choice, DictNum);
				printf("\nWord: %s\n", Choice);
				break;
			case 0:
				printf("\nQuiting...");
				EndSpellCheckSession(Speller);
				exit(1);
		} // switch
	} // for

// This is called in case 0:
//	EndSpellCheckSession(Speller);
}

#endif





