/*
 **********************************************************************
 *   Copyright (C) 2002-2010, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */

/*
 * paragraphLayout doesn't make much sense without
 * BreakIterator...
 */
#include "layout/LETypes.h"
#include "layout/LEScripts.h"
#include "layout/LELanguages.h"
#include "layout/LayoutEngine.h"
#include "layout/LEFontInstance.h"

#include "unicode/ubidi.h"
#include "unicode/uchriter.h"
#include "unicode/brkiter.h"

#if ! UCONFIG_NO_BREAK_ITERATION
#include "LXUtilities.h"
#include "usc_impl.h" /* this is currently private! */
#include "cstring.h"  /* this too! */

#include "layout/ParagraphLayout.h"

U_NAMESPACE_BEGIN

#define ARRAY_SIZE(array) (sizeof array  / sizeof array[0])

/* Leave this copyright notice here! It needs to go somewhere in this library. */
static const char copyright[] = U_COPYRIGHT_STRING;

class StyleRuns
{
public:
    StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount);

    ~StyleRuns();

    le_int32 getRuns(le_int32 runLimits[], le_int32 styleIndices[]);

private:
    le_int32 fStyleCount;
    le_int32 fRunCount;

    le_int32 *fRunLimits;
    le_int32 *fStyleIndices;
};

StyleRuns::StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount)
    : fStyleCount(styleCount), fRunCount(0), fRunLimits(NULL), fStyleIndices(NULL)
{
    le_int32 maxRunCount = 0;
    le_int32 style, run, runStyle;
    le_int32 *currentRun = LE_NEW_ARRAY(le_int32, styleCount);

    for (int i = 0; i < styleCount; i += 1) {
        maxRunCount += styleRunArrays[i]->getCount();
    }

    maxRunCount -= styleCount - 1;

    fRunLimits    = LE_NEW_ARRAY(le_int32, maxRunCount);
    fStyleIndices = LE_NEW_ARRAY(le_int32, maxRunCount * styleCount);

    for (style = 0; style < styleCount; style += 1) {
        currentRun[style] = 0;
    }

    run = 0;
    runStyle = 0;

    /*
     * Since the last run limit for each style run must be
     * the same, all the styles will hit the last limit at
     * the same time, so we know when we're done when the first
     * style hits the last limit.
     */
    while (currentRun[0] < styleRunArrays[0]->getCount()) {
        fRunLimits[run] = 0x7FFFFFFF;

        // find the minimum run limit for all the styles
        for (style = 0; style < styleCount; style += 1) {
            if (styleRunArrays[style]->getLimit(currentRun[style]) < fRunLimits[run]) {
                fRunLimits[run] = styleRunArrays[style]->getLimit(currentRun[style]);
            }
        }

        // advance all styles whose current run is at this limit to the next run
        for (style = 0; style < styleCount; style += 1) {
            fStyleIndices[runStyle++] = currentRun[style];

            if (styleRunArrays[style]->getLimit(currentRun[style]) == fRunLimits[run]) {
                currentRun[style] += 1;
            }
        }

        run += 1;
    }

    fRunCount = run;
    LE_DELETE_ARRAY(currentRun);
}

StyleRuns::~StyleRuns()
{
    fRunCount = 0;

    LE_DELETE_ARRAY(fStyleIndices);
    fStyleIndices = NULL;

    LE_DELETE_ARRAY(fRunLimits);
    fRunLimits = NULL;
}

le_int32 StyleRuns::getRuns(le_int32 runLimits[], le_int32 styleIndices[])
{
    if (runLimits != NULL) {
        LE_ARRAY_COPY(runLimits, fRunLimits, fRunCount);
    }

    if (styleIndices != NULL) {
        LE_ARRAY_COPY(styleIndices, fStyleIndices, fRunCount * fStyleCount);
    }

    return fRunCount;
}

/*
 * NOTE: This table only has "TRUE" values for
 * those scripts which the LayoutEngine can currently
 * process, rather for all scripts which require
 * complex processing for correct rendering.
 */
