/*******************************************************************************
;*******************************************************************************
;**                                                                           **
;**                  COPYRIGHT 1998-2012 NUANCE COMMUNICATIONS                **
;**                                                                           **
;**               NUANCE COMMUNICATIONS PROPRIETARY INFORMATION               **
;**                                                                           **
;**     This software is supplied under the terms of a license agreement      **
;**     or non-disclosure agreement with Nuance Communications and may not    **
;**     be copied or disclosed except in accordance with the terms of that    **
;**     agreement.                                                            **
;**                                                                           **
;*******************************************************************************
;**                                                                           **
;**     FileName: et9sym.c                                                    **
;**                                                                           **
;**  Description: T9 symbol information.                                      **
;**                                                                           **
;*******************************************************************************
;******* 10 ****** 20 ****** 30 ****** 40 ****** 50 ****** 60 ****** 70 *******/

/*! \addtogroup et9sym Symbol Handling for XT9
* Symbol handling for generic XT9.
* @{
*/

#include "et9api.h"
#include "et9sym.h"
#include "et9misc.h"
#include "et9kbdef.h"

#ifdef ET9SYMBOLENCODING_UNICODE
#ifdef _WIN32
#pragma message ("*** Symbol encoding: Unicode")
#endif
#endif
#ifdef ET9SYMBOLENCODING_SHIFTJIS
#ifdef _WIN32
#pragma message ("*** Symbol encoding: Shift-Jis")
#endif
#endif

#include "et9charprop.c"


/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                     
 *
 *                                       
 *
 *                             
 */

ET9SymbClass ET9FARCALL _ET9_GetSymbolClass (const ET9SYMB sSymb);

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                              
 *
 *                                       
 *                                                           
 *
 *                                               
 */

ET9SYMB ET9FARCALL _ET9SymToLower (const ET9SYMB sSymb, const ET9U32 dwLdbNum);

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                              
 *
 *                                       
 *                                                           
 *
 *                                               
 */

ET9SYMB ET9FARCALL _ET9SymToUpper (const ET9SYMB sSymb, const ET9U32 dwLdbNum);

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                             
 *
 *                                       
 *                                                           
 *
 *                                                                                                      
 */

