/* Bidi.java -- Bidirectional Algorithm implementation
   Copyright (C) 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.text;

import java.awt.font.NumericShaper;
import java.awt.font.TextAttribute;
import java.util.ArrayList;


/**
 * Bidirectional Algorithm implementation.
 *
 * The full algorithm is
 * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard
 * Annex #9: The Bidirectional Algorithm</a>.
 *
 * @since 1.4
 */
public final class Bidi
{
  /**
   * This indicates that a strongly directional character in the text should
   * set the initial direction, but if no such character is found, then the
   * initial direction will be left-to-right.
   */
  public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2;

  /**
   * This indicates that a strongly directional character in the text should
   * set the initial direction, but if no such character is found, then the
   * initial direction will be right-to-left.
   */
  public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1;

  /**
   * This indicates that the initial direction should be left-to-right.
   */
  public static final int DIRECTION_LEFT_TO_RIGHT = 0;

  /**
   * This indicates that the initial direction should be right-to-left.
   */
  public static final int DIRECTION_RIGHT_TO_LEFT = 1;

  // Flags used when computing the result.
  private static final int LTOR = 1 << DIRECTION_LEFT_TO_RIGHT;
  private static final int RTOL = 1 << DIRECTION_RIGHT_TO_LEFT;

  // The text we are examining, and the starting offset.
  // If we had a better way to handle createLineBidi, we wouldn't
  // need this at all -- which for the String case would be an
  // efficiency win.
  private char[] text;
  private int textOffset;
  // The embeddings corresponding to the text, and the starting offset.
  private byte[] embeddings;
  private int embeddingOffset;
  // The length of the text (and embeddings) to use.
  private int length;
  // The flags.
  private int flags;

  // All instance fields following this point are initialized
  // during analysis.  Fields before this must be set by the constructor.

  // The initial embedding level.
  private int baseEmbedding;
  // The type of each character in the text.
  private byte[] types;
  // The levels we compute.
  private byte[] levels;

  // A list of indices where a formatting code was found.  These
  // are indicies into the original text -- not into the text after
  // the codes have been removed.
  private ArrayList formatterIndices;

  // Indices of the starts of runs in the text. 
  private int[] runs;

  // A convenience field where we keep track of what kinds of runs
  // we've seen.
  private int resultFlags;

  /**
   * Create a new Bidi object given an attributed character iterator.
   * This constructor will examine various attributes of the text:
   * <ul>
   * <li> {@link TextAttribute#RUN_DIRECTION} is used to determine the
   * paragraph's base embedding level.  This constructor will recognize
   * either {@link TextAttribute#RUN_DIRECTION_LTR} or
   * {@link TextAttribute#RUN_DIRECTION_RTL}.  If neither is given,
   * {@link #DIRECTION_DEFAULT_LEFT_TO_RIGHT} is assumed.
   * </li>
   * 
   * <li> If {@link TextAttribute#NUMERIC_SHAPING} is seen, then numeric
   * shaping will be done before the Bidi algorithm is run.
   * </li>
   * 
   * <li> If {@link TextAttribute#BIDI_EMBEDDING} is seen on a given
   * character, then the value of this attribute will be used as an
   * embedding level override.
   * </li>
   * </ul>
   * @param iter the attributed character iterator to use
   */
  public Bidi(AttributedCharacterIterator iter)
  {
    // If set, this attribute should be set on all characters.
    // We don't check this (should we?) but we do assume that we
    // can simply examine the first character.
    Object val = iter.getAttribute(TextAttribute.RUN_DIRECTION);
    if (val == TextAttribute.RUN_DIRECTION_LTR)
      this.flags = DIRECTION_LEFT_TO_RIGHT;
    else if (val == TextAttribute.RUN_DIRECTION_RTL)
      this.flags = DIRECTION_RIGHT_TO_LEFT;
    else
      this.flags = DIRECTION_DEFAULT_LEFT_TO_RIGHT;

    // Likewise this attribute should be specified on the whole text.
    // We read it here and then, if it is set, we apply the numeric shaper
    // to the text before processing it.
    NumericShaper shaper = null;
    val = iter.getAttribute(TextAttribute.NUMERIC_SHAPING);
    if (val instanceof NumericShaper)
      shaper = (NumericShaper) val;

    char[] text = new char[iter.getEndIndex() - iter.getBeginIndex()];
    this.embeddings = new byte[this.text.length];
    this.embeddingOffset = 0;
    this.length = text.length;
    for (int i = 0; i < this.text.length; ++i)
      {
        this.text[i] = iter.current();

        val = iter.getAttribute(TextAttribute.BIDI_EMBEDDING);
        if (val instanceof Integer)
          {
            int ival = ((Integer) val).intValue();
            byte bval;
            if (ival < -62 || ival > 62)
              bval = 0;
            else
              bval = (byte) ival;
            this.embeddings[i] = bval;
          }
      }

    // Invoke the numeric shaper, if specified.
    if (shaper != null)
      shaper.shape(this.text, 0, this.length);

    runBidi();
  }