static const le_bool complexTable[scriptCodeCount] = {
    FALSE , /* Zyyy */
    FALSE,  /* Qaai */
    TRUE,   /* Arab */
    FALSE,  /* Armn */
    TRUE,   /* Beng */
    FALSE,  /* Bopo */
    FALSE,  /* Cher */
    FALSE,  /* Copt=Qaac */
    FALSE,  /* Cyrl */
    FALSE,  /* Dsrt */
    TRUE,   /* Deva */
    FALSE,  /* Ethi */
    FALSE,  /* Geor */
    FALSE,  /* Goth */
    FALSE,  /* Grek */
    TRUE,   /* Gujr */
    TRUE,   /* Guru */
    FALSE,  /* Hani */
    FALSE,  /* Hang */
    TRUE,   /* Hebr */
    FALSE,  /* Hira */
    TRUE,   /* Knda */
    FALSE,  /* Kana */
    FALSE,  /* Khmr */
    FALSE,  /* Laoo */
    FALSE,  /* Latn */
    TRUE,   /* Mlym */
    FALSE,  /* Mong */
    FALSE,  /* Mymr */
    FALSE,  /* Ogam */
    FALSE,  /* Ital */
    TRUE,   /* Orya */
    FALSE,  /* Runr */
    FALSE,  /* Sinh */
    FALSE,  /* Syrc */
    TRUE,   /* Taml */
    TRUE,   /* Telu */
    FALSE,  /* Thaa */
    TRUE,   /* Thai */
    FALSE,  /* Tibt */
    FALSE,  /* Cans */
    FALSE,  /* Yiii */
    FALSE,  /* Tglg */
    FALSE,  /* Hano */
    FALSE,  /* Buhd */
    FALSE,  /* Tagb */
    FALSE,  /* Brai */
    FALSE,  /* Cprt */
    FALSE,  /* Limb */
    FALSE,  /* Linb */
    FALSE,  /* Osma */
    FALSE,  /* Shaw */
    FALSE,  /* Tale */
    FALSE,  /* Ugar */
    FALSE,  /* Hrkt */
    FALSE,  /* Bugi */
    FALSE,  /* Glag */
    FALSE,  /* Khar */
    FALSE,  /* Sylo */
    FALSE,  /* Talu */
    FALSE,  /* Tfng */
    FALSE,  /* Xpeo */
    FALSE,  /* Bali */
    FALSE,  /* Batk */
    FALSE,  /* Blis */
    FALSE,  /* Brah */
    FALSE,  /* Cham */
    FALSE,  /* Cirt */
    FALSE,  /* Cyrs */
    FALSE,  /* Egyd */
    FALSE,  /* Egyh */
    FALSE,  /* Egyp */
    FALSE,  /* Geok */
    FALSE,  /* Hans */
    FALSE,  /* Hant */
    FALSE,  /* Hmng */
    FALSE,  /* Hung */
    FALSE,  /* Inds */
    FALSE,  /* Java */
    FALSE,  /* Kali */
    FALSE,  /* Latf */
    FALSE,  /* Latg */
    FALSE,  /* Lepc */
    FALSE,  /* Lina */
    FALSE,  /* Mand */
    FALSE,  /* Maya */
    FALSE,  /* Mero */
    FALSE,  /* Nkoo */
    FALSE,  /* Orkh */
    FALSE,  /* Perm */
    FALSE,  /* Phag */
    FALSE,  /* Phnx */
    FALSE,  /* Plrd */
    FALSE,  /* Roro */
    FALSE,  /* Sara */
    FALSE,  /* Syre */
    FALSE,  /* Syrj */
    FALSE,  /* Syrn */
    FALSE,  /* Teng */
    FALSE,  /* Taii */
    FALSE,  /* Visp */
    FALSE,  /* Xsux */
    FALSE,  /* Zxxx */
    FALSE,  /* Zzzz */
    FALSE,  /* Cari */
    FALSE,  /* Jpan */
    FALSE,  /* Lana */
    FALSE,  /* Lyci */
    FALSE,  /* Lydi */
    FALSE,  /* Olck */
    FALSE,  /* Rjng */
    FALSE,  /* Saur */
    FALSE,  /* Sgnw */
    FALSE,  /* Sund */
    FALSE,  /* Moon */
    FALSE,  /* Mtei */
    FALSE,  /* Armi */
    FALSE,  /* Avst */
    FALSE,  /* Cakm */
    FALSE,  /* Kore */
    FALSE,  /* Kthi */
    FALSE,  /* Mani */
    FALSE,  /* Phli */
    FALSE,  /* Phlp */
    FALSE,  /* Phlv */
    FALSE,  /* Prti */
    FALSE,  /* Samr */
    FALSE,  /* Tavt */
    FALSE,  /* Zmth */
    FALSE,  /* Zsym */
    FALSE,  /* Bamu */
    FALSE,  /* Lisu */
    FALSE,  /* Nkgb */
    FALSE   /* Sarb */
};


const char ParagraphLayout::fgClassID = 0;

static void fillMissingCharToGlyphMapValues(le_int32 *charToGlyphMap,
                                            le_int32 charCount) {
    le_int32 lastValidGlyph = -1;
    le_int32 ch;
    for (ch = 0; ch <= charCount; ch += 1) {
        if (charToGlyphMap[ch] == -1) {
            charToGlyphMap[ch] = lastValidGlyph;
        } else {
            lastValidGlyph = charToGlyphMap[ch];
        }
    }
}

