/*
*******************************************************************************
*   Copyright (C) 2001-2007, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*/
/* Written by Simon Montagu, Matitiahu Allouche
 * (ported from C code written by Markus W. Scherer)
 */

package com.ibm.icu.text;


import java.util.Arrays;

final class BidiLine {

    /*
     * General remarks about the functions in this file:
     *
     * These functions deal with the aspects of potentially mixed-directional
     * text in a single paragraph or in a line of a single paragraph
     * which has already been processed according to
     * the Unicode 3.0 Bidi algorithm as defined in
     * http://www.unicode.org/unicode/reports/tr9/ , version 13,
     * also described in The Unicode Standard, Version 4.0.1 .
     *
     * This means that there is a Bidi object with a levels
     * and a dirProps array.
     * paraLevel and direction are also set.
     * Only if the length of the text is zero, then levels==dirProps==NULL.
     *
     * The overall directionality of the paragraph
     * or line is used to bypass the reordering steps if possible.
     * Even purely RTL text does not need reordering there because
     * the getLogical/VisualIndex() methods can compute the
     * index on the fly in such a case.
     *
     * The implementation of the access to same-level-runs and of the reordering
     * do attempt to provide better performance and less memory usage compared to
     * a direct implementation of especially rule (L2) with an array of
     * one (32-bit) integer per text character.
     *
     * Here, the levels array is scanned as soon as necessary, and a vector of
     * same-level-runs is created. Reordering then is done on this vector.
     * For each run of text positions that were resolved to the same level,
     * only 8 bytes are stored: the first text position of the run and the visual
     * position behind the run after reordering.
     * One sign bit is used to hold the directionality of the run.
     * This is inefficient if there are many very short runs. If the average run
     * length is <2, then this uses more memory.
     *
     * In a further attempt to save memory, the levels array is never changed
     * after all the resolution rules (Xn, Wn, Nn, In).
     * Many methods have to consider the field trailingWSStart:
     * if it is less than length, then there is an implicit trailing run
     * at the paraLevel,
     * which is not reflected in the levels array.
     * This allows a line Bidi object to use the same levels array as
     * its paragraph parent object.
     *
     * When a Bidi object is created for a line of a paragraph, then the
     * paragraph's levels and dirProps arrays are reused by way of setting
     * a pointer into them, not by copying. This again saves memory and forbids to
     * change the now shared levels for (L1).
     */

    /* handle trailing WS (L1) -------------------------------------------------- */

    /*
     * setTrailingWSStart() sets the start index for a trailing
     * run of WS in the line. This is necessary because we do not modify
     * the paragraph's levels array that we just point into.
     * Using trailingWSStart is another form of performing (L1).
     *
     * To make subsequent operations easier, we also include the run
     * before the WS if it is at the paraLevel - we merge the two here.
     *
     * This method is called only from setLine(), so paraLevel is
     * set correctly for the line even when contextual multiple paragraphs.
     */

    static void setTrailingWSStart(Bidi bidi)
    {
        byte[] dirProps = bidi.dirProps;
        byte[] levels = bidi.levels;
        int start = bidi.length;
        byte paraLevel = bidi.paraLevel;

        /* If the line is terminated by a block separator, all preceding WS etc...
           are already set to paragraph level.
           Setting trailingWSStart to pBidi->length will avoid changing the
           level of B chars from 0 to paraLevel in getLevels when
           orderParagraphsLTR==TRUE
        */
        if (Bidi.NoContextRTL(dirProps[start - 1]) == Bidi.B) {
            bidi.trailingWSStart = start;   /* currently == bidi.length */
            return;
        }
        /* go backwards across all WS, BN, explicit codes */
        while (start > 0 &&
                (Bidi.DirPropFlagNC(dirProps[start - 1]) & Bidi.MASK_WS) != 0) {
            --start;
        }

        /* if the WS run can be merged with the previous run then do so here */
        while (start > 0 && levels[start - 1] == paraLevel) {
            --start;
        }

        bidi.trailingWSStart=start;
    }