  /**
   * Create a new Bidi object with the indicated text and, possibly, explicit
   * embedding settings.
   * 
   * If the embeddings array is null, it is ignored.  Otherwise it is taken to
   * be explicit embedding settings corresponding to the text.  Positive values
   * from 1 to 61 are embedding levels, and negative values from -1 to -61 are
   * embedding overrides.  (FIXME: not at all clear what this really means.)
   * 
   * @param text the text to use
   * @param offset the offset of the first character of the text
   * @param embeddings the explicit embeddings, or null if there are none
   * @param embedOffset the offset of the first embedding value to use
   * @param length the length of both the text and the embeddings
   * @param flags a flag indicating the base embedding direction
   */
  public Bidi(char[] text, int offset, byte[] embeddings, int embedOffset,
              int length, int flags)
  {
    if (flags != DIRECTION_DEFAULT_LEFT_TO_RIGHT
        && flags != DIRECTION_DEFAULT_RIGHT_TO_LEFT
        && flags != DIRECTION_LEFT_TO_RIGHT
        && flags != DIRECTION_RIGHT_TO_LEFT)
      throw new IllegalArgumentException("unrecognized 'flags' argument: "
                                         + flags);
    this.text = text;
    this.textOffset = offset;
    this.embeddings = embeddings;
    this.embeddingOffset = embedOffset;
    this.length = length;
    this.flags = flags;

    runBidi();
  }

  /**
   * Create a new Bidi object using the contents of the given String
   * as the text.
   * @param text the text to use
   * @param flags a flag indicating the base embedding direction
   */
  public Bidi(String text, int flags)
  {
    if (flags != DIRECTION_DEFAULT_LEFT_TO_RIGHT
        && flags != DIRECTION_DEFAULT_RIGHT_TO_LEFT
        && flags != DIRECTION_LEFT_TO_RIGHT
        && flags != DIRECTION_RIGHT_TO_LEFT)
      throw new IllegalArgumentException("unrecognized 'flags' argument: "
                                         + flags);

    // This is inefficient, but it isn't clear whether it matters.
    // If it does we can change our implementation a bit to allow either
    // a String or a char[].
    this.text = text.toCharArray();
    this.textOffset = 0;
    this.embeddings = null;
    this.embeddingOffset = 0;
    this.length = text.length();
    this.flags = flags;

    runBidi();
  }

  /**
   * Implementation function which computes the initial type of
   * each character in the input.
   */
  private void computeTypes()
  {
    types = new byte[length];
    for (int i = 0; i < length; ++i)
      types[i] = Character.getDirectionality(text[textOffset + i]);
  }