/*
 * How to deal with composite fonts:
 *
 * Don't store the client's FontRuns; we'll need to compute sub-font FontRuns using Doug's
 * LEFontInstance method. Do that by intersecting the client's FontRuns with fScriptRuns. Use
 * that to compute fFontRuns, and then intersect fFontRuns, fScriptRuns and fLevelRuns. Doing
 * it in this order means we do a two-way intersection and a three-way intersection.
 *
 * An optimization would be to only do this if there's at least one composite font...
 *
 * Other notes:
 *
 * * Return the sub-fonts as the run fonts... could keep the mapping back to the client's FontRuns
 *   but that probably makes it more complicated of everyone...
 *
 * * Take the LineInfo and LineRun types from Paragraph and use them here, incorporate them into the API.
 *
 * * Might want to change the name of the StyleRun type, and make a new one that holds fonts, scripts and levels?
 *
 */
ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
                                 const FontRuns   *fontRuns,
                                 const ValueRuns  *levelRuns,
                                 const ValueRuns  *scriptRuns,
                                 const LocaleRuns *localeRuns,
                                 UBiDiLevel paragraphLevel, le_bool vertical,
                                 LEErrorCode &status)
                                 : fChars(chars), fCharCount(count),
                                   fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns),
                                   fVertical(vertical), fClientLevels(TRUE), fClientScripts(TRUE), fClientLocales(TRUE), fEmbeddingLevels(NULL),
                                   fAscent(0), fDescent(0), fLeading(0),
                                   fGlyphToCharMap(NULL), fCharToMinGlyphMap(NULL), fCharToMaxGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0),
                                   fParaBidi(NULL), fLineBidi(NULL),
                                   fStyleRunLimits(NULL), fStyleIndices(NULL), fStyleRunCount(0),
                                   fBreakIterator(NULL), fLineStart(-1), fLineEnd(0),
                                 /*fVisualRuns(NULL), fStyleRunInfo(NULL), fVisualRunCount(-1),
                                   fFirstVisualRun(-1), fLastVisualRun(-1),*/ fVisualRunLastX(0), fVisualRunLastY(0)
{

    if (LE_FAILURE(status)) {
        fCharCount = -1;
        return;
    }

    // FIXME: should check the limit arrays for consistency...

    computeLevels(paragraphLevel);

    if (scriptRuns == NULL) {
        computeScripts();
    }

    if (localeRuns == NULL) {
        computeLocales();
    }

    computeSubFonts(fontRuns, status);

    if (LE_FAILURE(status)) {
        //other stuff?
        fCharCount = -1;
        return;
    }

    // now intersect the font, direction and script runs...
    const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns, fLocaleRuns};
    le_int32  styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0];
    StyleRuns styleRuns(styleRunArrays, styleCount);
    LEErrorCode layoutStatus = LE_NO_ERROR;
    
    fStyleRunCount = styleRuns.getRuns(NULL, NULL);

    fStyleRunLimits = LE_NEW_ARRAY(le_int32, fStyleRunCount);
    fStyleIndices   = LE_NEW_ARRAY(le_int32, fStyleRunCount * styleCount);
    if ((fStyleRunLimits == NULL) || (fStyleIndices == NULL)) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }

    styleRuns.getRuns(fStyleRunLimits, fStyleIndices);

    // now build a LayoutEngine for each style run...
    le_int32 *styleIndices = fStyleIndices;
    le_int32 run, runStart;

    fStyleRunInfo = LE_NEW_ARRAY(StyleRunInfo, fStyleRunCount);
    if (fStyleRunInfo == NULL) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }
    else {
        // initialize
        for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
            fStyleRunInfo[run].font = NULL;
            fStyleRunInfo[run].runBase = 0;
            fStyleRunInfo[run].runLimit = 0;
            fStyleRunInfo[run].script = (UScriptCode)0;
            fStyleRunInfo[run].locale = NULL;
            fStyleRunInfo[run].level = 0;
            fStyleRunInfo[run].glyphBase = 0;
            fStyleRunInfo[run].engine = NULL;
            fStyleRunInfo[run].glyphCount = 0;
            fStyleRunInfo[run].glyphs = NULL;
            fStyleRunInfo[run].positions = NULL;
        }
    }

    fGlyphCount = 0;
    for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
        fStyleRunInfo[run].font      = fFontRuns->getFont(styleIndices[0]);
        fStyleRunInfo[run].runBase   = runStart;
        fStyleRunInfo[run].runLimit  = fStyleRunLimits[run];
        fStyleRunInfo[run].script    = (UScriptCode) fScriptRuns->getValue(styleIndices[2]);
        fStyleRunInfo[run].locale    = fLocaleRuns->getLocale(styleIndices[3]);
        fStyleRunInfo[run].level     = (UBiDiLevel) fLevelRuns->getValue(styleIndices[1]);
        fStyleRunInfo[run].glyphBase = fGlyphCount;

        fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font,
            fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount,
            fStyleRunInfo[run].level & 1, 0, 0, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        runStart = fStyleRunLimits[run];
        styleIndices += styleCount;
        fGlyphCount += fStyleRunInfo[run].glyphCount;
    }

    // Make big arrays for the glyph widths, glyph-to-char and char-to-glyph maps,
    // in logical order. (Both maps need an extra entry for the end of the text.) 
    //
    // For each layout get the positions and convert them into glyph widths, in
    // logical order. Get the glyph-to-char mapping, offset by starting index in the
    // character array. Swap the glyph width and glyph-to-char arrays into logical order.
    // Finally, fill in the char-to-glyph mappings.
    fGlyphWidths       = LE_NEW_ARRAY(float, fGlyphCount);
    fGlyphToCharMap    = LE_NEW_ARRAY(le_int32, fGlyphCount + 1);
    fCharToMinGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
    fCharToMaxGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
    if ((fGlyphWidths == NULL) || (fGlyphToCharMap == NULL) || 
        (fCharToMinGlyphMap == NULL) || (fCharToMaxGlyphMap == NULL)) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }

    le_int32 glyph;

    for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
        LayoutEngine *engine = fStyleRunInfo[run].engine;
        le_int32 glyphCount  = fStyleRunInfo[run].glyphCount;
        le_int32 glyphBase   = fStyleRunInfo[run].glyphBase;

        fStyleRunInfo[run].glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount);
        fStyleRunInfo[run].positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2);
        if ((fStyleRunInfo[run].glyphs == NULL) || 
            (fStyleRunInfo[run].positions == NULL)) {
            status = LE_MEMORY_ALLOCATION_ERROR;
            return;
        }

        engine->getGlyphs(fStyleRunInfo[run].glyphs, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        engine->getGlyphPositions(fStyleRunInfo[run].positions, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        engine->getCharIndices(&fGlyphToCharMap[glyphBase], runStart, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        for (glyph = 0; glyph < glyphCount; glyph += 1) {
            fGlyphWidths[glyphBase + glyph] = fStyleRunInfo[run].positions[glyph * 2 + 2] - fStyleRunInfo[run].positions[glyph * 2];
        }

        if ((fStyleRunInfo[run].level & 1) != 0) {
            LXUtilities::reverse(&fGlyphWidths[glyphBase], glyphCount);
            LXUtilities::reverse(&fGlyphToCharMap[glyphBase], glyphCount);
        }

        runStart = fStyleRunLimits[run];

        delete engine;
        fStyleRunInfo[run].engine = NULL;
    }

    fGlyphToCharMap[fGlyphCount] = fCharCount;

    // Initialize the char-to-glyph maps to -1 so that we can later figure out
    // whether any of the entries in the map aren't filled in below.
    le_int32 chIndex;
    for (chIndex = 0; chIndex <= fCharCount; chIndex += 1) {
        fCharToMinGlyphMap[chIndex] = -1;
        fCharToMaxGlyphMap[chIndex] = -1;
    }

    for (glyph = fGlyphCount - 1; glyph >= 0; glyph -= 1) {
        le_int32 ch = fGlyphToCharMap[glyph];

        fCharToMinGlyphMap[ch] = glyph;
    }

    fCharToMinGlyphMap[fCharCount] = fGlyphCount;

    for (glyph = 0; glyph < fGlyphCount; glyph += 1) {
        le_int32 ch = fGlyphToCharMap[glyph];

        fCharToMaxGlyphMap[ch] = glyph;
    }

    fCharToMaxGlyphMap[fCharCount] = fGlyphCount;

    // Now fill in the missing values in the char-to-glyph maps.
    fillMissingCharToGlyphMapValues(fCharToMinGlyphMap, fCharCount);
    fillMissingCharToGlyphMapValues(fCharToMaxGlyphMap, fCharCount);
}

ParagraphLayout::~ParagraphLayout()
{
    delete (FontRuns *) fFontRuns;

    if (! fClientLevels) {
        delete (ValueRuns *) fLevelRuns;
        fLevelRuns = NULL;

        fClientLevels = TRUE;
    }

    if (! fClientScripts) {
        delete (ValueRuns *) fScriptRuns;
        fScriptRuns = NULL;

        fClientScripts = TRUE;
    }

    if (! fClientLocales) {
        delete (LocaleRuns *) fLocaleRuns;
        fLocaleRuns = NULL;

        fClientLocales = TRUE;
    }

    if (fEmbeddingLevels != NULL) {
        LE_DELETE_ARRAY(fEmbeddingLevels);
        fEmbeddingLevels = NULL;
    }

    if (fGlyphToCharMap != NULL) {
        LE_DELETE_ARRAY(fGlyphToCharMap);
        fGlyphToCharMap = NULL;
    }

    if (fCharToMinGlyphMap != NULL) {
        LE_DELETE_ARRAY(fCharToMinGlyphMap);
        fCharToMinGlyphMap = NULL;
    }

    if (fCharToMaxGlyphMap != NULL) {
        LE_DELETE_ARRAY(fCharToMaxGlyphMap);
        fCharToMaxGlyphMap = NULL;
    }

    if (fGlyphWidths != NULL) {
        LE_DELETE_ARRAY(fGlyphWidths);
        fGlyphWidths = NULL;
    }

    if (fParaBidi != NULL) {
        ubidi_close(fParaBidi);
        fParaBidi = NULL;
    }

    if (fLineBidi != NULL) {
        ubidi_close(fLineBidi);
        fLineBidi = NULL;
    }

    if (fStyleRunCount > 0) {
        le_int32 run;

        LE_DELETE_ARRAY(fStyleRunLimits);
        LE_DELETE_ARRAY(fStyleIndices);

        for (run = 0; run < fStyleRunCount; run += 1) {
            LE_DELETE_ARRAY(fStyleRunInfo[run].glyphs);
            LE_DELETE_ARRAY(fStyleRunInfo[run].positions);

            fStyleRunInfo[run].glyphs    = NULL;
            fStyleRunInfo[run].positions = NULL;
        }

        LE_DELETE_ARRAY(fStyleRunInfo);

        fStyleRunLimits = NULL;
        fStyleIndices   = NULL;
        fStyleRunInfo        = NULL;
        fStyleRunCount  = 0;
    }

    if (fBreakIterator != NULL) {
        delete fBreakIterator;
        fBreakIterator = NULL;
    }
}

    
le_bool ParagraphLayout::isComplex(const LEUnicode chars[], le_int32 count)
{
    UErrorCode scriptStatus = U_ZERO_ERROR;
    UScriptCode scriptCode  = USCRIPT_INVALID_CODE;
    UScriptRun *sr = uscript_openRun(chars, count, &scriptStatus);
    le_bool result = FALSE;

    while (uscript_nextRun(sr, NULL, NULL, &scriptCode)) {
        if (isComplex(scriptCode)) {
            result = TRUE;
            break;
        }
    }

    uscript_closeRun(sr);
    return result;
}

le_int32 ParagraphLayout::getAscent() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        ((ParagraphLayout *) this)->computeMetrics();
    }

    return fAscent;
}

