#include "Spell.h"


SpellClass::SpellClass()
	: CRegex(), CPhoneme(), CCase()
{
	char *copyright = "SpellWright Copyright 1996 by LexTek International (801) 375-8332; (801) 377-7654 FAX";
	char *copyright2 = "LexTek International 2255N University Parkway, Suite 15, Provo UT 84604";
	char *copyright3 = "LexTek International - producer of quality linguistical and textual toolkits";
	magic = DICTMAGIC;
	NumDictionaries = 0;
	Dictionaries = NULL;
	DictTypeFound = 0;
	DictsSearched = 0;
	DictSearching = 0;
	theDocDict = NULL;
	theDocNum = 0;
	LastWord[0] = '\0';
	DupDict = new UBloom(100, 25, By_Key);
	copyright = copyright;
	copyright2 = copyright2;
	copyright3 = copyright3;
}

SpellClass::~SpellClass()
{
	// I suspect we need to add some code to delete any
	// open dictionaries here.
	delete DupDict;
}

short
SpellClass::CheckDup(char *Word)
{
	if (DupDict->Test(Word, strlen(Word)))
	{	return TRUE;	// duplicate Word
	} else
	{	DupDict->Insert(Word, strlen(Word));
		return FALSE;
	}
}

void
SpellClass::ClearDup()
{
	DupDict->Reset();
}

CDict
* SpellClass::FindDict(unsigned long *DictNum, short *DictType)
{
	DictList *temp = Dictionaries;
  	unsigned long	theNum = (*DictNum & ~(DictsSearched));

	if (*DictType != 0)	// search only by type
	{  // !( (temp->DictType == *DictType) (AP 10/10/96)
		while ( ( temp != NULL ) && !( (temp->DictType & *DictType) && (temp->DictNum & ~DictsSearched ) ))		{
			temp = temp->next;
		}
	} else
	{
		while (( temp != NULL) && ((temp->DictNum & *DictNum)== 0))
		{
			temp = temp->next;
		}
	}


	if (temp == NULL)
	{	*DictType = 0;
		*DictNum = 0;
		return NULL;
	}
	else  {
		*DictType = temp->DictType;
		*DictNum = temp->DictNum;
		return temp->Dictionary;
	}
}




void
SpellClass::AddDict(unsigned long *DictNum, short DictType, long NumBuffers, FioParam * theFile)
{	
	if ((DictType == DOCUMENT_DICT) && (theDocNum != 0))
	{	*DictNum = theDocNum;
		return;
	}


	// this makes a number with each bit representing a 'used' dictionary number
	
	unsigned long	Number = 0;
	DictList *temp = Dictionaries;
	
	while ( temp != NULL)
	{	Number = Number | temp->DictNum;	// add the dict nums (bit add)
		temp = temp->next;
	}
	
	// this finds a Dict Num that is unused by examining all the bits
	// that are used.
	// Number = all the bits used
	
	*DictNum = 1;
	while ( (*DictNum <= MAXlong) && (*DictNum & Number) )
	{	*DictNum = *DictNum * 2;	// shift to next bit
	}
	
	if ( (*DictNum & Number))
	{	*DictNum = 0;
		return;
	}
	
	// create a new dict
	DictList *NewDict = (DictList*) malloc(sizeof( DictList));
	
	if (DictType == DOCUMENT_DICT)
	{
		theDocDict = new CDocDict(NumBuffers, theFile);
		NewDict->Dictionary = theDocDict;
		theDocNum = *DictNum;
	
	} else if (DictType == MAIN_DICT)
	{	NewDict->Dictionary = new CQCheck(NumBuffers, theFile);
	} else if (DictType == USER_DICT)
	{	NewDict->Dictionary = new CQCUser(NumBuffers, theFile);
	} else if (DictType == SKIP_DICT)
	{	NewDict->Dictionary = new CSkipDict(NumBuffers, theFile);
	} else if (DictType == AUTO_DICT)
	{	NewDict->Dictionary = new CSugDict(NumBuffers, theFile);
	} else if (DictType == SUGGEST_DICT)
	{	NewDict->Dictionary = new CSugDict(NumBuffers, theFile);
	}

	if (NewDict->Dictionary == NULL)
	{	ErrorFunc(eNo_Mem, SET);
		return;
	}
	
	NewDict->DictNum = *DictNum;
	NewDict->DictType = DictType;
	temp = Dictionaries;
	
	// check for empty list
	if (temp == NULL)
	{	Dictionaries = NewDict;
		NewDict->next = NULL;
		NumDictionaries++;
		return;
	}
	
	NewDict->next = Dictionaries;
	Dictionaries = NewDict;
	NumDictionaries++;
	return;
}

void 
SpellClass::DeleteDict(unsigned long DictNum)
{
	if (DictNum == theDocNum)
	{	theDocDict = NULL;
		theDocNum = 0;
	}


	DictList *temp = Dictionaries;
	DictList *temp2;
	
	// check head
	if ((Dictionaries != NULL ) && (temp->DictNum & DictNum))
	{	Dictionaries = temp->next;
		delete(((CMainDict *)temp->Dictionary));
		free(temp);
		NumDictionaries--;
		return;
	}

	while ( temp->next != NULL)
	{	
		if (temp->next->DictNum & DictNum)	{	
			temp2 = temp->next->next;
			delete(((CMainDict *)temp->next->Dictionary));
			free(temp->next);
			temp->next = temp2;
			NumDictionaries--;
		} else
			temp = temp->next;
	}
}