ET9BOOL ET9FARCALL _ET9SymIsLower(const ET9SYMB sSymb, const ET9U32 dwLdbNum)
{
    const ET9SYMB sUpper = _ET9SymToUpper(sSymb, dwLdbNum);

    return (ET9BOOL)(sUpper != sSymb);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                             
 *
 *                                       
 *                                                           
 *
 *                                                                                                      
 */

ET9BOOL ET9FARCALL _ET9SymIsUpper(const ET9SYMB sSymb, const ET9U32 dwLdbNum)
{
    const ET9SYMB sLower = _ET9SymToLower(sSymb, dwLdbNum);

    return (ET9BOOL)(sLower != sSymb);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                
 *
 *                                       
 *                                                           
 *
 *                                 
 */

ET9SYMB ET9FARCALL _ET9SymToOther(const ET9SYMB sSymb, const ET9U32 dwLdbNum)
{
    const ET9SYMB sLower = _ET9SymToLower(sSymb, dwLdbNum);

    if (sLower != sSymb) {
        return sLower;
    }

    return _ET9SymToUpper(sSymb, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                               
 *            
 *
 *                                                  
 *                                                                             
 *                                                                               
 *
 *                                                                                                                         
 */

ET9BOOL ET9FARCALL _ET9_GetFullSymbolKeyAndClass(const ET9SYMB      sSymb,
                                                 ET9U8      * const pbKey,
                                                 ET9U8      * const pbClass)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    if (pbKey) {
        *pbKey = 0;
    }

    if (pbClass) {
        *pbClass = (ET9U8)eClass;
    }

    return (ET9BOOL)(eClass != ET9_WhiteSymbClass && eClass != ET9_UnassSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                
 *
 *                                          
 *
 *                                             
 */

ET9BOOL ET9FARCALL _ET9_IsUnknown(const ET9SYMB sSymb)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    return (ET9BOOL)(eClass == ET9_UnassSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                   
 *
 *                                          
 *
 *                                                
 */

ET9BOOL ET9FARCALL _ET9_IsWhiteSpace(const ET9SYMB sSymb)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    return (ET9BOOL)(eClass == ET9_WhiteSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                                
 *
 *                                          
 *
 *                                                
 */

ET9BOOL ET9FARCALL _ET9_IsContextBreakChar(const ET9SYMB sSymb)
{
    return (ET9BOOL)(sSymb == 0x0A ||
                    sSymb == 0x0D ||
                    sSymb == 0x85 ||
                    sSymb == 0x2028 ||
                    sSymb == 0x2029);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                    
 *
 *                                          
 *
 *                                                 
 */

ET9BOOL ET9FARCALL _ET9_IsPunctChar(const ET9SYMB sSymb)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    return (ET9BOOL)(eClass == ET9_PunctSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                
 *
 *                                          
 *
 *                                             
 */

ET9BOOL ET9FARCALL _ET9_IsNumeric(const ET9SYMB sSymb)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    return (ET9BOOL)(eClass == ET9_NumbrSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                               
 *
 *                                          
 *
 *                                                            
 */

ET9BOOL ET9FARCALL _ET9_IsPunctOrNumeric(const ET9SYMB sSymb)
{
    const ET9SymbClass eClass = _ET9_GetSymbolClass(sSymb);

    return (ET9BOOL)(eClass == ET9_PunctSymbClass || eClass == ET9_NumbrSymbClass);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                    
 *
 *                                            
 *                                        
 *
 *                                                 
 */

ET9BOOL ET9FARCALL _ET9_IsNumericString(ET9SYMB       const * const psString,
                                        const ET9UINT               nStrLen)
{
    ET9UINT nCount;
    ET9SYMB const * psSymb;

    if (!nStrLen) {
        return 0;
    }

    psSymb = psString;
    for (nCount = nStrLen; nCount; --nCount, ++psSymb) {
        if (!_ET9_IsNumeric(*psSymb)) {
            return 0;
        }
    }

    return 1;
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                   /                                   
 *
 *                                            
 *                                        
 *
 *                           /                                        
 */

ET9BOOL ET9FARCALL _ET9FindSpacesAndUnknown(ET9SYMB       const * const psString,
                                            const ET9UINT               nStrLen)
{
    ET9UINT nCount;
    ET9SYMB const * psSymb;

    ET9Assert(psString);

    psSymb = psString;
    for (nCount = nStrLen; nCount; --nCount, ++psSymb) {

        const ET9SymbClass eClass = _ET9_GetSymbolClass(*psSymb);

        if (eClass == ET9_WhiteSymbClass || eClass == ET9_UnassSymbClass) {
            return 1;
        }

        /* special check for NULL symbs */

        if (!*psSymb) {
            return 1;
        }
    }

    return 0;
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                   
 *
 *                                            
 *                                        
 *
 *                                                      
 */

ET9BOOL ET9FARCALL _ET9StringLikelyURL(ET9SYMB       const * const psString,
                                       const ET9UINT               nStrLen)
{
    const ET9UINT nLastLen = __ET9Min(4, nStrLen);

    ET9UINT nIndex;
    ET9U32 dwHashValue = 0;

    for (nIndex = 0; nIndex < nLastLen; ++nIndex) {

        dwHashValue = _ET9SymToLower(psString[nIndex], 0) + (65599 * dwHashValue);

        switch (nIndex + 1)
        {
            case 3:
                switch (dwHashValue)
                {
                    case 850283106U:    /* ftp */
                        return 1;
                }
                break;

            case 4:
                switch (dwHashValue)
                {
                    case 542634248U:    /* http */
                    case 3686488887U:   /* www. */
                        return 1;
                }
                break;
        }
    }

    return 0;
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                            
 *
 *                                                                                                          
 *
 *                                            
 *                                        
 *
 *                                                               
 */

ET9BOOL ET9FARCALL _ET9StringLikelyPhoneNumber(ET9SYMB       const * const psString,
                                               const ET9UINT               nStrLen)
{
    ET9UINT nLparCount = 0;
    ET9UINT nFirstLparIndex = 0;
    ET9UINT nRparCount = 0;
    ET9UINT nFirstRparIndex = 0;
    ET9UINT nHyphenCount = 0;
    ET9UINT nFirstHyphenIndex = 0;
    ET9UINT nPeriodCount = 0;
    ET9UINT nFirstPeriodIndex = 0;
    ET9UINT nPlusCount = 0;
    ET9UINT nFirstPlusIndex = 0;
    ET9UINT nAlphaCount = 0;
    ET9UINT nFirstAlphaIndex = 0;
    ET9UINT nDigitCount = 0;
    ET9UINT nFirstDigitIndex = 0;

    ET9UINT nIndex;

    if (nStrLen < 7) {
        return 0;
    }

    for (nIndex = 0; nIndex < nStrLen; ++nIndex) {

        const ET9SYMB sSymb = psString[nIndex];

        switch (sSymb)
        {
            case '(':
                if (!nLparCount++) {
                    nFirstLparIndex = nIndex;
                }
                break;
            case ')':
                if (!nRparCount++) {
                    nFirstRparIndex = nIndex;
                }
                break;
            case '.':
                if (!nPeriodCount++) {
                    nFirstPeriodIndex = nIndex;
                }
                break;
            case '-':
                if (!nHyphenCount++) {
                    nFirstHyphenIndex = nIndex;
                }
                break;
            case '+':
                if (!nPlusCount++) {
                    nFirstPlusIndex = nIndex;
                }
                break;

            default:

                if (sSymb >= '0' && sSymb <= '9') {
                    if (!nDigitCount++) {
                        nFirstDigitIndex = nIndex;
                    }
                }
                else if (sSymb >= 'A' && sSymb <= 'Z') {
                    if (!nAlphaCount++) {
                        nFirstAlphaIndex = nIndex;
                    }
                }
                else {
                    return 0;
                }
        }
    }

    if (nDigitCount < 3) {
        return 0;
    }

    if (nAlphaCount > 7) {
        return 0;
    }

    if (nAlphaCount && nFirstAlphaIndex < nFirstDigitIndex) {
        return 0;
    }

    if (nPlusCount > 1 || nFirstPlusIndex > 0) {
        return 0;
    }

    if (nLparCount != nRparCount || nLparCount > 1 || nFirstLparIndex > nFirstRparIndex || nFirstLparIndex > 2 || (nLparCount && (nFirstRparIndex - nFirstLparIndex) != 4)) {
        return 0;
    }

    if (nPeriodCount > 3 || nHyphenCount > 3 || (nPeriodCount && nHyphenCount)) {
        return 0;
    }

    return 1;
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                        
 *                                                            
 *                                                                                  
 *
 *                                            
 *                                        
 *
 *                                                         
 */

ET9BOOL ET9FARCALL _ET9StringLikelyEmoticon(ET9SYMB       const * const psString,
                                            const ET9UINT               nStrLen)
{
    ET9UINT nCount;
    ET9UINT nAlphaCount;
    ET9SYMB const * psSymb;

    nAlphaCount = 0;

    psSymb = psString;
    for (nCount = nStrLen; nCount; --nCount, ++psSymb) {

        switch (_ET9_GetSymbolClass(*psSymb))
        {
            case ET9_WhiteSymbClass:
            case ET9_UnassSymbClass:
                return 0;
            case ET9_AlphaSymbClass:
                ++nAlphaCount;
                break;
            case ET9_PunctSymbClass:
            case ET9_NumbrSymbClass:
                break;
            default:
                ET9Assert(0);
                continue;
        }
    }

    return (ET9BOOL)((nStrLen > 1) && (2 * nAlphaCount) <= nStrLen);
}

/*---------------------------------------------------------------------------*/
/**
 * If the symbol is a SHIFTED symbol, convert to lower case.
 * Given a character return the lower case version.  If the input character is already
 * lower case, or has no case variant, then the input will be returned as output.
 *
 * @param sData             Symbol to check.
 * @param dwLdbNum          Relevant language source for symbol.
 *
 * @return Symbol of lower case.
 */

ET9SYMB ET9FARCALL ET9SymToLower(const ET9SYMB sData, const ET9U32 dwLdbNum)
{
    return _ET9SymToLower(sData, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/**
 * If the symbol is lower case, convert to upper case.
 * Given a character return the upper case version.  If the input character is already
 * lower case, or has no case variant, then the input will be returned as output.
 *
 * @param sData             Symbol to check.
 * @param dwLdbNum          Relevant language source for symbol.
 *
 * @return Symbol of upper case.
 */

ET9SYMB ET9FARCALL ET9SymToUpper(const ET9SYMB sData, const ET9U32 dwLdbNum)
{
    return _ET9SymToUpper(sData, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/**
 * Return symbol of opposite case.
 * Given a character return the other case version.  If the input character
 * has no case variant, then the input will be returned as output.
 *
 * @param sData             Symbol to check.
 * @param dwLdbNum          Relevant language source for symbol.
 *
 * @return Symbol of other case.
 */

ET9SYMB ET9FARCALL ET9SymToOther(const ET9SYMB sData, const ET9U32 dwLdbNum)
{
    return _ET9SymToOther(sData, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/**
 * Check if the symbol is an upper case symbol.
 *
 * @param sData             Symbol to check.
 * @param dwLdbNum          Relevant language source for symbol.
 *
 * @return Non zero is upper case, otherwise zero.
 */

ET9UINT ET9FARCALL ET9SymIsUpper(const ET9SYMB sData, const ET9U32 dwLdbNum)
{
    return (ET9UINT)_ET9SymIsUpper(sData, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/**
 * Check if the symbol is a lower case symbol.
 *
 * @param sData             Symbol to check.
 * @param dwLdbNum          Relevant language source for symbol.
 *
 * @return Non zero is lower case, otherwise zero.
 */

ET9UINT ET9FARCALL ET9SymIsLower(const ET9SYMB sData, const ET9U32 dwLdbNum)
{
    return (ET9UINT)_ET9SymIsLower(sData, dwLdbNum);
}

/*---------------------------------------------------------------------------*/
/**
 * Get the character class of a symbol.
 *
 * @param sData             Character to classify.
 *
 * @return Character class, ET9SYMWHITE, ET9SYMPUNCT, ET9SYMNUMBR, ET9SYMALPHA, ET9SYMUNKN.
 */

ET9U8 ET9FARCALL ET9GetSymbolClass(const ET9SYMB sData)
{
    ET9Assert(ET9SYMWHITE == ET9_WhiteSymbClass);
    ET9Assert(ET9SYMPUNCT == ET9_PunctSymbClass);
    ET9Assert(ET9SYMNUMBR == ET9_NumbrSymbClass);
    ET9Assert(ET9SYMALPHA == ET9_AlphaSymbClass);
    ET9Assert(ET9SYMUNKN  == ET9_UnassSymbClass);

    return (ET9U8)_ET9_GetSymbolClass(sData);
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                               
 *
 *                                             
 *
 *                                                  
 */

ET9BOOL ET9FARCALL ET9IsFunctionKeySymbol(const ET9SYMB sSymb)
{
    /* speed up */

    if (sSymb > 0x20 && sSymb <= 0xFF) {
        return 0;
    }

    /* check */

    switch (sSymb)
    {
        case ET9KEY_BACK:
        case ET9KEY_TAB:
        case ET9KEY_NEW_LINE:
        case ET9KEY_RETURN:
        case ET9KEY_SPACE:

        case ET9KEY_RELOAD:
        case ET9KEY_OK:
        case ET9KEY_CANCEL:
        case ET9KEY_LEFT:
        case ET9KEY_UP:
        case ET9KEY_RIGHT:
        case ET9KEY_DOWN:
        case ET9KEY_PREVTAB:
        case ET9KEY_CLEAR:
        case ET9KEY_CLOSE_SEL_LIST:
        case ET9KEY_MENU:
        case ET9KEY_SHIFT:
        case ET9KEY_CONTROL:
        case ET9KEY_ALT:
        case ET9KEY_PAUSE:
        case ET9KEY_CAPS_LOCK:
        case ET9KEY_OPTION:
        case ET9KEY_EMOTICON:
        case ET9KEY_ACCENTEDLAYOUT:
        case ET9KEY_SYMBOLLAYOUT:
        case ET9KEY_MAINLAYOUT:
        case ET9KEY_MULTITAP:
        case ET9KEY_ESCAPE:
        case ET9KEY_PRIOR:
        case ET9KEY_NEXT:
        case ET9KEY_END:
        case ET9KEY_HOME:
        case ET9KEY_DIGITLAYOUT:
        case ET9KEY_PUNCTLAYOUT:
        case ET9KEY_LANGUAGE:
        case ET9KEY_UNDO:
        case ET9KEY_REDO:
        case ET9KEY_HIDE:
        case ET9KEY_COMMAND:
        case ET9KEY_WINDOWS:

        case ET9KEY_SOFT1:
        case ET9KEY_SOFT2:
        case ET9KEY_SOFT3:
        case ET9KEY_SOFT4:

        case ET9KEY_OEMLAYOUT1:
        case ET9KEY_OEMLAYOUT2:
        case ET9KEY_OEMLAYOUT3:
        case ET9KEY_OEMLAYOUT4:

        case ET9KEY_OEM_01:
        case ET9KEY_OEM_02:
        case ET9KEY_OEM_03:
        case ET9KEY_OEM_04:
        case ET9KEY_OEM_05:
        case ET9KEY_OEM_06:
        case ET9KEY_OEM_07:
        case ET9KEY_OEM_08:
        case ET9KEY_OEM_09:
        case ET9KEY_OEM_0A:
        case ET9KEY_OEM_0B:
        case ET9KEY_OEM_0C:
        case ET9KEY_OEM_0D:
        case ET9KEY_OEM_0E:
        case ET9KEY_OEM_0F:
        case ET9KEY_OEM_10:
        case ET9KEY_OEM_11:
        case ET9KEY_OEM_12:
        case ET9KEY_OEM_13:
        case ET9KEY_OEM_14:
        case ET9KEY_OEM_15:
        case ET9KEY_OEM_16:
        case ET9KEY_OEM_17:
        case ET9KEY_OEM_18:
        case ET9KEY_OEM_19:
        case ET9KEY_OEM_1A:
        case ET9KEY_OEM_1B:
        case ET9KEY_OEM_1C:
        case ET9KEY_OEM_1D:
        case ET9KEY_OEM_1E:
        case ET9KEY_OEM_1F:

        case ET9KEY_RSV_1:
        case ET9KEY_RSV_2:
        case ET9KEY_RSV_3:
        case ET9KEY_RSV_4:
            return 1;
        default:
            return 0;
    }
}

#ifdef ET9_DEBUG

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *          
 */

ET9SYMBOL_ENCODING ET9SymbolEncodingQA = ET9SYMBOL_ENCODING_LAST;

#endif

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                 
 *                                     
 *                                        
 *
 *                                 
 */

ET9SYMBOL_ENCODING ET9FARCALL ET9_GetSymbolEncoding(void)
{
#ifdef ET9_DEBUG
    if (ET9SymbolEncodingQA < ET9SYMBOL_ENCODING_LAST) {
        return ET9SymbolEncodingQA;
    }
#endif

#ifdef ET9SYMBOLENCODING_UNICODE
    return ET9SYMBOL_ENCODING_UNICODE;
#endif
#ifdef ET9SYMBOLENCODING_SHIFTJIS
    return ET9SYMBOL_ENCODING_SHIFTJIS;
#endif
}

#ifdef ET9_DEBUG

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                      
 *
 *                                             
 *                                             
 *
 *                                                       
 */

ET9BOOL ET9FARCALL _ET9IsCaseExceptionChar(const ET9SYMB sSymbA, const ET9SYMB sSymbB)
{
    if (sSymbA == 0x131 || sSymbB == 0x131) {
        return 1;
    }

    return 0;
}

#endif

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                             
 *
 *                                                   
 *
 *                                                        
 */

ET9SYMB const * ET9FARCALL _ET9_GetAltCharsLower(const ET9SYMB sChar)
{
    static const ET9SYMB psAltCharTable[] = {
        0x03b1,0x03ac,0x0000,0x03b5,0x03ad,0x0000,0x03b7,0x03ae,0x0000,0x03b9,0x03af,0x03ca,0x0390,0x0000,0x03bf,0x03cc,0x0000,0x03c5,0x03cd,0x03cb,0x03b0,0x0000,0x03c9,0x03ce,0x0000,0x0915,0x0958,0x0000,0x0916,0x0959,0x0000,0x0917,0x095a,0x0000,0x091c,0x095b,0x0000,0x0921,0x095c,0x0000,0x0922,0x095d,0x0000,0x092b,0x095e,0x0000,0x092f,0x095f,0x0000,0x0061,0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x0101,0x0103,0x0105,0x0000,0x0062,0x0253,0x0000,
        0x0063,0x00e7,0x0107,0x0109,0x010b,0x010d,0x0000,0x0064,0x00f0,0x010f,0x0111,0x0257,0x0000,0x0065,0x00e8,0x00e9,0x00ea,0x00eb,0x0113,0x0115,0x0117,0x0119,0x011b,0x025b,0x1eb9,0x0000,0x0066,0x0192,0x0000,0x0067,0x011d,0x011f,0x0121,0x0123,0x0000,0x0068,0x0125,0x0127,0x0000,0x0069,0x00ec,0x00ed,0x00ee,0x00ef,0x0129,0x012b,0x012d,0x012f,0x0131,0x0133,0x1ecb,0x0000,0x006a,0x0135,0x0000,0x006b,0x0137,0x0138,0x0199,0x0000,0x006c,0x013a,0x013c,0x013e,
        0x0140,0x0142,0x0000,0x006e,0x00f1,0x0144,0x0146,0x0148,0x0149,0x014b,0x1e45,0x0000,0x006f,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f8,0x014d,0x014f,0x0151,0x0153,0x01a1,0x0254,0x1ecd,0x0000,0x0072,0x0155,0x0157,0x0159,0x0000,0x0073,0x00df,0x015b,0x015d,0x015f,0x0161,0x017f,0x1e63,0x0000,0x0074,0x00fe,0x0163,0x0165,0x0167,0x0000,0x0075,0x00f9,0x00fa,0x00fb,0x00fc,0x0169,0x016b,0x016d,0x016f,0x0171,0x0173,0x01b0,0x1ee5,0x0000,0x0077,0x0175,0x0000,
        0x0079,0x00fd,0x00ff,0x0177,0x01b4,0x0000,0x007a,0x017a,0x017c,0x017e,0x0000};

    switch (sChar)
    {
        case 0x0061: return &psAltCharTable[49];
        case 0x0062: return &psAltCharTable[61];
        case 0x0063: return &psAltCharTable[64];
        case 0x0064: return &psAltCharTable[71];
        case 0x0065: return &psAltCharTable[77];
        case 0x0066: return &psAltCharTable[90];
        case 0x0067: return &psAltCharTable[93];
        case 0x0068: return &psAltCharTable[99];
        case 0x0069: return &psAltCharTable[103];
        case 0x006a: return &psAltCharTable[116];
        case 0x006b: return &psAltCharTable[119];
        case 0x006c: return &psAltCharTable[124];
        case 0x006e: return &psAltCharTable[131];
        case 0x006f: return &psAltCharTable[140];
        case 0x0072: return &psAltCharTable[155];
        case 0x0073: return &psAltCharTable[160];
        case 0x0074: return &psAltCharTable[169];
        case 0x0075: return &psAltCharTable[175];
        case 0x0077: return &psAltCharTable[189];
        case 0x0079: return &psAltCharTable[192];
        case 0x007a: return &psAltCharTable[198];
        case 0x00df: return &psAltCharTable[160];
        case 0x00e0: return &psAltCharTable[49];
        case 0x00e1: return &psAltCharTable[49];
        case 0x00e2: return &psAltCharTable[49];
        case 0x00e3: return &psAltCharTable[49];
        case 0x00e4: return &psAltCharTable[49];
        case 0x00e5: return &psAltCharTable[49];
        case 0x00e6: return &psAltCharTable[49];
        case 0x00e7: return &psAltCharTable[64];
        case 0x00e8: return &psAltCharTable[77];
        case 0x00e9: return &psAltCharTable[77];
        case 0x00ea: return &psAltCharTable[77];
        case 0x00eb: return &psAltCharTable[77];
        case 0x00ec: return &psAltCharTable[103];
        case 0x00ed: return &psAltCharTable[103];
        case 0x00ee: return &psAltCharTable[103];
        case 0x00ef: return &psAltCharTable[103];
        case 0x00f0: return &psAltCharTable[71];
        case 0x00f1: return &psAltCharTable[131];
        case 0x00f2: return &psAltCharTable[140];
        case 0x00f3: return &psAltCharTable[140];
        case 0x00f4: return &psAltCharTable[140];
        case 0x00f5: return &psAltCharTable[140];
        case 0x00f6: return &psAltCharTable[140];
        case 0x00f8: return &psAltCharTable[140];
        case 0x00f9: return &psAltCharTable[175];
        case 0x00fa: return &psAltCharTable[175];
        case 0x00fb: return &psAltCharTable[175];
        case 0x00fc: return &psAltCharTable[175];
        case 0x00fd: return &psAltCharTable[192];
        case 0x00fe: return &psAltCharTable[169];
        case 0x00ff: return &psAltCharTable[192];
        case 0x0101: return &psAltCharTable[49];
        case 0x0103: return &psAltCharTable[49];
        case 0x0105: return &psAltCharTable[49];
        case 0x0107: return &psAltCharTable[64];
        case 0x0109: return &psAltCharTable[64];
        case 0x010b: return &psAltCharTable[64];
        case 0x010d: return &psAltCharTable[64];
        case 0x010f: return &psAltCharTable[71];
        case 0x0111: return &psAltCharTable[71];
        case 0x0113: return &psAltCharTable[77];
        case 0x0115: return &psAltCharTable[77];
        case 0x0117: return &psAltCharTable[77];
        case 0x0119: return &psAltCharTable[77];
        case 0x011b: return &psAltCharTable[77];
        case 0x011d: return &psAltCharTable[93];
        case 0x011f: return &psAltCharTable[93];
        case 0x0121: return &psAltCharTable[93];
        case 0x0123: return &psAltCharTable[93];
        case 0x0125: return &psAltCharTable[99];
        case 0x0127: return &psAltCharTable[99];
        case 0x0129: return &psAltCharTable[103];
        case 0x012b: return &psAltCharTable[103];
        case 0x012d: return &psAltCharTable[103];
        case 0x012f: return &psAltCharTable[103];
        case 0x0131: return &psAltCharTable[103];
        case 0x0133: return &psAltCharTable[103];
        case 0x0135: return &psAltCharTable[116];
        case 0x0137: return &psAltCharTable[119];
        case 0x0138: return &psAltCharTable[119];
        case 0x013a: return &psAltCharTable[124];
        case 0x013c: return &psAltCharTable[124];
        case 0x013e: return &psAltCharTable[124];
        case 0x0140: return &psAltCharTable[124];
        case 0x0142: return &psAltCharTable[124];
        case 0x0144: return &psAltCharTable[131];
        case 0x0146: return &psAltCharTable[131];
        case 0x0148: return &psAltCharTable[131];
        case 0x0149: return &psAltCharTable[131];
        case 0x014b: return &psAltCharTable[131];
        case 0x014d: return &psAltCharTable[140];
        case 0x014f: return &psAltCharTable[140];
        case 0x0151: return &psAltCharTable[140];
        case 0x0153: return &psAltCharTable[140];
        case 0x0155: return &psAltCharTable[155];
        case 0x0157: return &psAltCharTable[155];
        case 0x0159: return &psAltCharTable[155];
        case 0x015b: return &psAltCharTable[160];
        case 0x015d: return &psAltCharTable[160];
        case 0x015f: return &psAltCharTable[160];
        case 0x0161: return &psAltCharTable[160];
        case 0x0163: return &psAltCharTable[169];
        case 0x0165: return &psAltCharTable[169];
        case 0x0167: return &psAltCharTable[169];
        case 0x0169: return &psAltCharTable[175];
        case 0x016b: return &psAltCharTable[175];
        case 0x016d: return &psAltCharTable[175];
        case 0x016f: return &psAltCharTable[175];
        case 0x0171: return &psAltCharTable[175];
        case 0x0173: return &psAltCharTable[175];
        case 0x0175: return &psAltCharTable[189];
        case 0x0177: return &psAltCharTable[192];
        case 0x017a: return &psAltCharTable[198];
        case 0x017c: return &psAltCharTable[198];
        case 0x017e: return &psAltCharTable[198];
        case 0x017f: return &psAltCharTable[160];
        case 0x0192: return &psAltCharTable[90];
        case 0x0199: return &psAltCharTable[119];
        case 0x01a1: return &psAltCharTable[140];
        case 0x01b0: return &psAltCharTable[175];
        case 0x01b4: return &psAltCharTable[192];
        case 0x0253: return &psAltCharTable[61];
        case 0x0254: return &psAltCharTable[140];
        case 0x0257: return &psAltCharTable[71];
        case 0x025b: return &psAltCharTable[77];
        case 0x0390: return &psAltCharTable[9];
        case 0x03ac: return &psAltCharTable[0];
        case 0x03ad: return &psAltCharTable[3];
        case 0x03ae: return &psAltCharTable[6];
        case 0x03af: return &psAltCharTable[9];
        case 0x03b0: return &psAltCharTable[17];
        case 0x03b1: return &psAltCharTable[0];
        case 0x03b5: return &psAltCharTable[3];
        case 0x03b7: return &psAltCharTable[6];
        case 0x03b9: return &psAltCharTable[9];
        case 0x03bf: return &psAltCharTable[14];
        case 0x03c5: return &psAltCharTable[17];
        case 0x03c9: return &psAltCharTable[22];
        case 0x03ca: return &psAltCharTable[9];
        case 0x03cb: return &psAltCharTable[17];
        case 0x03cc: return &psAltCharTable[14];
        case 0x03cd: return &psAltCharTable[17];
        case 0x03ce: return &psAltCharTable[22];
        case 0x0915: return &psAltCharTable[25];
        case 0x0916: return &psAltCharTable[28];
        case 0x0917: return &psAltCharTable[31];
        case 0x091c: return &psAltCharTable[34];
        case 0x0921: return &psAltCharTable[37];
        case 0x0922: return &psAltCharTable[40];
        case 0x092b: return &psAltCharTable[43];
        case 0x092f: return &psAltCharTable[46];
        case 0x0958: return &psAltCharTable[25];
        case 0x0959: return &psAltCharTable[28];
        case 0x095a: return &psAltCharTable[31];
        case 0x095b: return &psAltCharTable[34];
        case 0x095c: return &psAltCharTable[37];
        case 0x095d: return &psAltCharTable[40];
        case 0x095e: return &psAltCharTable[43];
        case 0x095f: return &psAltCharTable[46];
        case 0x1e45: return &psAltCharTable[131];
        case 0x1e63: return &psAltCharTable[160];
        case 0x1eb9: return &psAltCharTable[77];
        case 0x1ecb: return &psAltCharTable[103];
        case 0x1ecd: return &psAltCharTable[140];
        case 0x1ee5: return &psAltCharTable[175];
        default:     return NULL;
    }
}

/*---------------------------------------------------------------------------*/
/*  -IDR-    
 *                                             
 *
 *                                                   
 *
 *                                                        
 */

ET9SYMB const * ET9FARCALL _ET9_GetAltCharsUpper(const ET9SYMB sChar)
{
    static const ET9SYMB psAltCharTable[] = {
        0x0391,0x0386,0x0000,0x0395,0x0388,0x0000,0x0397,0x0389,0x0000,0x0399,0x038a,0x03aa,0x0000,0x039f,0x038c,0x0000,0x03a5,0x038e,0x03ab,0x0000,0x03a9,0x038f,0x0000,0x0915,0x0958,0x0000,0x0916,0x0959,0x0000,0x0917,0x095a,0x0000,0x091c,0x095b,0x0000,0x0921,0x095c,0x0000,0x0922,0x095d,0x0000,0x092b,0x095e,0x0000,0x092f,0x095f,0x0000,0x0041,0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x0100,0x0102,0x0104,0x0000,0x0042,0x0181,0x0000,0x0043,0x00c7,
        0x0106,0x0108,0x010a,0x010c,0x0000,0x0044,0x00d0,0x010e,0x0110,0x018a,0x0000,0x0045,0x00c8,0x00c9,0x00ca,0x00cb,0x0112,0x0114,0x0116,0x0118,0x011a,0x0190,0x1eb8,0x0000,0x0046,0x0191,0x0000,0x0047,0x011c,0x011e,0x0120,0x0122,0x0000,0x0048,0x0124,0x0126,0x0000,0x0049,0x00cc,0x00cd,0x00ce,0x00cf,0x0128,0x012a,0x012c,0x012e,0x0132,0x1eca,0x0000,0x004a,0x0134,0x0000,0x004b,0x0136,0x0138,0x0198,0x0000,0x004c,0x0139,0x013b,0x013d,0x013f,0x0141,0x0000,
        0x004e,0x00d1,0x0143,0x0145,0x0147,0x0149,0x014a,0x1e44,0x0000,0x004f,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d8,0x014c,0x014e,0x0150,0x0152,0x01a0,0x0186,0x1ecc,0x0000,0x0052,0x0154,0x0156,0x0158,0x0000,0x0053,0x00df,0x015a,0x015c,0x015e,0x0160,0x1e62,0x0000,0x0054,0x00de,0x0162,0x0164,0x0166,0x0000,0x0055,0x00d9,0x00da,0x00db,0x00dc,0x0168,0x016a,0x016c,0x016e,0x0170,0x0172,0x01af,0x1ee4,0x0000,0x0057,0x0174,0x0000,0x0059,0x00dd,0x0178,0x0176,
        0x01b3,0x0000,0x005a,0x0179,0x017b,0x017d,0x0000};

    switch (sChar)
    {
        case 0x0041: return &psAltCharTable[47];
        case 0x0042: return &psAltCharTable[59];
        case 0x0043: return &psAltCharTable[62];
        case 0x0044: return &psAltCharTable[69];
        case 0x0045: return &psAltCharTable[75];
        case 0x0046: return &psAltCharTable[88];
        case 0x0047: return &psAltCharTable[91];
        case 0x0048: return &psAltCharTable[97];
        case 0x0049: return &psAltCharTable[101];
        case 0x004a: return &psAltCharTable[113];
        case 0x004b: return &psAltCharTable[116];
        case 0x004c: return &psAltCharTable[121];
        case 0x004e: return &psAltCharTable[128];
        case 0x004f: return &psAltCharTable[137];
        case 0x0052: return &psAltCharTable[152];
        case 0x0053: return &psAltCharTable[157];
        case 0x0054: return &psAltCharTable[165];
        case 0x0055: return &psAltCharTable[171];
        case 0x0057: return &psAltCharTable[185];
        case 0x0059: return &psAltCharTable[188];
        case 0x005a: return &psAltCharTable[194];
        case 0x00c0: return &psAltCharTable[47];
        case 0x00c1: return &psAltCharTable[47];
        case 0x00c2: return &psAltCharTable[47];
        case 0x00c3: return &psAltCharTable[47];
        case 0x00c4: return &psAltCharTable[47];
        case 0x00c5: return &psAltCharTable[47];
        case 0x00c6: return &psAltCharTable[47];
        case 0x00c7: return &psAltCharTable[62];
        case 0x00c8: return &psAltCharTable[75];
        case 0x00c9: return &psAltCharTable[75];
        case 0x00ca: return &psAltCharTable[75];
        case 0x00cb: return &psAltCharTable[75];
        case 0x00cc: return &psAltCharTable[101];
        case 0x00cd: return &psAltCharTable[101];
        case 0x00ce: return &psAltCharTable[101];
        case 0x00cf: return &psAltCharTable[101];
        case 0x00d0: return &psAltCharTable[69];
        case 0x00d1: return &psAltCharTable[128];
        case 0x00d2: return &psAltCharTable[137];
        case 0x00d3: return &psAltCharTable[137];
        case 0x00d4: return &psAltCharTable[137];
        case 0x00d5: return &psAltCharTable[137];
        case 0x00d6: return &psAltCharTable[137];
        case 0x00d8: return &psAltCharTable[137];
        case 0x00d9: return &psAltCharTable[171];
        case 0x00da: return &psAltCharTable[171];
        case 0x00db: return &psAltCharTable[171];
        case 0x00dc: return &psAltCharTable[171];
        case 0x00dd: return &psAltCharTable[188];
        case 0x00de: return &psAltCharTable[165];
        case 0x00df: return &psAltCharTable[157];
        case 0x0100: return &psAltCharTable[47];
        case 0x0102: return &psAltCharTable[47];
        case 0x0104: return &psAltCharTable[47];
        case 0x0106: return &psAltCharTable[62];
        case 0x0108: return &psAltCharTable[62];
        case 0x010a: return &psAltCharTable[62];
        case 0x010c: return &psAltCharTable[62];
        case 0x010e: return &psAltCharTable[69];
        case 0x0110: return &psAltCharTable[69];
        case 0x0112: return &psAltCharTable[75];
        case 0x0114: return &psAltCharTable[75];
        case 0x0116: return &psAltCharTable[75];
        case 0x0118: return &psAltCharTable[75];
        case 0x011a: return &psAltCharTable[75];
        case 0x011c: return &psAltCharTable[91];
        case 0x011e: return &psAltCharTable[91];
        case 0x0120: return &psAltCharTable[91];
        case 0x0122: return &psAltCharTable[91];
        case 0x0124: return &psAltCharTable[97];
        case 0x0126: return &psAltCharTable[97];
        case 0x0128: return &psAltCharTable[101];
        case 0x012a: return &psAltCharTable[101];
        case 0x012c: return &psAltCharTable[101];
        case 0x012e: return &psAltCharTable[101];
        case 0x0132: return &psAltCharTable[101];
        case 0x0134: return &psAltCharTable[113];
        case 0x0136: return &psAltCharTable[116];
        case 0x0138: return &psAltCharTable[116];
        case 0x0139: return &psAltCharTable[121];
        case 0x013b: return &psAltCharTable[121];
        case 0x013d: return &psAltCharTable[121];
        case 0x013f: return &psAltCharTable[121];
        case 0x0141: return &psAltCharTable[121];
        case 0x0143: return &psAltCharTable[128];
        case 0x0145: return &psAltCharTable[128];
        case 0x0147: return &psAltCharTable[128];
        case 0x0149: return &psAltCharTable[128];
        case 0x014a: return &psAltCharTable[128];
        case 0x014c: return &psAltCharTable[137];
        case 0x014e: return &psAltCharTable[137];
        case 0x0150: return &psAltCharTable[137];
        case 0x0152: return &psAltCharTable[137];
        case 0x0154: return &psAltCharTable[152];
        case 0x0156: return &psAltCharTable[152];
        case 0x0158: return &psAltCharTable[152];
        case 0x015a: return &psAltCharTable[157];
        case 0x015c: return &psAltCharTable[157];
        case 0x015e: return &psAltCharTable[157];
        case 0x0160: return &psAltCharTable[157];
        case 0x0162: return &psAltCharTable[165];
        case 0x0164: return &psAltCharTable[165];
        case 0x0166: return &psAltCharTable[165];
        case 0x0168: return &psAltCharTable[171];
        case 0x016a: return &psAltCharTable[171];
        case 0x016c: return &psAltCharTable[171];
        case 0x016e: return &psAltCharTable[171];
        case 0x0170: return &psAltCharTable[171];
        case 0x0172: return &psAltCharTable[171];
        case 0x0174: return &psAltCharTable[185];
        case 0x0176: return &psAltCharTable[188];
        case 0x0178: return &psAltCharTable[188];
        case 0x0179: return &psAltCharTable[194];
        case 0x017b: return &psAltCharTable[194];
        case 0x017d: return &psAltCharTable[194];
        case 0x0181: return &psAltCharTable[59];
        case 0x0186: return &psAltCharTable[137];
        case 0x018a: return &psAltCharTable[69];
        case 0x0190: return &psAltCharTable[75];
        case 0x0191: return &psAltCharTable[88];
        case 0x0198: return &psAltCharTable[116];
        case 0x01a0: return &psAltCharTable[137];
        case 0x01af: return &psAltCharTable[171];
        case 0x01b3: return &psAltCharTable[188];
        case 0x0386: return &psAltCharTable[0];
        case 0x0388: return &psAltCharTable[3];
        case 0x0389: return &psAltCharTable[6];
        case 0x038a: return &psAltCharTable[9];
        case 0x038c: return &psAltCharTable[13];
        case 0x038e: return &psAltCharTable[16];
        case 0x038f: return &psAltCharTable[20];
        case 0x0391: return &psAltCharTable[0];
        case 0x0395: return &psAltCharTable[3];
        case 0x0397: return &psAltCharTable[6];
        case 0x0399: return &psAltCharTable[9];
        case 0x039f: return &psAltCharTable[13];
        case 0x03a5: return &psAltCharTable[16];
        case 0x03a9: return &psAltCharTable[20];
        case 0x03aa: return &psAltCharTable[9];
        case 0x03ab: return &psAltCharTable[16];
        case 0x0915: return &psAltCharTable[23];
        case 0x0916: return &psAltCharTable[26];
        case 0x0917: return &psAltCharTable[29];
        case 0x091c: return &psAltCharTable[32];
        case 0x0921: return &psAltCharTable[35];
        case 0x0922: return &psAltCharTable[38];
        case 0x092b: return &psAltCharTable[41];
        case 0x092f: return &psAltCharTable[44];
        case 0x0958: return &psAltCharTable[23];
        case 0x0959: return &psAltCharTable[26];
        case 0x095a: return &psAltCharTable[29];
        case 0x095b: return &psAltCharTable[32];
        case 0x095c: return &psAltCharTable[35];
        case 0x095d: return &psAltCharTable[38];
        case 0x095e: return &psAltCharTable[41];
        case 0x095f: return &psAltCharTable[44];
        case 0x1e44: return &psAltCharTable[128];
        case 0x1e62: return &psAltCharTable[157];
        case 0x1eb8: return &psAltCharTable[75];
        case 0x1eca: return &psAltCharTable[101];
        case 0x1ecc: return &psAltCharTable[137];
        case 0x1ee4: return &psAltCharTable[171];
        default:     return NULL;
    }
}

/*! @} */
/* ----------------------------------< eof >--------------------------------- */