le_int32 ParagraphLayout::getDescent() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        ((ParagraphLayout *) this)->computeMetrics();
    }

    return fDescent;
}

le_int32 ParagraphLayout::getLeading() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        ((ParagraphLayout *) this)->computeMetrics();
    }

    return fLeading;
}

le_bool ParagraphLayout::isDone() const
{
    return fLineEnd >= fCharCount;
}

ParagraphLayout::Line *ParagraphLayout::nextLine(float width)
{
    if (isDone()) {
        return NULL;
    }

    fLineStart = fLineEnd;

    if (width > 0) {
        le_int32 glyph    = fCharToMinGlyphMap[fLineStart];
        float widthSoFar  = 0;

        while (glyph < fGlyphCount && widthSoFar + fGlyphWidths[glyph] <= width) {
            widthSoFar += fGlyphWidths[glyph++];
        }

        // If no glyphs fit on the line, force one to fit.
        //
        // (There shouldn't be any zero width glyphs at the
        // start of a line unless the paragraph consists of
        // only zero width glyphs, because otherwise the zero
        // width glyphs will have been included on the end of
        // the previous line...)
        if (widthSoFar == 0 && glyph < fGlyphCount) {
            glyph += 1;
        }

        fLineEnd = previousBreak(fGlyphToCharMap[glyph]);

        // If this break is at or before the last one,
        // find a glyph, starting at the one which didn't
        // fit, that produces a break after the last one.
        while (fLineEnd <= fLineStart) {
            fLineEnd = fGlyphToCharMap[glyph++];
        }
    } else {
        fLineEnd = fCharCount;
    }

    return computeVisualRuns();
}