    static Bidi setLine(Bidi paraBidi, int start, int limit) {
        int length;

        Bidi lineBidi = new Bidi();

        /* set the values in lineBidi from its paraBidi parent */
        /* class members are already initialized to 0 */
        // lineBidi.paraBidi = null;        /* mark unfinished setLine */
        // lineBidi.flags = 0;
        // lineBidi.controlCount = 0;

        length = lineBidi.length = lineBidi.originalLength =
                lineBidi.resultLength = limit - start;

        lineBidi.text = new char[length];
        System.arraycopy(paraBidi.text, start, lineBidi.text, 0, length);
        lineBidi.paraLevel = paraBidi.GetParaLevelAt(start);
        lineBidi.paraCount = paraBidi.paraCount;
        lineBidi.runs = new BidiRun[0];
        lineBidi.reorderingMode = paraBidi.reorderingMode;
        lineBidi.reorderingOptions = paraBidi.reorderingOptions;
        if (paraBidi.controlCount > 0) {
            int j;
            for (j = start; j < limit; j++) {
                if (Bidi.IsBidiControlChar(paraBidi.text[j])) {
                    lineBidi.controlCount++;
                }
            }
            lineBidi.resultLength -= lineBidi.controlCount;
        }
        /* copy proper subset of DirProps */
        lineBidi.getDirPropsMemory(length);
        lineBidi.dirProps = lineBidi.dirPropsMemory;
        System.arraycopy(paraBidi.dirProps, start, lineBidi.dirProps, 0,
                         length);
        /* copy proper subset of Levels */
        lineBidi.getLevelsMemory(length);
        lineBidi.levels = lineBidi.levelsMemory;
        System.arraycopy(paraBidi.levels, start, lineBidi.levels, 0,
                         length);
        lineBidi.runCount = -1;

        if (paraBidi.direction != Bidi.MIXED) {
            /* the parent is already trivial */
            lineBidi.direction = paraBidi.direction;

            /*
             * The parent's levels are all either
             * implicitly or explicitly ==paraLevel;
             * do the same here.
             */
            if (paraBidi.trailingWSStart <= start) {
                lineBidi.trailingWSStart = 0;
            } else if (paraBidi.trailingWSStart < limit) {
                lineBidi.trailingWSStart = paraBidi.trailingWSStart - start;
            } else {
                lineBidi.trailingWSStart = length;
            }
        } else {
            byte[] levels = lineBidi.levels;
            int i, trailingWSStart;
            byte level;

            setTrailingWSStart(lineBidi);
            trailingWSStart = lineBidi.trailingWSStart;

            /* recalculate lineBidi.direction */
            if (trailingWSStart == 0) {
                /* all levels are at paraLevel */
                lineBidi.direction = (byte)(lineBidi.paraLevel & 1);
            } else {
                /* get the level of the first character */
                level = (byte)(levels[0] & 1);

                /* if there is anything of a different level, then the line
                   is mixed */
                if (trailingWSStart < length &&
                    (lineBidi.paraLevel & 1) != level) {
                    /* the trailing WS is at paraLevel, which differs from
                       levels[0] */
                    lineBidi.direction = Bidi.MIXED;
                } else {
                    /* see if levels[1..trailingWSStart-1] have the same
                       direction as levels[0] and paraLevel */
                    for (i = 1; ; i++) {
                        if (i == trailingWSStart) {
                            /* the direction values match those in level */
                            lineBidi.direction = level;
                            break;
                        } else if ((levels[i] & 1) != level) {
                            lineBidi.direction = Bidi.MIXED;
                            break;
                        }
                    }
                }
            }

            switch(lineBidi.direction) {
                case Bidi.DIRECTION_LEFT_TO_RIGHT:
                    /* make sure paraLevel is even */
                    lineBidi.paraLevel = (byte)
                        ((lineBidi.paraLevel + 1) & ~1);

                    /* all levels are implicitly at paraLevel (important for
                       getLevels()) */
                    lineBidi.trailingWSStart = 0;
                    break;
                case Bidi.DIRECTION_RIGHT_TO_LEFT:
                    /* make sure paraLevel is odd */
                    lineBidi.paraLevel |= 1;

                    /* all levels are implicitly at paraLevel (important for
                       getLevels()) */
                    lineBidi.trailingWSStart = 0;
                    break;
                default:
                    break;
            }
        }
        lineBidi.paraBidi = paraBidi;     /* mark successful setLine */
        return lineBidi;
    }

    static byte getLevelAt(Bidi bidi, int charIndex)
    {
        /* return paraLevel if in the trailing WS run, otherwise the real level */
        if (bidi.direction != Bidi.MIXED || charIndex >= bidi.trailingWSStart) {
            return bidi.GetParaLevelAt(charIndex);
        } else {
            return bidi.levels[charIndex];
        }
    }

    static byte[] getLevels(Bidi bidi)
    {
        int start = bidi.trailingWSStart;
        int length = bidi.length;

        if (start != length) {
            /* the current levels array does not reflect the WS run */
            /*
             * After the previous if(), we know that the levels array
             * has an implicit trailing WS run and therefore does not fully
             * reflect itself all the levels.
             * This must be a Bidi object for a line, and
             * we need to create a new levels array.
             */
            /* bidi.paraLevel is ok even if contextual multiple paragraphs,
               since bidi is a line object                                     */
            Arrays.fill(bidi.levels, start, length, bidi.paraLevel);

            /* this new levels array is set for the line and reflects the WS run */
            bidi.trailingWSStart = length;
        }
        if (length < bidi.levels.length) {
            byte[] levels = new byte[length];
            System.arraycopy(bidi.levels, 0, levels, 0, length);
            return levels;
        }
        return bidi.levels;
    }

    static BidiRun getLogicalRun(Bidi bidi, int logicalPosition)
    {
        /* this is done based on runs rather than on levels since levels have
           a special interpretation when REORDER_RUNS_ONLY
         */
        BidiRun newRun = new BidiRun(), iRun;
        getRuns(bidi);
        int runCount = bidi.runCount;
        int visualStart = 0, logicalLimit = 0;
        iRun = bidi.runs[0];

        for (int i = 0; i < runCount; i++) {
            iRun = bidi.runs[i];
            logicalLimit = iRun.start + iRun.limit - visualStart;
            if ((logicalPosition >= iRun.start) &&
                (logicalPosition < logicalLimit)) {
                break;
            }
            visualStart = iRun.limit;
        }
        newRun.start = iRun.start;
        newRun.limit = logicalLimit;
        newRun.level = iRun.level;
        return newRun;
    }

