/*
 *******************************************************************************
 *
 *   Copyright (C) 1999-2001, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  Paragraph.cpp
 *
 *   created on: 09/06/2000
 *   created by: Eric R. Mader
 */

#include "unicode/loengine.h"

#include "RenderingFontInstance.h"

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

#include "paragraph.h"
#include "scrptrun.h"
#include "UnicodeReader.h"
#include "FontMap.h"

#define MARGIN 10

Paragraph::Paragraph(void *surface, RunParams params[], int32_t count, UBiDi *bidi)
    : fBidi(bidi), fRunCount(count), fRunInfo(NULL), fCharCount(0), fText(NULL), fGlyphCount(0), fGlyphs(NULL),
      fCharIndices(NULL), fGlyphIndices(NULL), fDX(NULL), fBreakArray(NULL), fBreakCount(0),
      fLineHeight(-1), fAscent(-1)
{
    int32_t i;

    fWidth = fHeight = 0;

    fRunInfo = new RunInfo[count + 1];

    // Set charBase and rightToLeft for
    // each run and count the total characters
    for (i = 0; i < count; i += 1) {
        fRunInfo[i].charBase = fCharCount;
        fRunInfo[i].rightToLeft = params[i].rightToLeft;
        fCharCount += params[i].count;
    }

    // Set charBase and rightToLeft for the
    // fake run at the end.
    fRunInfo[count].charBase = fCharCount;
    fRunInfo[count].rightToLeft = false;

    fBreakArray = new int32_t[fCharCount + 1];
    fText = new LEUnicode[fCharCount];
    
    // Copy the text runs into a single array
    for (i = 0; i < count; i += 1) {
        int32_t charBase = fRunInfo[i].charBase;
        int32_t charCount = fRunInfo[i + 1].charBase - charBase;

        LE_ARRAY_COPY(&fText[charBase], params[i].text, charCount);
    }

    Locale thai("th");
    UCharCharacterIterator *iter = new UCharCharacterIterator(fText, fCharCount);
    UErrorCode status = U_ZERO_ERROR;
    Locale dummyLocale;

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

    ICULayoutEngine **engines = new ICULayoutEngine *[count];
    int32_t maxAscent = -1, maxDescent = -1, maxLeading = -1;
    float x = 0, y = 0;

    // Layout each run, set glyphBase and glyphCount
    // and count the total number of glyphs
    for (i = 0; i < count; i += 1) {
        int32_t charBase = fRunInfo[i].charBase;
        int32_t charCount = fRunInfo[i + 1].charBase - charBase;
        int32_t glyphCount = 0;
        int32_t runAscent = 0, runDescent = 0, runLeading = 0;
        UErrorCode success = U_ZERO_ERROR;

        fRunInfo[i].fontInstance = params[i].fontInstance;

        fRunInfo[i].fontInstance->setFont(surface);

        runAscent  = fRunInfo[i].fontInstance->getAscent();
        runDescent = fRunInfo[i].fontInstance->getDescent();
        runLeading = fRunInfo[i].fontInstance->getLeading();


        if (runAscent > maxAscent) {
            maxAscent = runAscent;
        }

        if (runDescent > maxDescent) {
            maxDescent = runDescent;
        }

        if (runLeading > maxLeading) {
            maxLeading = runLeading;
        }

        engines[i] = ICULayoutEngine::createInstance(fRunInfo[i].fontInstance, params[i].scriptCode, dummyLocale, success);

        glyphCount = engines[i]->layoutChars(fText, charBase, charBase + charCount, fCharCount,
            fRunInfo[i].rightToLeft, x, y, success);

        engines[i]->getGlyphPosition(glyphCount, x, y, success);

        fRunInfo[i].glyphBase = fGlyphCount;
        fGlyphCount += glyphCount;
    }

    fLineHeight = maxAscent + maxDescent + maxLeading;
    fAscent = maxAscent;

    // Set glyphBase for the fake run at the end
    fRunInfo[count].glyphBase = fGlyphCount;

    fGlyphs = new LEGlyphID[fGlyphCount];
    fCharIndices = new int32_t[fGlyphCount];
    fGlyphIndices = new int32_t[fCharCount + 1];
    fDX = new int32_t[fGlyphCount];
    fDY = new int32_t[fGlyphCount];


    float *positions = new float[fGlyphCount * 2 + 2];

    // Build the glyph, charIndices and positions arrays
    for (i = 0; i < count; i += 1) {
        ICULayoutEngine *engine = engines[i];
        int32_t charBase = fRunInfo[i].charBase;
        int32_t glyphBase = fRunInfo[i].glyphBase;
        UErrorCode success = U_ZERO_ERROR;

        engine->getGlyphs(&fGlyphs[glyphBase], success);
        engine->getCharIndices(&fCharIndices[glyphBase], charBase, success);
        engine->getGlyphPositions(&positions[glyphBase * 2], success);
    }

    // Filter deleted glyphs, compute logical advances
    // and set the char to glyph map
    for (i = 0; i < fGlyphCount; i += 1) {
        // Filter deleted glyphs
        if (fGlyphs[i] == 0xFFFE || fGlyphs[i] == 0xFFFF) {
            fGlyphs[i] = 0x0001;
        }

        // compute the logical advance
        fDX[i] = (int32_t) (positions[i * 2 + 2] - positions[i * 2]);

        // save the Y offset
        fDY[i] = (int32_t) positions[i * 2 + 1];

        // set char to glyph map
        fGlyphIndices[fCharIndices[i]] = i;
    }

    if (fRunInfo[count - 1].rightToLeft) {
        fGlyphIndices[fCharCount] = fRunInfo[count - 1].glyphBase - 1;
    } else {
        fGlyphIndices[fCharCount] = fGlyphCount;
    }

    delete[] positions;

    // Get rid of the LayoutEngine's:
    for (i = 0; i < count; i += 1) {
        delete engines[i];
    }

    delete[] engines;
}