void ParagraphLayout::computeLevels(UBiDiLevel paragraphLevel)
{
    UErrorCode bidiStatus = U_ZERO_ERROR;

    if (fLevelRuns != NULL) {
        le_int32 ch;
        le_int32 run;

        fEmbeddingLevels = LE_NEW_ARRAY(UBiDiLevel, fCharCount);

        for (ch = 0, run = 0; run < fLevelRuns->getCount(); run += 1) {
            UBiDiLevel runLevel = (UBiDiLevel) fLevelRuns->getValue(run) | UBIDI_LEVEL_OVERRIDE;
            le_int32   runLimit = fLevelRuns->getLimit(run);

            while (ch < runLimit) {
                fEmbeddingLevels[ch++] = runLevel;
            }
        }
    }

    fParaBidi = ubidi_openSized(fCharCount, 0, &bidiStatus);
    ubidi_setPara(fParaBidi, fChars, fCharCount, paragraphLevel, fEmbeddingLevels, &bidiStatus);

    if (fLevelRuns == NULL) {
        le_int32 levelRunCount = ubidi_countRuns(fParaBidi, &bidiStatus);
        ValueRuns *levelRuns = new ValueRuns(levelRunCount);

        le_int32 logicalStart = 0;
        le_int32 run;
        le_int32 limit;
        UBiDiLevel level;

        for (run = 0; run < levelRunCount; run += 1) {
            ubidi_getLogicalRun(fParaBidi, logicalStart, &limit, &level);
            levelRuns->add(level, limit);
            logicalStart = limit;
        }

        fLevelRuns    = levelRuns;
        fClientLevels = FALSE;
    }
}

void ParagraphLayout::computeScripts()
{
    UErrorCode scriptStatus = U_ZERO_ERROR;
    UScriptRun *sr = uscript_openRun(fChars, fCharCount, &scriptStatus);
    ValueRuns  *scriptRuns = new ValueRuns(0);
    le_int32 limit;
    UScriptCode script;

    while (uscript_nextRun(sr, NULL, &limit, &script)) {
        scriptRuns->add(script, limit);
    }

    uscript_closeRun(sr);

    fScriptRuns    = scriptRuns;
    fClientScripts = FALSE;
}

void ParagraphLayout::computeLocales()
{
    LocaleRuns *localeRuns = new LocaleRuns(0);
    const Locale *defaultLocale = &Locale::getDefault();

    localeRuns->add(defaultLocale, fCharCount);

    fLocaleRuns    = localeRuns;
    fClientLocales = FALSE;
}

void ParagraphLayout::computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status)
{
    if (LE_FAILURE(status)) {
        return;
    }

    const RunArray *styleRunArrays[] = {fontRuns, fScriptRuns};
    le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0];
    StyleRuns styleRuns(styleRunArrays, styleCount);
    le_int32 styleRunCount = styleRuns.getRuns(NULL, NULL);
    le_int32 *styleRunLimits = LE_NEW_ARRAY(le_int32, styleRunCount);
    le_int32 *styleIndices = LE_NEW_ARRAY(le_int32, styleRunCount * styleCount);
    FontRuns *subFontRuns  = new FontRuns(0);
    le_int32  run, offset, *si;

    styleRuns.getRuns(styleRunLimits, styleIndices);

    si = styleIndices;
    offset = 0;

    for (run = 0; run < styleRunCount; run += 1) {
        const LEFontInstance *runFont = fontRuns->getFont(si[0]);
        le_int32 script = fScriptRuns->getValue(si[1]);

        while (offset < styleRunLimits[run]) {
            const LEFontInstance *subFont = runFont->getSubFont(fChars, &offset, styleRunLimits[run], script, status);

            if (LE_FAILURE(status)) {
                delete subFontRuns;
                goto cleanUp;
            }

            subFontRuns->add(subFont, offset);
        }

        si += styleCount;
    }

    fFontRuns = subFontRuns;

cleanUp:
    LE_DELETE_ARRAY(styleIndices);
    LE_DELETE_ARRAY(styleRunLimits);
}