    static BidiRun getVisualRun(Bidi bidi, int runIndex)
    {
        int start = bidi.runs[runIndex].start;
        int limit;
        byte level = bidi.runs[runIndex].level;

        if (runIndex > 0) {
            limit = start +
                    bidi.runs[runIndex].limit -
                    bidi.runs[runIndex - 1].limit;
        } else {
            limit = start + bidi.runs[0].limit;
        }
        return new BidiRun(start, limit, level);
    }

    /* in trivial cases there is only one trivial run; called by getRuns() */
    static void getSingleRun(Bidi bidi, byte level) {
        /* simple, single-run case */
        bidi.runs = bidi.simpleRuns;
        bidi.runCount = 1;

        /* fill and reorder the single run */
        bidi.runs[0] = new BidiRun(0, bidi.length, level);
    }

    /* reorder the runs array (L2) ---------------------------------------------- */

    /*
     * Reorder the same-level runs in the runs array.
     * Here, runCount>1 and maxLevel>=minLevel>=paraLevel.
     * All the visualStart fields=logical start before reordering.
     * The "odd" bits are not set yet.
     *
     * Reordering with this data structure lends itself to some handy shortcuts:
     *
     * Since each run is moved but not modified, and since at the initial maxLevel
     * each sequence of same-level runs consists of only one run each, we
     * don't need to do anything there and can predecrement maxLevel.
     * In many simple cases, the reordering is thus done entirely in the
     * index mapping.
     * Also, reordering occurs only down to the lowest odd level that occurs,
     * which is minLevel|1. However, if the lowest level itself is odd, then
     * in the last reordering the sequence of the runs at this level or higher
     * will be all runs, and we don't need the elaborate loop to search for them.
     * This is covered by ++minLevel instead of minLevel|=1 followed
     * by an extra reorder-all after the reorder-some loop.
     * About a trailing WS run:
     * Such a run would need special treatment because its level is not
     * reflected in levels[] if this is not a paragraph object.
     * Instead, all characters from trailingWSStart on are implicitly at
     * paraLevel.
     * However, for all maxLevel>paraLevel, this run will never be reordered
     * and does not need to be taken into account. maxLevel==paraLevel is only reordered
     * if minLevel==paraLevel is odd, which is done in the extra segment.
     * This means that for the main reordering loop we don't need to consider
     * this run and can --runCount. If it is later part of the all-runs
     * reordering, then runCount is adjusted accordingly.
     */
    private static void reorderLine(Bidi bidi, byte minLevel, byte maxLevel) {

        /* nothing to do? */
        if (maxLevel<=(minLevel|1)) {
            return;
        }

        BidiRun[] runs;
        BidiRun tempRun;
        byte[] levels;
        int firstRun, endRun, limitRun, runCount;

        /*
         * Reorder only down to the lowest odd level
         * and reorder at an odd minLevel in a separate, simpler loop.
         * See comments above for why minLevel is always incremented.
         */
        ++minLevel;

        runs = bidi.runs;
        levels = bidi.levels;
        runCount = bidi.runCount;

        /* do not include the WS run at paraLevel<=old minLevel except in the simple loop */
        if (bidi.trailingWSStart < bidi.length) {
            --runCount;
        }

        while (--maxLevel >= minLevel) {
            firstRun = 0;

            /* loop for all sequences of runs */
            for ( ; ; ) {
                /* look for a sequence of runs that are all at >=maxLevel */
                /* look for the first run of such a sequence */
                while (firstRun < runCount && levels[runs[firstRun].start] < maxLevel) {
                    ++firstRun;
                }
                if (firstRun >= runCount) {
                    break;  /* no more such runs */
                }

                /* look for the limit run of such a sequence (the run behind it) */
                for (limitRun = firstRun; ++limitRun < runCount &&
                      levels[runs[limitRun].start]>=maxLevel; ) {}

                /* Swap the entire sequence of runs from firstRun to limitRun-1. */
                endRun = limitRun - 1;
                while (firstRun < endRun) {
                    tempRun = runs[firstRun];
                    runs[firstRun] = runs[endRun];
                    runs[endRun] = tempRun;
                    ++firstRun;
                    --endRun;
                }

                if (limitRun == runCount) {
                    break;  /* no more such runs */
                } else {
                    firstRun = limitRun + 1;
                }
            }
        }

        /* now do maxLevel==old minLevel (==odd!), see above */
        if ((minLevel & 1) == 0) {
            firstRun = 0;

            /* include the trailing WS run in this complete reordering */
            if (bidi.trailingWSStart == bidi.length) {
                --runCount;
            }

            /* Swap the entire sequence of all runs. (endRun==runCount) */
            while (firstRun < runCount) {
                tempRun = runs[firstRun];
                runs[firstRun] = runs[runCount];
                runs[runCount] = tempRun;
                ++firstRun;
                --runCount;
            }
        }
    }