  /**
   * An internal function which implements rules P2 and P3.
   * This computes the base embedding level.
   * @return the paragraph's base embedding level
   */
  private int computeParagraphEmbeddingLevel()
  {
    // First check to see if the user supplied a directionality override.
    if (flags == DIRECTION_LEFT_TO_RIGHT
        || flags == DIRECTION_RIGHT_TO_LEFT)
      return flags;

    // This implements rules P2 and P3.
    // (Note that we don't need P1, as the user supplies
    // a paragraph.)
    for (int i = 0; i < length; ++i)
      {
        int dir = types[i];
        if (dir == Character.DIRECTIONALITY_LEFT_TO_RIGHT)
          return DIRECTION_LEFT_TO_RIGHT;
        if (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT
            || dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
          return DIRECTION_RIGHT_TO_LEFT;
      }
    return (flags == DIRECTION_DEFAULT_LEFT_TO_RIGHT
            ? DIRECTION_LEFT_TO_RIGHT
            : DIRECTION_RIGHT_TO_LEFT);
  }

  /**
   * An internal function which implements rules X1 through X9.
   * This computes the initial levels for the text, handling
   * explicit overrides and embeddings.
   */
  private void computeExplicitLevels()
  {
    levels = new byte[length];
    byte currentEmbedding = (byte) baseEmbedding;
    // The directional override is a Character directionality
    // constant.  -1 means there is no override.
    byte directionalOverride = -1;
    // The stack of pushed embeddings, and the stack pointer.
    // Note that because the direction is inherent in the depth,
    // and because we have a bit left over in a byte, we can encode
    // the override, if any, directly in this value on the stack.
    final int MAX_DEPTH = 62;
    byte[] embeddingStack = new byte[MAX_DEPTH];
    int sp = 0;

    for (int i = 0; i < length; ++i)
      {
        // If we see an explicit embedding, we use that, even if
        // the current character is itself a directional override.
        if (embeddings != null && embeddings[embeddingOffset + i] != 0)
          {
            // It isn't at all clear what we're supposed to do here.
            // What does a negative value really mean?
            // Should we push on the embedding stack here?
            currentEmbedding = embeddings[embeddingOffset + i]; 
            if (currentEmbedding < 0)
              {
                currentEmbedding = (byte) -currentEmbedding;
                directionalOverride
                  = (((currentEmbedding % 2) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);
              }
            else
              directionalOverride = -1;
            continue;
          }
        // No explicit embedding.
        boolean isLtoR = false;
        boolean isSpecial = true;
        switch (types[i])
          {
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE:
              isLtoR = true;
              // Fall through.
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
              {
                byte newEmbedding;
                if (isLtoR)
                  {
                    // Least greater even.
                    newEmbedding = (byte) ((currentEmbedding & ~1) + 2);
                  }
                else
                  {
                    // Least greater odd.
                    newEmbedding = (byte) ((currentEmbedding + 1) | 1);
                  }
                // FIXME: we don't properly handle invalid pushes.
                if (newEmbedding < MAX_DEPTH)
                  {
                    // The new level is valid.  Push the old value.
                    // See above for a comment on the encoding here.
                    if (directionalOverride != -1)
                      currentEmbedding |= Byte.MIN_VALUE;
                    embeddingStack[sp++] = currentEmbedding;
                    currentEmbedding = newEmbedding;
                    if (types[i] == Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE)
                      directionalOverride = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
                    else if (types[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE)
                      directionalOverride = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
                    else
                      directionalOverride = -1;
                  }
                }
              break;
            case Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT:
              {
                // FIXME: we don't properly handle a pop with a corresponding
                // invalid push.
                if (sp == 0)
                  {
                    // We saw a pop without a push.  Just ignore it.
                    break;
                  }
                byte newEmbedding = embeddingStack[--sp];
                currentEmbedding = (byte) (newEmbedding & 0x7f);
                if (newEmbedding < 0)
                  directionalOverride
                  = (((newEmbedding & 1) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);
                else
                  directionalOverride = -1;
              }
              break;
            default:
              isSpecial = false;
              break;
          }
        levels[i] = currentEmbedding;
        if (isSpecial)
          {
            // Mark this character for removal.
            if (formatterIndices == null)
              formatterIndices = new ArrayList();
            formatterIndices.add(Integer.valueOf(i));
          }
        else if (directionalOverride != -1)
          types[i] = directionalOverride;
      }

    // Remove the formatting codes and update both the arrays
    // and 'length'.  It would be more efficient not to remove
    // these codes, but it is also more complicated.  Also, the
    // Unicode algorithm reference does not properly describe
    // how this is to be done -- from what I can tell, their suggestions
    // in this area will not yield the correct results.
    if (formatterIndices == null)
      return;
    int output = 0, input = 0;
    final int size = formatterIndices.size();
    for (int i = 0; i <= size; ++i)
      {
        int nextFmt;
        if (i == size)
          nextFmt = length;
        else
          nextFmt = ((Integer) formatterIndices.get(i)).intValue();
        // Non-formatter codes are from 'input' to 'nextFmt'.
        int len = nextFmt - input;
        System.arraycopy(levels, input, levels, output, len);
        System.arraycopy(types, input, types, output, len);
        output += len;
        input = nextFmt + 1;
      }
    length -= formatterIndices.size();
  }

  /**
   * An internal function to compute the boundaries of runs
   * in the text.  It isn't strictly necessary to do this, but
   * it lets us write some following passes in a less complicated
   * way.  Also it lets us efficiently implement some of the public
   * methods.  A run is simply a sequence of characters at the
   * same level.
   */
  private void computeRuns()
  {
    int runCount = 0;
    int currentEmbedding = baseEmbedding;
    for (int i = 0; i < length; ++i)
      {
        if (levels[i] != currentEmbedding)
          {
            currentEmbedding = levels[i];
            ++runCount;
          }
      }

    // This may be called multiple times.  If so, and if
    // the number of runs has not changed, then don't bother
    // allocating a new array.
    if (runs == null || runs.length != runCount + 1)
      runs = new int[runCount + 1];
    int where = 0;
    int lastRunStart = 0;
    currentEmbedding = baseEmbedding;
    for (int i = 0; i < length; ++i)
      {
        if (levels[i] != currentEmbedding)
          {
            runs[where++] = lastRunStart;
            lastRunStart = i;
            currentEmbedding = levels[i];
          }
      }
    runs[where++] = lastRunStart;
  }

  /**
   * An internal method to resolve weak types.  This implements
   * rules W1 through W7.
   */
  private void resolveWeakTypes()
  {
    final int runCount = getRunCount();
    
    int previousLevel = baseEmbedding;
    for (int run = 0; run < runCount; ++run)
      {
        int start = getRunStart(run);
        int end = getRunLimit(run);
        int level = getRunLevel(run);

        // These are the names used in the Bidi algorithm.
        byte sor = (((Math.max(previousLevel, level) % 2) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);
        int nextLevel;
        if (run == runCount - 1)
          nextLevel = baseEmbedding;
        else
          nextLevel = getRunLevel(run + 1);
        byte eor = (((Math.max(level, nextLevel) % 2) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);

        byte prevType = sor;
        byte prevStrongType = sor;
        for (int i = start; i < end; ++i)
          {
            final byte nextType = (i == end - 1) ? eor : types[i + 1];

            // Rule W1: change NSM to the prevailing direction.
            if (types[i] == Character.DIRECTIONALITY_NONSPACING_MARK)
              types[i] = prevType;
            else
              prevType = types[i];

            // Rule W2: change EN to AN in some cases.
            if (types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
              {
                if (prevStrongType == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
                  types[i] = Character.DIRECTIONALITY_ARABIC_NUMBER;
              }
            else if (types[i] == Character.DIRECTIONALITY_LEFT_TO_RIGHT
                     || types[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT
                     || types[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
              prevStrongType = types[i];

            // Rule W3: change AL to R.
            if (types[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
              types[i] = Character.DIRECTIONALITY_RIGHT_TO_LEFT;

            // Rule W4: handle separators between two numbers.
            if (prevType == Character.DIRECTIONALITY_EUROPEAN_NUMBER
                && nextType == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
              {
                if (types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
                    || types[i] == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR)
                  types[i] = nextType;
              }
            else if (prevType == Character.DIRECTIONALITY_ARABIC_NUMBER
                     && nextType == Character.DIRECTIONALITY_ARABIC_NUMBER
                     && types[i] == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR)
              types[i] = nextType;

            // Rule W5: change a sequence of european terminators to
            // european numbers, if they are adjacent to european numbers.
            // We also include BN characters in this.
            if (types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
                || types[i] == Character.DIRECTIONALITY_BOUNDARY_NEUTRAL)
              {
                if (prevType == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
                  types[i] = prevType;
                else
                  {
                    // Look ahead to see if there is an EN terminating this
                    // sequence of ETs.
                    int j = i + 1;
                    while (j < end
                           && (types[j] == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
                               || types[j] == Character.DIRECTIONALITY_BOUNDARY_NEUTRAL))
                      ++j;
                    if (j < end
                        && types[j] == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
                      {
                        // Change them all to EN now.
                        for (int k = i; k < j; ++k)
                          types[k] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
                      }
                  }
              }

            // Rule W6: separators and terminators change to ON.
            // Again we include BN.
            if (types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
                || types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
                || types[i] == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
                || types[i] == Character.DIRECTIONALITY_BOUNDARY_NEUTRAL)
              types[i] = Character.DIRECTIONALITY_OTHER_NEUTRALS;

            // Rule W7: change european number types.
            if (prevStrongType == Character.DIRECTIONALITY_LEFT_TO_RIGHT
                && types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
              types[i] = prevStrongType;
          }

        previousLevel = level;
      }
  }

  /**
   * An internal method to resolve neutral types.  This implements
   * rules N1 and N2.
   */
  private void resolveNeutralTypes()
  {
    // This implements rules N1 and N2.
    final int runCount = getRunCount();
    
    int previousLevel = baseEmbedding;
    for (int run = 0; run < runCount; ++run)
      {
        int start = getRunStart(run);
        int end = getRunLimit(run);
        int level = getRunLevel(run);

        byte embeddingDirection
          = (((level % 2) == 0) ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                                : Character.DIRECTIONALITY_RIGHT_TO_LEFT);
        // These are the names used in the Bidi algorithm.
        byte sor = (((Math.max(previousLevel, level) % 2) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);
        int nextLevel;
        if (run == runCount - 1)
          nextLevel = baseEmbedding;
        else
          nextLevel = getRunLevel(run + 1);
        byte eor = (((Math.max(level, nextLevel) % 2) == 0)
                      ? Character.DIRECTIONALITY_LEFT_TO_RIGHT
                      : Character.DIRECTIONALITY_RIGHT_TO_LEFT);

        byte prevStrong = sor;
        int neutralStart = -1;
        for (int i = start; i <= end; ++i)
          {
            byte newStrong = -1;
            byte thisType = i == end ? eor : types[i];
            switch (thisType)
              {
              case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
                newStrong = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
                break;
              case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
              case Character.DIRECTIONALITY_ARABIC_NUMBER:
              case Character.DIRECTIONALITY_EUROPEAN_NUMBER:
                newStrong = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
                break;
              case Character.DIRECTIONALITY_BOUNDARY_NEUTRAL:
              case Character.DIRECTIONALITY_OTHER_NEUTRALS:
              case Character.DIRECTIONALITY_SEGMENT_SEPARATOR:
              case Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR:
	      case Character.DIRECTIONALITY_WHITESPACE:
                if (neutralStart == -1)
                  neutralStart = i;
                break;
              }
            // If we see a strong character, update all the neutrals.
            if (newStrong != -1)
              {
                if (neutralStart != -1)
                  {
                    byte override = (prevStrong == newStrong
                                     ? prevStrong
                                     : embeddingDirection);
                    for (int j = neutralStart; j < i; ++j)
                      types[j] = override;
                  }
                prevStrong = newStrong;
                neutralStart = -1;
              }
          }

        previousLevel = level;
      }
  }

  /**
   * An internal method to resolve implicit levels.
   * This implements rules I1 and I2.
   */
  private void resolveImplicitLevels()
  {
    // This implements rules I1 and I2.
    for (int i = 0; i < length; ++i)
      {
        if ((levels[i] & 1) == 0)
          {
            if (types[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
              ++levels[i];
            else if (types[i] == Character.DIRECTIONALITY_ARABIC_NUMBER
                     || types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
              levels[i] += 2;
          }
        else
          {
            if (types[i] == Character.DIRECTIONALITY_LEFT_TO_RIGHT
                || types[i] == Character.DIRECTIONALITY_ARABIC_NUMBER
                || types[i] == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
              ++levels[i];
          }

        // Update the result flags.
        resultFlags |= 1 << (levels[i] & 1);
      }
    // One final update of the result flags, using the base level.
    resultFlags |= 1 << baseEmbedding;
  }

  /**
   * This reinserts the formatting codes that we removed early on.
   * Actually it does not insert formatting codes per se, but rather
   * simply inserts new levels at the appropriate locations in the
   * 'levels' array.
   */
  private void reinsertFormattingCodes()
  {
    if (formatterIndices == null)
      return;
    int input = length;
    int output = levels.length;
    // Process from the end as we are copying the array over itself here.
    for (int index = formatterIndices.size() - 1; index >= 0; --index)
      {
        int nextFmt = ((Integer) formatterIndices.get(index)).intValue();

        // nextFmt points to a location in the original array.  So,
        // nextFmt+1 is the target of our copying.  output is the location
        // to which we last copied, thus we can derive the length of the
        // copy from it.
        int len = output - nextFmt - 1;
        output = nextFmt;
        input -= len;
        // Note that we no longer need 'types' at this point, so we
        // only edit 'levels'.
        if (nextFmt + 1 < levels.length)
          System.arraycopy(levels, input, levels, nextFmt + 1, len);

        // Now set the level at the reinsertion point.
        int rightLevel;
        if (output == levels.length - 1)
          rightLevel = baseEmbedding;
        else
          rightLevel = levels[output + 1];
        int leftLevel;
        if (input == 0)
          leftLevel = baseEmbedding;
        else
          leftLevel = levels[input];
        levels[output] = (byte) Math.max(leftLevel, rightLevel);
      }
    length = levels.length;
  }

  /**
   * This is the main internal entry point.  After a constructor
   * has initialized the appropriate local state, it will call
   * this method to do all the work.
   */
  private void runBidi()
  {
    computeTypes();
    baseEmbedding = computeParagraphEmbeddingLevel();
    computeExplicitLevels();
    computeRuns();
    resolveWeakTypes();
    resolveNeutralTypes();
    resolveImplicitLevels();
    // We're done with the types.  Let the GC clean up.
    types = null;
    reinsertFormattingCodes();
    // After resolving the implicit levels, the number
    // of runs may have changed.
    computeRuns();
  }

  /**
   * Return true if the paragraph base embedding is left-to-right,
   * false otherwise.
   */
  public boolean baseIsLeftToRight()
  {
    return baseEmbedding == DIRECTION_LEFT_TO_RIGHT;
  }

  /**
   * Create a new Bidi object for a single line of text, taken
   * from the text used when creating the current Bidi object.
   * @param start the index of the first character of the line
   * @param end the index of the final character of the line
   * @return a new Bidi object for the indicated line of text
   */
  public Bidi createLineBidi(int start, int end)
  {
    // This isn't the most efficient implementation possible.
    // This probably does not matter, so we choose simplicity instead.
    int level = getLevelAt(start);
    int flag = (((level % 2) == 0)
                ? DIRECTION_LEFT_TO_RIGHT
                : DIRECTION_RIGHT_TO_LEFT);
    return new Bidi(text, textOffset + start,
                    embeddings, embeddingOffset + start,
                    end - start, flag);
  }

  /**
   * Return the base embedding level of the paragraph.
   */
  public int getBaseLevel()
  {
    return baseEmbedding;
  }

  /**
   * Return the length of the paragraph, in characters.
   */
  public int getLength()
  {
    return length;
  }

  /**
   * Return the level at the indicated character.  If the
   * supplied index is less than zero or greater than the length
   * of the text, then the paragraph's base embedding level will
   * be returned.
   * @param offset the character to examine
   * @return the level of that character
   */
  public int getLevelAt(int offset)
  {
    if (offset < 0 || offset >= length)
      return getBaseLevel();
    return levels[offset];
  }

  /**
   * Return the number of runs in the result.  A run is
   * a sequence of characters at the same embedding level.
   */
  public int getRunCount()
  {
    return runs.length;
  }

  /**
   * Return the level of the indicated run.
   * @param which the run to examine
   * @return the level of that run
   */
  public int getRunLevel(int which)
  {
    return levels[runs[which]];
  }

  /**
   * Return the index of the character just following the end
   * of the indicated run.
   * @param which the run to examine
   * @return the index of the character after the final character
   * of the run
   */
  public int getRunLimit(int which)
  {
    if (which == runs.length - 1)
      return length;
    return runs[which + 1];
  }

  /**
   * Return the index of the first character in the indicated run.
   * @param which the run to examine
   * @return the index of the first character of the run
   */
  public int getRunStart(int which)
  {
    return runs[which];
  }

  /**
   * Return true if the text is entirely left-to-right, and the
   * base embedding is also left-to-right.
   */
  public boolean isLeftToRight()
  {
    return resultFlags == LTOR;
  }

  /**
   * Return true if the text consists of mixed left-to-right and
   * right-to-left runs, or if the text consists of one kind of run
   * which differs from the base embedding direction.
   */
  public boolean isMixed()
  {
    return resultFlags == (LTOR | RTOL);
  }

  /**
   * Return true if the text is entirely right-to-left, and the
   * base embedding is also right-to-left.
   */
  public boolean isRightToLeft()
  {
    return resultFlags == RTOL;
  }

  /**
   * Return a String describing the internal state of this object.
   * This is only useful for debugging.
   */
  public String toString()
  {
    return "Bidi Bidi Bidi I like you, Buck!";
  }

  /**
   * Reorder objects according to the levels passed in.  This implements
   * reordering as defined by the Unicode bidirectional layout specification.
   * The levels are integers from 0 to 62; even numbers represent left-to-right
   * runs, and odd numbers represent right-to-left runs.
   *
   * @param levels the levels associated with each object
   * @param levelOffset the index of the first level to use
   * @param objs the objects to reorder according to the levels
   * @param objOffset the index of the first object to use
   * @param count the number of objects (and levels) to manipulate
   */
  public static void reorderVisually(byte[] levels, int levelOffset,
                                     Object[] objs, int objOffset, int count)
  {
    // We need a copy of the 'levels' array, as we are going to modify it.
    // This is unfortunate but difficult to avoid.
    byte[] levelCopy = new byte[count];
    // Do this explicitly so we can also find the maximum depth at the
    // same time.
    int max = 0;
    int lowestOdd = 63;
    for (int i = 0; i < count; ++i)
      {
        levelCopy[i] = levels[levelOffset + i];
        max = Math.max(levelCopy[i], max);
        if (levelCopy[i] % 2 != 0)
          lowestOdd = Math.min(lowestOdd, levelCopy[i]);
      }

    // Reverse the runs starting with the deepest.
    for (int depth = max; depth >= lowestOdd; --depth)
      {
        int start = 0;
        while (start < count)
          {
            // Find the start of a run >= DEPTH.
            while (start < count && levelCopy[start] < depth)
              ++start;
            if (start == count)
              break;
            // Find the end of the run.
            int end = start + 1;
            while (end < count && levelCopy[end] >= depth)
              ++end;

            // Reverse this run.
            for (int i = 0; i < (end - start) / 2; ++i)
              {
                byte tmpb = levelCopy[end - i - 1];
                levelCopy[end - i - 1] = levelCopy[start + i];
                levelCopy[start + i] = tmpb;
                Object tmpo = objs[objOffset + end - i - 1];
                objs[objOffset + end - i - 1] = objs[objOffset + start + i];
                objs[objOffset + start + i] = tmpo;
              }

            // Handle the next run.
            start = end + 1;
          }
      }
  }

  /**
   * Returns false if all characters in the text between start and end
   * are all left-to-right text. This implementation is just calls
   * <code>Character.getDirectionality(char)</code> on all characters
   * and makes sure all characters are either explicitly left-to-right
   * or neutral in directionality (character types L, EN, ES, ET, AN,
   * CS, S and WS).
   */
  public static boolean requiresBidi(char[] text, int start, int end)
  {
    for (int i = start; i < end; i++)
      {
	byte dir = Character.getDirectionality(text[i]);
	if (dir != Character.DIRECTIONALITY_LEFT_TO_RIGHT
	    && dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER
	    && dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
	    && dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
	    && dir != Character.DIRECTIONALITY_ARABIC_NUMBER
	    && dir != Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
	    && dir != Character.DIRECTIONALITY_SEGMENT_SEPARATOR
	    && dir != Character.DIRECTIONALITY_WHITESPACE)
	  return true;
      }

    return false;
  }
}