void ParagraphLayout::computeMetrics()
{
    le_int32 i, count = fFontRuns->getCount();
    le_int32 maxDL = 0;

    for (i = 0; i < count; i += 1) {
        const LEFontInstance *font = fFontRuns->getFont(i);
        le_int32 ascent  = font->getAscent();
        le_int32 descent = font->getDescent();
        le_int32 leading = font->getLeading();
        le_int32 dl      = descent + leading;

        if (ascent > fAscent) {
            fAscent = ascent;
        }

        if (descent > fDescent) {
            fDescent = descent;
        }

        if (leading > fLeading) {
            fLeading = leading;
        }

        if (dl > maxDL) {
            maxDL = dl;
        }
    }

    fLeading = maxDL - fDescent;
}

#if 1
struct LanguageMap
{
    const char *localeCode;
    le_int32 languageCode;
};

static const LanguageMap languageMap[] =
{
    {"afr", afkLanguageCode}, // Afrikaans
    {"ara", araLanguageCode}, // Arabic
    {"asm", asmLanguageCode}, // Assamese
    {"bel", belLanguageCode}, // Belarussian
    {"ben", benLanguageCode}, // Bengali
    {"bod", tibLanguageCode}, // Tibetan
    {"bul", bgrLanguageCode}, // Bulgarian
    {"cat", catLanguageCode}, // Catalan
    {"ces", csyLanguageCode}, // Czech
    {"che", cheLanguageCode}, // Chechen
    {"cop", copLanguageCode}, // Coptic
    {"cym", welLanguageCode}, // Welsh
    {"dan", danLanguageCode}, // Danish
    {"deu", deuLanguageCode}, // German
    {"dzo", dznLanguageCode}, // Dzongkha
    {"ell", ellLanguageCode}, // Greek
    {"eng", engLanguageCode}, // English
    {"est", etiLanguageCode}, // Estonian
    {"eus", euqLanguageCode}, // Basque
    {"fas", farLanguageCode}, // Farsi
    {"fin", finLanguageCode}, // Finnish
    {"fra", fraLanguageCode}, // French
    {"gle", gaeLanguageCode}, // Irish Gaelic
    {"guj", gujLanguageCode}, // Gujarati
    {"hau", hauLanguageCode}, // Hausa
    {"heb", iwrLanguageCode}, // Hebrew
    {"hin", hinLanguageCode}, // Hindi
    {"hrv", hrvLanguageCode}, // Croatian
    {"hun", hunLanguageCode}, // Hungarian
    {"hye", hyeLanguageCode}, // Armenian
    {"ind", indLanguageCode}, // Indonesian
    {"ita", itaLanguageCode}, // Italian
    {"jpn", janLanguageCode}, // Japanese
    {"kan", kanLanguageCode}, // Kannada
    {"kas", kshLanguageCode}, // Kashmiri
    {"khm", khmLanguageCode}, // Khmer
    {"kok", kokLanguageCode}, // Konkani
    {"kor", korLanguageCode}, // Korean
//  {"mal_XXX", malLanguageCode}, // Malayalam - Traditional
    {"mal", mlrLanguageCode}, // Malayalam - Reformed
    {"mar", marLanguageCode}, // Marathi
    {"mlt", mtsLanguageCode}, // Maltese
    {"mni", mniLanguageCode}, // Manipuri
    {"mon", mngLanguageCode}, // Mongolian
    {"nep", nepLanguageCode}, // Nepali
    {"ori", oriLanguageCode}, // Oriya
    {"pol", plkLanguageCode}, // Polish
    {"por", ptgLanguageCode}, // Portuguese
    {"pus", pasLanguageCode}, // Pashto
    {"ron", romLanguageCode}, // Romanian
    {"rus", rusLanguageCode}, // Russian
    {"san", sanLanguageCode}, // Sanskrit
    {"sin", snhLanguageCode}, // Sinhalese
    {"slk", skyLanguageCode}, // Slovak
    {"snd", sndLanguageCode}, // Sindhi
    {"slv", slvLanguageCode}, // Slovenian
    {"spa", espLanguageCode}, // Spanish
    {"sqi", sqiLanguageCode}, // Albanian
    {"srp", srbLanguageCode}, // Serbian
    {"swe", sveLanguageCode}, // Swedish
    {"syr", syrLanguageCode}, // Syriac
    {"tam", tamLanguageCode}, // Tamil
    {"tel", telLanguageCode}, // Telugu
    {"tha", thaLanguageCode}, // Thai
    {"tur", trkLanguageCode}, // Turkish
    {"urd", urdLanguageCode}, // Urdu
    {"yid", jiiLanguageCode}, // Yiddish
//  {"zhp", zhpLanguageCode}, // Chinese - Phonetic
    {"zho", zhsLanguageCode}, // Chinese
    {"zho_CHN", zhsLanguageCode}, // Chinese - China
    {"zho_HKG", zhsLanguageCode}, // Chinese - Hong Kong
    {"zho_MAC", zhtLanguageCode}, // Chinese - Macao
    {"zho_SGP", zhsLanguageCode}, // Chinese - Singapore
    {"zho_TWN", zhtLanguageCode}  // Chinese - Taiwan
};

static const le_int32 languageMapCount = ARRAY_SIZE(languageMap);

le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
    char code[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    const char *language = locale->getISO3Language();
    const char *country  = locale->getISO3Country();

    uprv_strcat(code, language);

    if ((uprv_strcmp(language, "zho") == 0) && country != NULL) {
        uprv_strcat(code, "_");
        uprv_strcat(code, country);
    }

    for (le_int32 i = 0; i < languageMapCount; i += 1) {
        if (uprv_strcmp(code, languageMap[i].localeCode) == 0) {
            return languageMap[i].languageCode;
        }
    }

    return nullLanguageCode;
}
#else