Paragraph::~Paragraph()
{
    delete[] fDY;
    delete[] fDX;
    delete[] fGlyphIndices;
    delete[] fCharIndices;
    delete[] fGlyphs;

    delete fBrkiter;
    delete fText;

    delete[] fBreakArray;
    delete[] fRunInfo;

    ubidi_close(fBidi);
}

int32_t Paragraph::getLineHeight()
{
    return fLineHeight;
}

int32_t Paragraph::getLineCount()
{
    return fBreakCount;
}

int32_t Paragraph::getAscent()
{
    return fAscent;
}

int32_t Paragraph::previousBreak(int32_t charIndex)
{
    LEUnicode ch = fText[charIndex];

    // skip over any whitespace or control
    // characters, because they can hang in
    // the margin.
    while (charIndex < fCharCount &&
           (Unicode::isWhitespace(ch) ||
            Unicode::isControl(ch))) {
        ch = fText[++charIndex];
    }

    // 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 fBrkiter->preceding(charIndex + 1);
}

void Paragraph::breakLines(int32_t width, int32_t height)
{
    int32_t lineWidth = width - (2 * MARGIN);
    int32_t thisWidth = 0;
    int32_t thisBreak = -1;
    int32_t prevWidth = fWidth;

    fWidth  = width;
    fHeight = height;

    // don't re-break if the width hasn't changed
    if (width == prevWidth) {
        return;
    }

    fBreakArray[0] = 0;
    fBreakCount = 1;

    for (int32_t run = 0; run < fRunCount; run += 1) {
        int32_t glyph = fRunInfo[run].glyphBase;
        int32_t stop = fRunInfo[run + 1].glyphBase;
        int32_t dir = 1;

        if (fRunInfo[run].rightToLeft) {
            glyph = stop - 1;
            stop = fRunInfo[run].glyphBase - 1;
            dir = -1;
        }

        while (glyph != stop) {
            // Find the first glyph that doesn't fit on the line
            while (thisWidth + fDX[glyph] <= lineWidth) {
                thisWidth += fDX[glyph];
                glyph += dir;

                if (glyph == stop) {
                    break;
                }
            }

            // Check to see if we fell off the
            // end of the run
            if (glyph == stop) {
                break;
            }


            // Find a place before here to break,
            thisBreak = previousBreak(fCharIndices[glyph]);

            // If there wasn't one, force one
            if (thisBreak <= fBreakArray[fBreakCount - 1]) {
                thisBreak = fCharIndices[glyph];
            }

            // Save the break location.
            fBreakArray[fBreakCount++] = thisBreak;

            // Reset the accumulated width
            thisWidth = 0;

            // Map the character back to a glyph
            glyph = fGlyphIndices[thisBreak];

            // Check to see if the new glyph is off
            // the end of the run.
            if (glyph == stop) {
                break;
            }

            // If the glyph's not in the run we stopped in, we
            // have to re-synch to the new run
            if (glyph < fRunInfo[run].glyphBase || glyph >= fRunInfo[run + 1].glyphBase) {
                run = getGlyphRun(glyph, 0, 1);

                if (fRunInfo[run].rightToLeft) {
                    stop = fRunInfo[run].glyphBase - 1;
                    dir = -1;
                } else {
                    stop = fRunInfo[run + 1].glyphBase;
                    dir = 1;
                }
            }
        }
    }

    // Make sure the last break is after the last character
    if (fBreakArray[--fBreakCount] != fCharCount) {
        fBreakArray[++fBreakCount] = fCharCount;
    }

    return;
}