    /* compute the runs array --------------------------------------------------- */

    static int getRunFromLogicalIndex(Bidi bidi, int logicalIndex) {
        BidiRun[] runs = bidi.runs;
        int runCount = bidi.runCount, visualStart = 0, i, length, logicalStart;

        for (i = 0; i < runCount; i++) {
            length = runs[i].limit - visualStart;
            logicalStart = runs[i].start;
            if ((logicalIndex >= logicalStart) && (logicalIndex < (logicalStart+length))) {
                return i;
            }
            visualStart += length;
        }
        /* we should never get here */
        throw new IllegalStateException("Internal ICU error in getRunFromLogicalIndex");
    }

    /*
     * Compute the runs array from the levels array.
     * After getRuns() returns true, runCount is guaranteed to be >0
     * and the runs are reordered.
     * Odd-level runs have visualStart on their visual right edge and
     * they progress visually to the left.
     * If option OPTION_INSERT_MARKS is set, insertRemove will contain the
     * sum of appropriate LRM/RLM_BEFORE/AFTER flags.
     * If option OPTION_REMOVE_CONTROLS is set, insertRemove will contain the
     * negative number of BiDi control characters within this run.
     */
    static void getRuns(Bidi bidi) {
        /*
         * This method returns immediately if the runs are already set. This
         * includes the case of length==0 (handled in setPara)..
         */
        if (bidi.runCount >= 0) {
            return;
        }
        if (bidi.direction != Bidi.MIXED) {
            /* simple, single-run case - this covers length==0 */
            /* bidi.paraLevel is ok even for contextual multiple paragraphs */
            getSingleRun(bidi, bidi.paraLevel);
        } else /* Bidi.MIXED, length>0 */ {
            /* mixed directionality */
            int length = bidi.length, limit;
            byte[] levels = bidi.levels;
            int i, runCount;
            byte level = Bidi.LEVEL_DEFAULT_LTR;   /* initialize with no valid level */
            /*
             * If there are WS characters at the end of the line
             * and the run preceding them has a level different from
             * paraLevel, then they will form their own run at paraLevel (L1).
             * Count them separately.
             * We need some special treatment for this in order to not
             * modify the levels array which a line Bidi object shares
             * with its paragraph parent and its other line siblings.
             * In other words, for the trailing WS, it may be
             * levels[]!=paraLevel but we have to treat it like it were so.
             */
            limit = bidi.trailingWSStart;
            /* count the runs, there is at least one non-WS run, and limit>0 */
            runCount = 0;
            for (i = 0; i < limit; ++i) {
                /* increment runCount at the start of each run */
                if (levels[i] != level) {
                    ++runCount;
                    level = levels[i];
                }
            }

            /*
             * We don't need to see if the last run can be merged with a trailing
             * WS run because setTrailingWSStart() would have done that.
             */
            if (runCount == 1 && limit == length) {
                /* There is only one non-WS run and no trailing WS-run. */
                getSingleRun(bidi, levels[0]);
            } else /* runCount>1 || limit<length */ {
                /* allocate and set the runs */
                BidiRun[] runs;
                int runIndex, start;
                byte minLevel = Bidi.MAX_EXPLICIT_LEVEL + 1;
                byte maxLevel=0;

                /* now, count a (non-mergeable) WS run */
                if (limit < length) {
                    ++runCount;
                }

                /* runCount > 1 */
                bidi.getRunsMemory(runCount);
                runs = bidi.runsMemory;

                /* set the runs */
                /* FOOD FOR THOUGHT: this could be optimized, e.g.:
                 * 464->444, 484->444, 575->555, 595->555
                 * However, that would take longer. Check also how it would
                 * interact with BiDi control removal and inserting Marks.
                 */
                runIndex = 0;

                /* search for the run limits and initialize visualLimit values with the run lengths */
                i = 0;
                do {
                    /* prepare this run */
                    start = i;
                    level = levels[i];
                    if (level < minLevel) {
                        minLevel = level;
                    }
                    if (level > maxLevel) {
                        maxLevel = level;
                    }

                    /* look for the run limit */
                    while (++i < limit && levels[i] == level) {}

                    /* i is another run limit */
                    runs[runIndex] = new BidiRun(start, i - start, level);
                    ++runIndex;
                } while (i < limit);

                if (limit < length) {
                    /* there is a separate WS run */
                    runs[runIndex] = new BidiRun(limit, length - limit, bidi.paraLevel);
                    /* For the trailing WS run, bidi.paraLevel is ok even
                       if contextual multiple paragraphs.                   */
                    if (bidi.paraLevel < minLevel) {
                        minLevel = bidi.paraLevel;
                    }
                }

                /* set the object fields */
                bidi.runs = runs;
                bidi.runCount = runCount;

                reorderLine(bidi, minLevel, maxLevel);

                /* now add the direction flags and adjust the visualLimit's to be just that */
                /* this loop will also handle the trailing WS run */
                limit = 0;
                for (i = 0; i < runCount; ++i) {
                    runs[i].level = levels[runs[i].start];
                    limit = (runs[i].limit += limit);
                }

                /* Set the embedding level for the trailing WS run. */
                /* For a RTL paragraph, it will be the *first* run in visual order. */
                /* For the trailing WS run, bidi.paraLevel is ok even if
                   contextual multiple paragraphs.                          */
                if (runIndex < runCount) {
                    int trailingRun = ((bidi.paraLevel & 1) != 0)? 0 : runIndex;
                    runs[trailingRun].level = bidi.paraLevel;
                }
            }
        }

        /* handle insert LRM/RLM BEFORE/AFTER run */
        if (bidi.insertPoints.size > 0) {
            Bidi.Point point;
            int runIndex, ip;
            for (ip = 0; ip < bidi.insertPoints.size; ip++) {
                point = bidi.insertPoints.points[ip];
                runIndex = getRunFromLogicalIndex(bidi, point.pos);
                bidi.runs[runIndex].insertRemove |= point.flag;
            }
        }

        /* handle remove BiDi control characters */
        if (bidi.controlCount > 0) {
            int runIndex, ic;
            char c;
            for (ic = 0; ic < bidi.length; ic++) {
                c = bidi.text[ic];
                if (Bidi.IsBidiControlChar(c)) {
                    runIndex = getRunFromLogicalIndex(bidi, ic);
                    bidi.runs[runIndex].insertRemove--;
                }
            }
        }
    }