// TODO - dummy implementation for right now...
le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
    return nullLanguageCode;
}
#endif

le_bool ParagraphLayout::isComplex(UScriptCode script)
{
    if (script < 0 || script >= (UScriptCode) scriptCodeCount) {
        return FALSE;
    }

    return complexTable[script];
}

le_int32 ParagraphLayout::previousBreak(le_int32 charIndex)
{
    // skip over any whitespace or control characters,
    // because they can hang in the margin.
    while (charIndex < fCharCount &&
           (u_isWhitespace(fChars[charIndex]) ||
            u_iscntrl(fChars[charIndex]))) {
        charIndex += 1;
    }

    // Create the BreakIterator if we don't already have one
    if (fBreakIterator == NULL) {
        Locale thai("th");
        UCharCharacterIterator *iter = new UCharCharacterIterator(fChars, fCharCount);
        UErrorCode status = U_ZERO_ERROR;

        fBreakIterator = BreakIterator::createLineInstance(thai, status);
        fBreakIterator->adoptText(iter);
    }

    // return the break location that's at or before
    // the character we stopped on. Note: if we're
    // on a break, the "+ 1" will cause preceding to
    // back up to it.
    return fBreakIterator->preceding(charIndex + 1);
}

ParagraphLayout::Line *ParagraphLayout::computeVisualRuns()
{
    UErrorCode bidiStatus = U_ZERO_ERROR;
    le_int32 dirRunCount, visualRun;

    fVisualRunLastX = 0;
    fVisualRunLastY = 0;
    fFirstVisualRun = getCharRun(fLineStart);
    fLastVisualRun  = getCharRun(fLineEnd - 1);

    if (fLineBidi == NULL) {
        fLineBidi = ubidi_openSized(fCharCount, 0, &bidiStatus);
    }

    ubidi_setLine(fParaBidi, fLineStart, fLineEnd, fLineBidi, &bidiStatus);
    dirRunCount = ubidi_countRuns(fLineBidi, &bidiStatus);

    Line *line = new Line();

    for (visualRun = 0; visualRun < dirRunCount; visualRun += 1) {
        le_int32 relStart, run, runLength;
        UBiDiDirection runDirection = ubidi_getVisualRun(fLineBidi, visualRun, &relStart, &runLength);
        le_int32 runStart = fLineStart + relStart;
        le_int32 runEnd   = runStart + runLength - 1;
        le_int32 firstRun = getCharRun(runStart);
        le_int32 lastRun  = getCharRun(runEnd);
        le_int32 startRun = (runDirection == UBIDI_LTR)? firstRun : lastRun;
        le_int32 stopRun  = (runDirection == UBIDI_LTR)? lastRun + 1 : firstRun - 1;
        le_int32 dir      = (runDirection == UBIDI_LTR)?  1 : -1;

        for (run = startRun; run != stopRun; run += dir) {
            le_int32 firstChar = (run == firstRun)? runStart : fStyleRunInfo[run].runBase;
            le_int32 lastChar  = (run == lastRun)?  runEnd   : fStyleRunInfo[run].runLimit - 1;

            appendRun(line, run, firstChar, lastChar);
        }
    }

    return line;
}

void ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar)
{
    le_int32 glyphBase = fStyleRunInfo[run].glyphBase;
    le_int32 inGlyph, outGlyph;

    // Get the glyph indices for all the characters between firstChar and lastChar,
    // make the minimum one be leftGlyph and the maximum one be rightGlyph.
    // (need to do this to handle local reorderings like Indic left matras)
    le_int32 leftGlyph  = fGlyphCount;
    le_int32 rightGlyph = -1;
    le_int32 ch;

    for (ch = firstChar; ch <= lastChar; ch += 1) {
        le_int32 minGlyph = fCharToMinGlyphMap[ch];
        le_int32 maxGlyph = fCharToMaxGlyphMap[ch];

        if (minGlyph < leftGlyph) {
            leftGlyph = minGlyph;
        }

        if (maxGlyph > rightGlyph) {
            rightGlyph = maxGlyph;
        }
    }

    if ((fStyleRunInfo[run].level & 1) != 0) {
        le_int32 swap = rightGlyph;
        le_int32 last = glyphBase + fStyleRunInfo[run].glyphCount - 1;

        // Here, we want to remove the glyphBase bias...
        rightGlyph = last - leftGlyph;
        leftGlyph  = last - swap;
    } else {
        rightGlyph -= glyphBase;
        leftGlyph  -= glyphBase;
    }

    // Set the position bias for the glyphs. If we're at the start of
    // a line, we want the first glyph to be at x = 0, even if it comes
    // from the middle of a layout. If we've got a right-to-left run, we
    // want the left-most glyph to start at the final x position of the
    // previous run, even though this glyph may be in the middle of the
    // run.
    fVisualRunLastX -= fStyleRunInfo[run].positions[leftGlyph * 2];
 
    // Make rightGlyph be the glyph just to the right of
    // the run's glyphs
    rightGlyph += 1;

    UBiDiDirection direction  = ((fStyleRunInfo[run].level & 1) == 0)? UBIDI_LTR : UBIDI_RTL;
    le_int32   glyphCount     = rightGlyph - leftGlyph;
    LEGlyphID *glyphs         = LE_NEW_ARRAY(LEGlyphID, glyphCount);
    float     *positions      = LE_NEW_ARRAY(float, glyphCount * 2 + 2);
    le_int32  *glyphToCharMap = LE_NEW_ARRAY(le_int32, glyphCount);

    LE_ARRAY_COPY(glyphs, &fStyleRunInfo[run].glyphs[leftGlyph], glyphCount);

    for (outGlyph = 0, inGlyph = leftGlyph * 2; inGlyph <= rightGlyph * 2; inGlyph += 2, outGlyph += 2) {
        positions[outGlyph]     = fStyleRunInfo[run].positions[inGlyph] + fVisualRunLastX;
        positions[outGlyph + 1] = fStyleRunInfo[run].positions[inGlyph + 1] + fVisualRunLastY;
    }

    // Save the ending position of this run
    // to use for the start of the next run
    fVisualRunLastX = positions[outGlyph - 2];
    fVisualRunLastY = positions[outGlyph - 1];

    if ((fStyleRunInfo[run].level & 1) == 0) {
        for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) {
            glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph];
        }
    } else {
        // Because fGlyphToCharMap is stored in logical order to facilitate line breaking,
        // we need to map the physical glyph indices to logical indices while we copy the
        // character indices.
        le_int32 base = glyphBase + fStyleRunInfo[run].glyphCount - 1;

        for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) {
            glyphToCharMap[outGlyph] = fGlyphToCharMap[base - inGlyph];
        }
    }

    line->append(fStyleRunInfo[run].font, direction, glyphCount, glyphs, positions, glyphToCharMap);
}