int32_t Paragraph::getGlyphRun(int32_t glyph, int32_t startingRun, int32_t direction)
{
    int32_t limit;

    if (direction < 0) {
        limit = -1;
    } else {
        limit = fRunCount;
    }

    for (int32_t run = startingRun; run != limit; run += direction) {
        if (glyph >= fRunInfo[run].glyphBase && glyph < fRunInfo[run + 1].glyphBase) {
            return run;
        }
    }

    return limit;
}

int32_t Paragraph::getCharRun(int32_t ch, int32_t startingRun, int32_t direction)
{
    int32_t limit;

    if (direction < 0) {
        limit = -1;
    } else {
        limit = fRunCount;
    }

    for (int32_t run = startingRun; run != limit; run += direction) {
        if (ch >= fRunInfo[run].charBase && ch < fRunInfo[run + 1].charBase) {
            return run;
        }
    }

    return limit;
}

int32_t Paragraph::getRunWidth(int32_t startGlyph, int32_t endGlyph)
{
    int32_t width = 0;

    for (int32_t glyph = startGlyph; glyph <= endGlyph; glyph += 1) {
        width += fDX[glyph];
    }

    return width;
}

int32_t Paragraph::drawRun(void *surface, const RenderingFontInstance *fontInstance, int32_t firstChar, int32_t lastChar,
                         int32_t x, int32_t y)
{
    int32_t firstGlyph = fGlyphIndices[firstChar];
    int32_t lastGlyph  = fGlyphIndices[lastChar];

    for (int32_t ch = firstChar; ch <= lastChar; ch += 1) {
        int32_t glyph = fGlyphIndices[ch];

        if (glyph < firstGlyph) {
            firstGlyph = glyph;
        }

        if (glyph > lastGlyph) {
            lastGlyph = glyph;
        }
    }

    int32_t dyStart = firstGlyph, dyEnd = dyStart;

    fontInstance->setFont(surface);

    while (dyEnd <= lastGlyph) {
        while (dyEnd <= lastGlyph && fDY[dyStart] == fDY[dyEnd]) {
            dyEnd += 1;
        }

        fontInstance->drawGlyphs(surface, &fGlyphs[dyStart], dyEnd - dyStart,
            &fDX[dyStart], x, y + fDY[dyStart], fWidth, fHeight);

        dyStart = dyEnd;
    }

    return getRunWidth(firstGlyph, lastGlyph);
}