    static int[] prepareReorder(byte[] levels, byte[] pMinLevel, byte[] pMaxLevel)
    {
        int start;
        byte level, minLevel, maxLevel;

        if (levels == null || levels.length <= 0) {
            return null;
        }

        /* determine minLevel and maxLevel */
        minLevel = Bidi.MAX_EXPLICIT_LEVEL + 1;
        maxLevel = 0;
        for (start = levels.length; start>0; ) {
            level = levels[--start];
            if (level > Bidi.MAX_EXPLICIT_LEVEL + 1) {
                return null;
            }
            if (level < minLevel) {
                minLevel = level;
            }
            if (level > maxLevel) {
                maxLevel = level;
            }
        }
        pMinLevel[0] = minLevel;
        pMaxLevel[0] = maxLevel;

        /* initialize the index map */
        int[] indexMap = new int[levels.length];
        for (start = levels.length; start > 0; ) {
            --start;
            indexMap[start] = start;
        }

        return indexMap;
    }

    static int[] reorderLogical(byte[] levels)
    {
        byte[] aMinLevel = new byte[1];
        byte[] aMaxLevel = new byte[1];
        int start, limit, sumOfSosEos;
        byte minLevel, maxLevel;
        int[] indexMap = prepareReorder(levels, aMinLevel, aMaxLevel);
        if (indexMap == null) {
            return null;
        }

        minLevel = aMinLevel[0];
        maxLevel = aMaxLevel[0];

        /* nothing to do? */
        if (minLevel == maxLevel && (minLevel & 1) == 0) {
            return indexMap;
        }

        /* reorder only down to the lowest odd level */
        minLevel |= 1;

        /* loop maxLevel..minLevel */
        do {
            start = 0;

            /* loop for all sequences of levels to reorder at the current maxLevel */
            for ( ; ; ) {
                /* look for a sequence of levels that are all at >=maxLevel */
                /* look for the first index of such a sequence */
                while (start < levels.length && levels[start] < maxLevel) {
                    ++start;
                }
                if (start >= levels.length) {
                    break;  /* no more such sequences */
                }

                /* look for the limit of such a sequence (the index behind it) */
                for (limit = start; ++limit < levels.length && levels[limit] >= maxLevel; ) {}

                /*
                 * sos=start of sequence, eos=end of sequence
                 *
                 * The closed (inclusive) interval from sos to eos includes all the logical
                 * and visual indexes within this sequence. They are logically and
                 * visually contiguous and in the same range.
                 *
                 * For each run, the new visual index=sos+eos-old visual index;
                 * we pre-add sos+eos into sumOfSosEos ->
                 * new visual index=sumOfSosEos-old visual index;
                 */
                sumOfSosEos = start + limit - 1;

                /* reorder each index in the sequence */
                do {
                    indexMap[start] = sumOfSosEos - indexMap[start];
                } while (++start < limit);

                /* start==limit */
                if (limit == levels.length) {
                    break;  /* no more such sequences */
                } else {
                    start = limit + 1;
                }
            }
        } while (--maxLevel >= minLevel);
        return indexMap;
    }