le_int32 ParagraphLayout::getCharRun(le_int32 charIndex)
{
    if (charIndex < 0 || charIndex > fCharCount) {
        return -1;
    }

    le_int32 run;

    // NOTE: as long as fStyleRunLimits is well-formed
    // the above range check guarantees that we'll never
    // fall off the end of the array.
    run = 0;
    while (charIndex >= fStyleRunLimits[run]) {
        run += 1;
    }

    return run;
}


const char ParagraphLayout::Line::fgClassID = 0;

#define INITIAL_RUN_CAPACITY 4
#define RUN_CAPACITY_GROW_LIMIT 16

ParagraphLayout::Line::~Line()
{
    le_int32 i;

    for (i = 0; i < fRunCount; i += 1) {
        delete fRuns[i];
    }

    LE_DELETE_ARRAY(fRuns);
}

le_int32 ParagraphLayout::Line::getAscent() const
{
    if (fAscent <= 0) {
        ((ParagraphLayout::Line *)this)->computeMetrics();
    }

    return fAscent;
}

le_int32 ParagraphLayout::Line::getDescent() const
{
    if (fAscent <= 0) {
        ((ParagraphLayout::Line *)this)->computeMetrics();
    }

    return fDescent;
}

le_int32 ParagraphLayout::Line::getLeading() const
{
    if (fAscent <= 0) {
        ((ParagraphLayout::Line *)this)->computeMetrics();
    }

    return fLeading;
}

le_int32 ParagraphLayout::Line::getWidth() const
{
    const VisualRun *lastRun = getVisualRun(fRunCount - 1);

    if (lastRun == NULL) {
        return 0;
    }

    le_int32 glyphCount = lastRun->getGlyphCount();
    const float *positions = lastRun->getPositions();
    
    return (le_int32) positions[glyphCount * 2];
}

const ParagraphLayout::VisualRun *ParagraphLayout::Line::getVisualRun(le_int32 runIndex) const
{
    if (runIndex < 0 || runIndex >= fRunCount) {
        return NULL;
    }

    return fRuns[runIndex];
}

void ParagraphLayout::Line::append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
                                   const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[])
{
    if (fRunCount >= fRunCapacity) {
        if (fRunCapacity == 0) {
            fRunCapacity = INITIAL_RUN_CAPACITY;
            fRuns = LE_NEW_ARRAY(ParagraphLayout::VisualRun *, fRunCapacity);
        } else {
            fRunCapacity += (fRunCapacity < RUN_CAPACITY_GROW_LIMIT? fRunCapacity : RUN_CAPACITY_GROW_LIMIT);
            fRuns = (ParagraphLayout::VisualRun **) LE_GROW_ARRAY(fRuns, fRunCapacity);
        }
    }

    fRuns[fRunCount++] = new ParagraphLayout::VisualRun(font, direction, glyphCount, glyphs, positions, glyphToCharMap);
}

void ParagraphLayout::Line::computeMetrics()
{
    le_int32 maxDL = 0;

    for (le_int32 i = 0; i < fRunCount; i += 1) {
        le_int32 ascent  = fRuns[i]->getAscent();
        le_int32 descent = fRuns[i]->getDescent();
        le_int32 leading = fRuns[i]->getLeading();
        le_int32 dl      = descent + leading;

        if (ascent > fAscent) {
            fAscent = ascent;
        }

        if (descent > fDescent) {
            fDescent = descent;
        }

        if (leading > fLeading) {
            fLeading = leading;
        }

        if (dl > maxDL) {
            maxDL = dl;
        }
    }

    fLeading = maxDL - fDescent;
}

const char ParagraphLayout::VisualRun::fgClassID = 0;

ParagraphLayout::VisualRun::~VisualRun()
{
    LE_DELETE_ARRAY(fGlyphToCharMap);
    LE_DELETE_ARRAY(fPositions);
    LE_DELETE_ARRAY(fGlyphs);
}

U_NAMESPACE_END

#endif

