// EdIRDict.cpp : implementation file
//

#include "stdafx.h"

#include "Defines.hpp"

#ifdef D_ED_IR_ACTIVE

#include "EdIRDict.hpp"

//////////////////////////////////////////////////////////////////
// class CPA_EdIR_WordEntry
//////////////////////////////////////////////////////////////////

/****************************************************************************/
CPA_EdIR_WordEntry::CPA_EdIR_WordEntry()
{
	m_csLanguage=C_INVALID_WORD;
	m_csWord=C_INVALID_LANGUAGE;
}

/****************************************************************************/
CPA_EdIR_WordEntry::CPA_EdIR_WordEntry(CString csWord,CString csLanguage)
{
	m_csWord=csWord;
	m_csLanguage=csLanguage;
}

/****************************************************************************/
CString CPA_EdIR_WordEntry::m_fn_csGetLanguage()
{
	ASSERT(M_LANGUAGE_IS_VALID(m_csLanguage));

	return m_csLanguage;
}

/****************************************************************************/
CString CPA_EdIR_WordEntry::m_fn_csGetWord()
{
	ASSERT(M_WORD_IS_VALID(m_csWord));

	return m_csWord;
}

/****************************************************************************/
void CPA_EdIR_WordEntry::m_fn_vSetLanguage(CString csLanguage)
{
	ASSERT(M_LANGUAGE_IS_VALID(csLanguage));
	ASSERT(M_LANGUAGE_IS_INVALID(m_csLanguage));

	m_csLanguage=csLanguage;
}

/****************************************************************************/
void CPA_EdIR_WordEntry::m_fn_vSetWord(CString csWord)
{
	ASSERT(M_WORD_IS_VALID(csWord));
	ASSERT(M_WORD_IS_INVALID(m_csWord));

	m_csWord=csWord;
}

//////////////////////////////////////////////////////////////////
// class CPA_EdIR_DictionnaryEntry
//////////////////////////////////////////////////////////////////

/****************************************************************************/
CPA_EdIR_DictionnaryEntry::CPA_EdIR_DictionnaryEntry(long lNbEntries)
{
	m_pclWordEntries=new CPA_EdIR_WordEntry[lNbEntries];

	m_csScriptName=C_INVALID_SCRIPTNAME;
	m_lId=C_INVALID_ID;

	m_lNbEntries=lNbEntries;
	m_lCurrentEntry=0;
//ANNECY CB
	memset(m_acFirstLetter, 0, 256 * sizeof(char));
	memset(m_acSecondLetter, 0, 256 * sizeof(char));
//END ANNECY
}

/****************************************************************************/
CPA_EdIR_DictionnaryEntry::~CPA_EdIR_DictionnaryEntry()
{
	delete[] m_pclWordEntries;
}

/****************************************************************************/
void CPA_EdIR_DictionnaryEntry::m_fn_vAddEntry(CString csWord,CString csLanguage)
{
	ASSERT(m_lCurrentEntry<m_lNbEntries);

//ANNECY CB
	m_acFirstLetter[toupper(((LPCSTR) csWord)[0])] = 1;
	m_acFirstLetter[tolower(((LPCSTR) csWord)[0])] = 1;
	m_acSecondLetter[toupper(((LPCSTR) csWord)[1])] = 1;
	m_acSecondLetter[tolower(((LPCSTR) csWord)[1])] = 1;
//END

	m_pclWordEntries[m_lCurrentEntry].m_fn_vSetWord(csWord);
	m_pclWordEntries[m_lCurrentEntry].m_fn_vSetLanguage(csLanguage);

	m_lCurrentEntry++;
}

/****************************************************************************/
CString CPA_EdIR_DictionnaryEntry::m_fn_csGetScriptName()
{
	ASSERT(M_SCRIPTNAME_IS_VALID(m_csScriptName));

	return m_csScriptName;
}

/****************************************************************************/
long CPA_EdIR_DictionnaryEntry::m_fn_lGetId()
{
	ASSERT(M_ID_IS_VALID(m_lId));

	return m_lId;
}

/****************************************************************************/
void CPA_EdIR_DictionnaryEntry::m_fn_vSetScriptName(CString csScriptName)
{
	ASSERT(M_SCRIPTNAME_IS_VALID(csScriptName));
	ASSERT(M_SCRIPTNAME_IS_INVALID(m_csScriptName));

	m_csScriptName=csScriptName;
}

/****************************************************************************/
void CPA_EdIR_DictionnaryEntry::m_fn_vSetId(long lId)
{
	ASSERT(M_ID_IS_VALID(lId));
	ASSERT(M_ID_IS_INVALID(m_lId));

	m_lId=lId;
}

/****************************************************************************/
CString	CPA_EdIR_DictionnaryEntry::m_fn_csGetName(CString csLanguage)
{
	long	lIndex=0;
	BOOL	bFound=FALSE;
	while(lIndex<m_lCurrentEntry && !bFound)
	{
		bFound=(csLanguage.CompareNoCase(m_pclWordEntries[lIndex].m_fn_csGetLanguage())==0);

		lIndex++;
	}

	if(bFound)
		return m_pclWordEntries[lIndex-1].m_fn_csGetWord();
	else
		return C_INVALID_WORD;
}