    static int[] reorderVisual(byte[] levels)
    {
        byte[] aMinLevel = new byte[1];
        byte[] aMaxLevel = new byte[1];
        int start, end, limit, temp;
        byte minLevel, maxLevel;

        int[] indexMap = prepareReorder(levels, aMinLevel, aMaxLevel);
        if (indexMap == null) {
            return null;
        }

        minLevel = aMinLevel[0];
        maxLevel = aMaxLevel[0];

        /* nothing to do? */
        if (minLevel == maxLevel && (minLevel & 1) == 0) {
            return indexMap;
        }

        /* reorder only down to the lowest odd level */
        minLevel |= 1;

        /* loop maxLevel..minLevel */
        do {
            start = 0;

            /* loop for all sequences of levels to reorder at the current maxLevel */
            for ( ; ; ) {
                /* look for a sequence of levels that are all at >=maxLevel */
                /* look for the first index of such a sequence */
                while (start < levels.length && levels[start] < maxLevel) {
                    ++start;
                }
                if (start >= levels.length) {
                    break;  /* no more such runs */
                }

                /* look for the limit of such a sequence (the index behind it) */
                for (limit = start; ++limit < levels.length && levels[limit] >= maxLevel; ) {}

                /*
                 * Swap the entire interval of indexes from start to limit-1.
                 * We don't need to swap the levels for the purpose of this
                 * algorithm: the sequence of levels that we look at does not
                 * move anyway.
                 */
                end = limit - 1;
                while (start < end) {
                    temp = indexMap[start];
                    indexMap[start] = indexMap[end];
                    indexMap[end] = temp;

                    ++start;
                    --end;
                }

                if (limit == levels.length) {
                    break;  /* no more such sequences */
                } else {
                    start = limit + 1;
                }
            }
        } while (--maxLevel >= minLevel);

        return indexMap;
    }

    static int getVisualIndex(Bidi bidi, int logicalIndex)
    {
        int visualIndex = Bidi.MAP_NOWHERE;

        /* we can do the trivial cases without the runs array */
        switch(bidi.direction) {
        case Bidi.LTR:
            visualIndex = logicalIndex;
            break;
        case Bidi.RTL:
            visualIndex = bidi.length - logicalIndex - 1;
            break;
        default:
            getRuns(bidi);
            BidiRun[] runs = bidi.runs;
            int i, visualStart = 0, offset, length;

            /* linear search for the run, search on the visual runs */
            for (i = 0; i < bidi.runCount; ++i) {
                length = runs[i].limit - visualStart;
                offset = logicalIndex - runs[i].start;
                if (offset >= 0 && offset < length) {
                    if (runs[i].isEvenRun()) {
                        /* LTR */
                        visualIndex = visualStart + offset;
                    } else {
                        /* RTL */
                        visualIndex = visualStart + length - offset - 1;
                    }
                    break;                  /* exit for loop */
                }
                visualStart += length;
            }
            if (i >= bidi.runCount) {
                return Bidi.MAP_NOWHERE;
            }
        }

        if (bidi.insertPoints.size > 0) {
            /* add the number of added marks until the calculated visual index */
            BidiRun runs[] = bidi.runs;
            int i, length, insertRemove;
            int visualStart = 0, markFound = 0;
            for (i = 0; ; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                if ((insertRemove & (Bidi.LRM_BEFORE|Bidi.RLM_BEFORE)) > 0) {
                    markFound++;
                }
                /* is it the run containing the visual index? */
                if (visualIndex < runs[i].limit) {
                    return visualIndex + markFound;
                }
                if ((insertRemove & (Bidi.LRM_AFTER|Bidi.RLM_AFTER)) > 0) {
                    markFound++;
                }
            }
        }
        else if (bidi.controlCount > 0) {
            /* subtract the number of controls until the calculated visual index */
            BidiRun[] runs = bidi.runs;
            int i, j, start, limit, length, insertRemove;
            int visualStart = 0, controlFound = 0;
            char uchar = bidi.text[logicalIndex];
            /* is the logical index pointing to a control ? */
            if (Bidi.IsBidiControlChar(uchar)) {
                return Bidi.MAP_NOWHERE;
            }
            /* loop on runs */
            for (i = 0; ; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                /* calculated visual index is beyond this run? */
                if (visualIndex >= runs[i].limit) {
                    controlFound -= insertRemove;
                    continue;
                }
                /* calculated visual index must be within current run */
                if (insertRemove == 0) {
                    return visualIndex - controlFound;
                }
                if (runs[i].isEvenRun()) {
                    /* LTR: check from run start to logical index */
                    start = runs[i].start;
                    limit = logicalIndex;
                } else {
                    /* RTL: check from logical index to run end */
                    start = logicalIndex + 1;
                    limit = runs[i].start + length;
                }
                for (j = start; j < limit; j++) {
                    uchar = bidi.text[j];
                    if (Bidi.IsBidiControlChar(uchar)) {
                        controlFound++;
                    }
                }
                return visualIndex - controlFound;
            }
        }

        return visualIndex;
    }