void Paragraph::draw(void *surface, int32_t firstLine, int32_t lastLine)
{
    int32_t line, x, y;
    int32_t prevRun = 0;
    UErrorCode bidiStatus = U_ZERO_ERROR;
    UBiDi  *lBidi = ubidi_openSized(fCharCount, 0, &bidiStatus);

    y = fAscent;

    for (line = firstLine; line <= lastLine; line += 1) {
        int32_t firstChar = fBreakArray[line];
        int32_t lastChar  = fBreakArray[line + 1] - 1;
        int32_t dirCount, dirRun;

        x = MARGIN;

        ubidi_setLine(fBidi, firstChar, lastChar + 1, lBidi, &bidiStatus);

        dirCount = ubidi_countRuns(lBidi, &bidiStatus);

        for (dirRun = 0; dirRun < dirCount; dirRun += 1) {
            UTextOffset relStart = 0, runLength = 0;
            UBiDiDirection runDirection = ubidi_getVisualRun(lBidi, dirRun, &relStart, &runLength);
            int32_t runStart  = relStart + firstChar;
            int32_t runEnd    = runStart + runLength - 1;
            int32_t firstRun  = getCharRun(runStart, prevRun, 1);
            int32_t lastRun   = getCharRun(runEnd,   firstRun, 1);

            for (int32_t run = firstRun; run <= lastRun; run += 1) {
                const RenderingFontInstance *fontInstance = fRunInfo[run].fontInstance;
                int32_t nextBase;

                if (run == lastRun) {
                    nextBase = runEnd + 1;
                } else {
                    nextBase = fRunInfo[run + 1].charBase;
                }

                x += drawRun(surface, fontInstance, runStart, nextBase - 1, x, y);
                runStart = nextBase;
            }

            prevRun = lastRun;
        }

        y += fLineHeight;
    }

    ubidi_close(lBidi);
}

Paragraph *Paragraph::paragraphFactory(const char *fileName, FontMap *fontMap, GUISupport *guiSupport, void *surface)
{
    RunParams params[64];
    int32_t paramCount = 0;
    int32_t charCount  = 0;
    int32_t dirCount   = 0;
    int32_t dirRun     = 0;
    RFIErrorCode fontStatus = RFI_NO_ERROR;
    UErrorCode bidiStatus = U_ZERO_ERROR;
    const UChar *text = UnicodeReader::readFile(fileName, guiSupport, charCount);
    ScriptRun scriptRun(text, charCount);

    if (text == NULL) {
        return NULL;
    }

    UBiDi *pBidi = ubidi_openSized(charCount, 0, &bidiStatus);

    ubidi_setPara(pBidi, text, charCount, UBIDI_DEFAULT_LTR, NULL, &bidiStatus);

    dirCount = ubidi_countRuns(pBidi, &bidiStatus);

    for (dirRun = 0; dirRun < dirCount; dirRun += 1) {
        UTextOffset runStart = 0, runLength = 0;
        UBiDiDirection runDirection = ubidi_getVisualRun(pBidi, dirRun, &runStart, &runLength);
        
        scriptRun.reset(runStart, runLength);

        while (scriptRun.next()) {
            int32_t     start = scriptRun.getScriptStart();
            int32_t     end   = scriptRun.getScriptEnd();
            UScriptCode code  = scriptRun.getScriptCode();

            params[paramCount].text = &((UChar *) text)[start];
            params[paramCount].count = end - start;
            params[paramCount].scriptCode = (UScriptCode) code;
            params[paramCount].rightToLeft = runDirection == UBIDI_RTL;

            params[paramCount].fontInstance = fontMap->getScriptFont(code, fontStatus);

            if (params[paramCount].fontInstance == NULL) {
                ubidi_close(pBidi);
                return 0;
            }

            paramCount += 1;
        }
    }

    return new Paragraph(surface, params, paramCount, pBidi);
}