/****************************************************************************/
CString	CPA_EdIR_DictionnaryEntry::m_fn_csTranslate(CString csWord,CString csLanguage)
{
	//Looks for this word in this dictionnary entry
	BOOL	bWordFound=(csWord==C_INVALID_WORD);
	long	lIndex=0;
	while(lIndex<m_lCurrentEntry && !bWordFound)
	{
		bWordFound=(csWord.CompareNoCase(m_pclWordEntries[lIndex].m_fn_csGetWord())==0);

		lIndex++;
	}

	//Gets the corresponding word in the "csLanguage"
	if(bWordFound)
	{
		long	lIndex=0;
		BOOL	bFound=FALSE;
		while(lIndex<m_lCurrentEntry && !bFound)
		{
			bFound=(csLanguage.CompareNoCase(m_pclWordEntries[lIndex].m_fn_csGetLanguage())==0);

			lIndex++;
		}

		if(bFound)
			return m_pclWordEntries[lIndex-1].m_fn_csGetWord();
		else
			return C_INVALID_WORD;
	}
	else
		return C_INVALID_WORD;
}

/****************************************************************************/
//ANNECY CB
BOOL	CPA_EdIR_DictionnaryEntry::m_fn_bEntryExists(CString &csWord,CString &csLanguage)
//BOOL	CPA_EdIR_DictionnaryEntry::m_fn_bEntryExists(CString csWord,CString csLanguage)
//END
{
//ANNECY CB
	LPCSTR	pszWord = (LPCSTR) csWord, pszLanguage = (LPCSTR) csLanguage;
//END
	//Looks for this (word,language) in this dictionnary entry
	BOOL	bFound=(csWord=="");
	long	lIndex=0;
//ANNECY CB
	while(lIndex<m_lCurrentEntry && !bFound)
	{
		if(!strcmpi(pszWord, (LPCSTR) m_pclWordEntries[lIndex].m_csWord))
			if(!strcmpi(pszLanguage, (LPCSTR) m_pclWordEntries[lIndex].m_csLanguage))
				return TRUE;
//		bFound=(csWord.CompareNoCase(m_pclWordEntries[lIndex].m_fn_csGetWord())==0) &&
//					 (csLanguage.CompareNoCase(m_pclWordEntries[lIndex].m_fn_csGetLanguage())==0);
		lIndex++;
	}
//END

	return bFound;
}

//////////////////////////////////////////////////////////////////
// class CPA_EdIR_Dictionary
//////////////////////////////////////////////////////////////////

typedef CPA_EdIR_DictionnaryEntry *CPA_EdIR_DictionnaryEntryPointer;

/****************************************************************************/
CPA_EdIR_Dictionary::CPA_EdIR_Dictionary(long lNbDictionnaryEntries,long lNbLanguages)
{
	m_ppclDictionnaryEntry=new CPA_EdIR_DictionnaryEntryPointer[lNbDictionnaryEntries];

	for(long lIndex=0;lIndex<lNbDictionnaryEntries;lIndex++)
		m_ppclDictionnaryEntry[lIndex]=new CPA_EdIR_DictionnaryEntry(lNbLanguages);

	m_lNbEntries=lNbDictionnaryEntries;
	m_lCurrentEntry=0;

	m_pstCouple=NULL;
	m_csOldLanguage1="";
	m_csOldLanguage2="";
//ANNECY CB
	memset(m_acFirstLetter, 0, 256 * sizeof(char));
	memset(m_acSecondLetter, 0, 256 * sizeof(char));
//END ANNECY
}

/****************************************************************************/
CPA_EdIR_Dictionary::~CPA_EdIR_Dictionary()
{
	for(long lIndex=0;lIndex<m_lNbEntries;lIndex++)
		delete[] m_ppclDictionnaryEntry[lIndex];

	delete[] m_ppclDictionnaryEntry;

	if(m_pstCouple)
		delete[] m_pstCouple;
}

/****************************************************************************/
long CPA_EdIR_Dictionary::m_fn_lGetNbEntries()
{
	return m_lNbEntries;
}

/****************************************************************************/
void CPA_EdIR_Dictionary::m_fn_vAddEntry(CString csScriptName,long lId,CString csWord,CString csLanguage)
{
	//Looks for this word (with this lId) in the dictionnary
	long	lIndex=0;
	BOOL	bFound=FALSE;
//ANNECY CB
	m_acFirstLetter[toupper(((LPCSTR) csWord)[0])] = 1;
	m_acFirstLetter[tolower(((LPCSTR) csWord)[0])] = 1;
	m_acSecondLetter[toupper(((LPCSTR) csWord)[1])] = 1;
	m_acSecondLetter[tolower(((LPCSTR) csWord)[1])] = 1;
//END
	while(lIndex<m_lCurrentEntry && !bFound)
	{
		bFound=(lId==m_ppclDictionnaryEntry[lIndex]->m_fn_lGetId());

		lIndex++;
	}

	//Adds the entry
	if(bFound)
	{
		m_ppclDictionnaryEntry[lIndex-1]->m_fn_vAddEntry(csWord,csLanguage);
	}
	else
	{
		ASSERT(m_lCurrentEntry<m_lNbEntries);

		m_ppclDictionnaryEntry[m_lCurrentEntry]->m_fn_vAddEntry(csWord,csLanguage);
		m_ppclDictionnaryEntry[m_lCurrentEntry]->m_fn_vSetId(lId);
		m_ppclDictionnaryEntry[m_lCurrentEntry]->m_fn_vSetScriptName(csScriptName);

		m_lCurrentEntry++;
	}
}