    static int getLogicalIndex(Bidi bidi, int visualIndex)
    {
        BidiRun[] runs;
        int i, runCount, start;

        runs = bidi.runs;
        runCount = bidi.runCount;
        if (bidi.insertPoints.size > 0) {
            /* handle inserted LRM/RLM */
            int markFound = 0, insertRemove;
            int visualStart = 0, length;
            /* subtract number of marks until visual index */
            for (i = 0; ; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                if ((insertRemove & (Bidi.LRM_BEFORE|Bidi.RLM_BEFORE)) > 0) {
                    if (visualIndex <= (visualStart+markFound)) {
                        return Bidi.MAP_NOWHERE;
                    }
                    markFound++;
                }
                /* is adjusted visual index within this run? */
                if (visualIndex < (runs[i].limit + markFound)) {
                    visualIndex -= markFound;
                    break;
                }
                if ((insertRemove & (Bidi.LRM_AFTER|Bidi.RLM_AFTER)) > 0) {
                    if (visualIndex == (visualStart + length + markFound)) {
                        return Bidi.MAP_NOWHERE;
                    }
                    markFound++;
                }
            }
        }
        else if (bidi.controlCount > 0) {
            /* handle removed BiDi control characters */
            int controlFound = 0, insertRemove, length;
            int logicalStart, logicalEnd, visualStart = 0, j, k;
            char uchar;
            boolean evenRun;
            /* add number of controls until visual index */
            for (i = 0; ; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                /* is adjusted visual index beyond current run? */
                if (visualIndex >= (runs[i].limit - controlFound + insertRemove)) {
                    controlFound -= insertRemove;
                    continue;
                }
                /* adjusted visual index is within current run */
                if (insertRemove == 0) {
                    visualIndex += controlFound;
                    break;
                }
                /* count non-control chars until visualIndex */
                logicalStart = runs[i].start;
                evenRun = runs[i].isEvenRun();
                logicalEnd = logicalStart + length - 1;
                for (j = 0; j < length; j++) {
                    k= evenRun ? logicalStart+j : logicalEnd-j;
                    uchar = bidi.text[k];
                    if (Bidi.IsBidiControlChar(uchar)) {
                        controlFound++;
                    }
                    if ((visualIndex + controlFound) == (visualStart + j)) {
                        break;
                    }
                }
                visualIndex += controlFound;
                break;
            }
        }
        /* handle all cases */
        if (runCount <= 10) {
            /* linear search for the run */
            for (i = 0; visualIndex >= runs[i].limit; ++i) {}
        } else {
            /* binary search for the run */
            int begin = 0, limit = runCount;

            /* the middle if() is guaranteed to find the run, we don't need a loop limit */
            for ( ; ; ) {
                i = (begin + limit) / 2;
                if (visualIndex >= runs[i].limit) {
                    begin = i + 1;
                } else if (i==0 || visualIndex >= runs[i-1].limit) {
                    break;
                } else {
                    limit = i;
                }
            }
        }

        start= runs[i].start;
        if (runs[i].isEvenRun()) {
            /* LTR */
            /* the offset in runs[i] is visualIndex-runs[i-1].visualLimit */
            if (i > 0) {
                visualIndex -= runs[i - 1].limit;
            }
            return start + visualIndex;
        } else {
            /* RTL */
            return start + runs[i].limit - visualIndex - 1;
        }
    }

    static int[] getLogicalMap(Bidi bidi)
    {
        /* fill a logical-to-visual index map using the runs[] */
        BidiRun[] runs = bidi.runs;
        int logicalStart, visualStart, logicalLimit, visualLimit;
        int[] indexMap = new int[bidi.length];
        if (bidi.length > bidi.resultLength) {
            Arrays.fill(indexMap, Bidi.MAP_NOWHERE);
        }

        visualStart = 0;
        for (int j = 0; j < bidi.runCount; ++j) {
            logicalStart = runs[j].start;
            visualLimit = runs[j].limit;
            if (runs[j].isEvenRun()) {
                do { /* LTR */
                    indexMap[logicalStart++] = visualStart++;
                } while (visualStart < visualLimit);
            } else {
                logicalStart += visualLimit - visualStart;  /* logicalLimit */
                do { /* RTL */
                    indexMap[--logicalStart] = visualStart++;
                } while (visualStart < visualLimit);
            }
            /* visualStart==visualLimit; */
        }

        if (bidi.insertPoints.size > 0) {
            int markFound = 0, runCount = bidi.runCount;
            int length, insertRemove, i, j;
            runs = bidi.runs;
            visualStart = 0;
            /* add number of marks found until each index */
            for (i = 0; i < runCount; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                if ((insertRemove & (Bidi.LRM_BEFORE|Bidi.RLM_BEFORE)) > 0) {
                    markFound++;
                }
                if (markFound > 0) {
                    logicalStart = runs[i].start;
                    logicalLimit = logicalStart + length;
                    for (j = logicalStart; j < logicalLimit; j++) {
                        indexMap[j] += markFound;
                    }
                }
                if ((insertRemove & (Bidi.LRM_AFTER|Bidi.RLM_AFTER)) > 0) {
                    markFound++;
                }
            }
        }
        else if (bidi.controlCount > 0) {
            int controlFound = 0, runCount = bidi.runCount;
            int length, insertRemove, i, j, k;
            boolean evenRun;
            char uchar;
            runs = bidi.runs;
            visualStart = 0;
            /* subtract number of controls found until each index */
            for (i = 0; i < runCount; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                /* no control found within previous runs nor within this run */
                if ((controlFound - insertRemove) == 0) {
                    continue;
                }
                logicalStart = runs[i].start;
                evenRun = runs[i].isEvenRun();
                logicalLimit = logicalStart + length;
                /* if no control within this run */
                if (insertRemove == 0) {
                    for (j = logicalStart; j < logicalLimit; j++) {
                        indexMap[j] -= controlFound;
                    }
                    continue;
                }
                for (j = 0; j < length; j++) {
                    k = evenRun ? logicalStart + j : logicalLimit - j - 1;
                    uchar = bidi.text[k];
                    if (Bidi.IsBidiControlChar(uchar)) {
                        controlFound++;
                        indexMap[k] = Bidi.MAP_NOWHERE;
                        continue;
                    }
                    indexMap[k] -= controlFound;
                }
            }
        }
        return indexMap;
    }

