/****************************************************************************
**
** Copyright (C) 1992-2004 Trolltech AS. All rights reserved.
**
** This file is part of the core module of the Qt Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#ifndef QUNICODETABLES_P_H
#define QUNICODETABLES_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of internal files.  This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//

#include "qstring.h"

namespace QUnicodeTables {

    // see http://www.unicode.org/reports/tr14/tr14-13.html
    // we don't use the XX and AI properties and map them to AL instead.
    enum LineBreakClass {
        LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS,
        LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO,
        LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY,
        LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM,
        LineBreak_SA, LineBreak_BK, LineBreak_CR, LineBreak_LF, LineBreak_SG,
        LineBreak_CB, LineBreak_SP
    };

    inline uint surrogateToUcs4(ushort high, ushort low) {
        return (high<<10) + low - 0x35fdc00;
    }
    inline ushort highSurrogate(uint ucs4) {
        return (ucs4>>10) + 0xd7c0;
    }
    inline ushort lowSurrogate(uint ucs4) {
        return ucs4%0x400 + 0xdc00;
    }
    inline bool isHighSurrogate(uint utf16) {
        return (utf16 >= 0xd800 && utf16 < 0xdc00);
    }
    inline bool isLowSurrogate(uint utf16) {
        return (utf16 >= 0xdc00 && utf16 < 0xe000);
    }


    Q_CORE_EXPORT QChar::Category  QT_FASTCALL category(uint ucs4);
    Q_CORE_EXPORT unsigned char  QT_FASTCALL combiningClass(uint ucs4);
    Q_CORE_EXPORT QChar::Direction QT_FASTCALL direction(uint ucs4);
    Q_CORE_EXPORT QChar::UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4);
    Q_CORE_EXPORT QChar::Joining QT_FASTCALL joining(uint ucs4);
    Q_CORE_EXPORT bool QT_FASTCALL mirrored(uint ucs4);
    Q_CORE_EXPORT int QT_FASTCALL mirroredChar(uint ucs4);
    Q_CORE_EXPORT LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4);
    Q_CORE_EXPORT int QT_FASTCALL upper(uint ucs4);
    Q_CORE_EXPORT int QT_FASTCALL lower(uint ucs4);
    Q_CORE_EXPORT int QT_FASTCALL digitValue(uint ucs4);
    Q_CORE_EXPORT QString QT_FASTCALL decomposition(uint ucs4);
    Q_CORE_EXPORT QChar::Decomposition QT_FASTCALL decompositionTag(uint ucs4);
    Q_CORE_EXPORT ushort QT_FASTCALL ligature(ushort u1, ushort u2);

    enum NormalizationMode {
        NormalizationMode_D,
        NormalizationMode_C,
        NormalizationMode_KD,
        NormalizationMode_KC
    };
    Q_CORE_EXPORT QString normalize(const QString &str, QUnicodeTables::NormalizationMode mode);
    Q_CORE_EXPORT QString normalize(const QString &str, QUnicodeTables::NormalizationMode mode, QChar::UnicodeVersion version);
};


inline QChar::Category category(const QChar &c)
{
    return QUnicodeTables::category(c.unicode());
}

inline QChar lower(const QChar &c)
{
    return QChar(QUnicodeTables::lower(c.unicode()));
}

inline QChar upper(const QChar &c)
{
    return QChar(QUnicodeTables::upper(c.unicode()));
}

inline QChar::Direction direction(const QChar &c)
{
    return QUnicodeTables::direction(c.unicode());
}

inline bool mirrored(const QChar &c)
{
    return QUnicodeTables::mirrored(c.unicode());
}


inline QChar mirroredChar(const QChar &c)
{
    return QUnicodeTables::mirroredChar(c.unicode());
}

inline QChar::Joining joining(const QChar &c)
{
    return QUnicodeTables::joining(c.unicode());
}

inline bool isMark(const QChar &ch)
{
    QChar::Category c = QUnicodeTables::category(ch.unicode());
    return c >= QChar::Mark_NonSpacing && c <= QChar::Mark_Enclosing;
}

inline unsigned char combiningClass(const QChar &ch)
{
    return QUnicodeTables::combiningClass(ch.unicode());
}

inline bool isSpace(const QChar &ch)
{
    if(ch.unicode() >= 9 && ch.unicode() <=13) return true;
    QChar::Category c = QUnicodeTables::category(ch.unicode());
    return c >= QChar::Separator_Space && c <= QChar::Separator_Paragraph;
}

inline int lineBreakClass(const QChar &ch)
{
    return QUnicodeTables::lineBreakClass(ch.unicode());
}

Q_CORE_EXPORT int qt_scriptForChar(ushort uc);

#ifdef Q_WS_X11
#define SCRIPT_FOR_CHAR(script, c)         \
do {                                                 \
    unsigned short _uc = (c).unicode();                 \
    if (_uc < 0x100) {                                \
        script = QFont::Latin;                \
    } else {                                         \
        script = (QFont::Script)qt_scriptForChar(_uc);         \
    }                                                 \
} while(false)
#else
#define SCRIPT_FOR_CHAR(script, c) \
    script = (QFont::Script)qt_scriptForChar((c).unicode())
#endif

#endif