/****************************************************************************/
//ANNECY CB
long CPA_EdIR_Dictionary::m_fn_lGetId(CString &csWord,CString &csLanguage)
//long CPA_EdIR_Dictionary::m_fn_lGetId(CString csWord,CString csLanguage)
//END
{
	//Looks for this (word,language) in the dictionnary
	long	lIndex=0;
	BOOL	bFound=FALSE;
//ANNECY CB
	LPCSTR pcsWord = (LPCSTR) csWord;
	if(m_acFirstLetter[pcsWord[0]] == 0)
		return C_INVALID_ID;
	if(m_acSecondLetter[pcsWord[1]] == 0)
		return C_INVALID_ID;
//END

	while(lIndex<m_lCurrentEntry && !bFound)
	{
//ANNECY CB
		if((m_ppclDictionnaryEntry[lIndex]->m_acFirstLetter[pcsWord[0]])
			&& (m_ppclDictionnaryEntry[lIndex]->m_acSecondLetter[pcsWord[1]]))
//END
		bFound=m_ppclDictionnaryEntry[lIndex]->m_fn_bEntryExists(csWord,csLanguage);

		lIndex++;
	}

	if(bFound)
		return m_ppclDictionnaryEntry[lIndex-1]->m_fn_lGetId();
	else
		return C_INVALID_ID;
}

/****************************************************************************/
//ANNECY CB
CString CPA_EdIR_Dictionary::m_fn_csGetWord(long lId,CString &csLanguage)
//CString CPA_EdIR_Dictionary::m_fn_csGetWord(long lId,CString csLanguage)
//END
{
	//Looks for this "lId" in the dictionnary
	long	lIndex=0;
	BOOL	bFound=FALSE;
	while(lIndex<m_lCurrentEntry && !bFound)
	{
		bFound=(lId==m_ppclDictionnaryEntry[lIndex]->m_fn_lGetId());

		lIndex++;
	}

	if(bFound)
		return m_ppclDictionnaryEntry[lIndex-1]->m_fn_csGetName(csLanguage);
	else
		return C_INVALID_WORD;
}

/****************************************************************************/
CString CPA_EdIR_Dictionary::m_fn_csTranslate(CString csWord,CString csLanguage)
{
	CString	csTranslation=C_INVALID_WORD;
	long		lIndex=0;
	while((lIndex<m_lCurrentEntry) && M_WORD_IS_INVALID(csTranslation))
	{
		csTranslation=m_ppclDictionnaryEntry[lIndex]->m_fn_csTranslate(csWord,csLanguage);

		lIndex++;
	}

	return csTranslation;
}

/****************************************************************************/
int CPA_EdIR_Dictionary::m_fn_iCompareNoCase(const void *pcsWord1,const void *pcsWord2)
{
	return ((CString *)pcsWord1)->CompareNoCase(*((CString *)pcsWord2));
}

/****************************************************************************/
void CPA_EdIR_Dictionary::m_fn_vInitFastTranslation(CString csLanguage1,CString csLanguage2)
{
	if((m_csOldLanguage1.CompareNoCase(csLanguage1)!=0) ||
		 (m_csOldLanguage2.CompareNoCase(csLanguage2)!=0))
	{
		m_csOldLanguage1=csLanguage1;
		m_csOldLanguage2=csLanguage2;

		if(m_pstCouple)
			delete[] m_pstCouple;

		m_pstCouple=new CPA_EdIR_stCouple[m_lNbEntries];
		for(long lIndex=0;lIndex<m_lNbEntries;lIndex++)
		{
			m_pstCouple[lIndex].csWord=m_ppclDictionnaryEntry[lIndex]->m_fn_csGetName(csLanguage1);
			m_pstCouple[lIndex].csTranslatedWord=m_ppclDictionnaryEntry[lIndex]->m_fn_csGetName(csLanguage2);
		}

		qsort(m_pstCouple,m_lNbEntries,sizeof(CPA_EdIR_stCouple),m_fn_iCompareNoCase);
	}
}

/****************************************************************************/
CString	CPA_EdIR_Dictionary::m_fn_csFastTranslate(CString csWord)
{
	CPA_EdIR_stCouple	*pstCouple;

	pstCouple=(CPA_EdIR_stCouple *)bsearch((void *)(&csWord),m_pstCouple,m_lNbEntries,sizeof(CPA_EdIR_stCouple),m_fn_iCompareNoCase);

	if(pstCouple!=NULL)
		return pstCouple->csTranslatedWord;
	else
		return C_INVALID_WORD;
}

#endif //D_ED_IR_ACTIVE