    static int[] getVisualMap(Bidi bidi)
    {
        /* fill a visual-to-logical index map using the runs[] */
        BidiRun[] runs = bidi.runs;
        int logicalStart, visualStart, visualLimit;
        int allocLength = bidi.length > bidi.resultLength ? bidi.length
                                                          : bidi.resultLength;
        int[] indexMap = new int[allocLength];

        visualStart = 0;
        int idx = 0;
        for (int j = 0; j < bidi.runCount; ++j) {
            logicalStart = runs[j].start;
            visualLimit = runs[j].limit;
            if (runs[j].isEvenRun()) {
                do { /* LTR */
                    indexMap[idx++] = logicalStart++;
                } while (++visualStart < visualLimit);
            } else {
                logicalStart += visualLimit - visualStart;  /* logicalLimit */
                do { /* RTL */
                    indexMap[idx++] = --logicalStart;
                } while (++visualStart < visualLimit);
            }
            /* visualStart==visualLimit; */
        }

        if (bidi.insertPoints.size > 0) {
            int markFound = 0, runCount = bidi.runCount;
            int insertRemove, i, j, k;
            runs = bidi.runs;
            /* count all inserted marks */
            for (i = 0; i < runCount; i++) {
                insertRemove = runs[i].insertRemove;
                if ((insertRemove & (Bidi.LRM_BEFORE|Bidi.RLM_BEFORE)) > 0) {
                    markFound++;
                }
                if ((insertRemove & (Bidi.LRM_AFTER|Bidi.RLM_AFTER)) > 0) {
                    markFound++;
                }
            }
            /* move back indexes by number of preceding marks */
            k = bidi.resultLength;
            for (i = runCount - 1; i >= 0 && markFound > 0; i--) {
                insertRemove = runs[i].insertRemove;
                if ((insertRemove & (Bidi.LRM_AFTER|Bidi.RLM_AFTER)) > 0) {
                    indexMap[--k] = Bidi.MAP_NOWHERE;
                    markFound--;
                }
                visualStart = i > 0 ? runs[i-1].limit : 0;
                for (j = runs[i].limit - 1; j >= visualStart && markFound > 0; j--) {
                    indexMap[--k] = indexMap[j];
                }
                if ((insertRemove & (Bidi.LRM_BEFORE|Bidi.RLM_BEFORE)) > 0) {
                    indexMap[--k] = Bidi.MAP_NOWHERE;
                    markFound--;
                }
            }
        }
        else if (bidi.controlCount > 0) {
            int runCount = bidi.runCount, logicalEnd;
            int insertRemove, length, i, j, k, m;
            char uchar;
            boolean evenRun;
            runs = bidi.runs;
            visualStart = 0;
            /* move forward indexes by number of preceding controls */
            k = 0;
            for (i = 0; i < runCount; i++, visualStart += length) {
                length = runs[i].limit - visualStart;
                insertRemove = runs[i].insertRemove;
                /* if no control found yet, nothing to do in this run */
                if ((insertRemove == 0) && (k == visualStart)) {
                    k += length;
                    continue;
                }
                /* if no control in this run */
                if (insertRemove == 0) {
                    visualLimit = runs[i].limit;
                    for (j = visualStart; j < visualLimit; j++) {
                        indexMap[k++] = indexMap[j];
                    }
                    continue;
                }
                logicalStart = runs[i].start;
                evenRun = runs[i].isEvenRun();
                logicalEnd = logicalStart + length - 1;
                for (j = 0; j < length; j++) {
                    m = evenRun ? logicalStart + j : logicalEnd - j;
                    uchar = bidi.text[m];
                    if (!Bidi.IsBidiControlChar(uchar)) {
                        indexMap[k++] = m;
                    }
                }
            }
        }
        if (allocLength == bidi.resultLength) {
            return indexMap;
        }
        int[] newMap = new int[bidi.resultLength];
        System.arraycopy(indexMap, 0, newMap, 0, bidi.resultLength);
        return newMap;
    }

    static int[] invertMap(int[] srcMap)
    {
        int srcLength = srcMap.length;
        int destLength = -1, count = 0, i, srcEntry;

        /* find highest value and count positive indexes in srcMap */
        for (i = 0; i < srcLength; i++) {
            srcEntry = srcMap[i];
            if (srcEntry > destLength) {
                destLength = srcEntry;
            }
            if (srcEntry >= 0) {
                count++;
            }
        }
        destLength++;           /* add 1 for origin 0 */
        int[] destMap = new int[destLength];
        if (count < destLength) {
            /* we must fill unmatched destMap entries with -1 */
            Arrays.fill(destMap, Bidi.MAP_NOWHERE);
        }
        for (i = 0; i < srcLength; i++) {
            srcEntry = srcMap[i];
            if (srcEntry >= 0) {
                destMap[srcEntry] = i;
            }
        }
        return destMap;
    }
}
