/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 *
 * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
 */

package sun.font;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;

import java.awt.font.FontRenderContext;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import java.util.Map;

/**
 * Default implementation of ExtendedTextLabel.
 */

// {jbr} I made this class package-private to keep the
// Decoration.Label API package-private.

/* public */
class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.Label {

  TextSource source;
  private Decoration decorator;

  // caches
  private Font font;
  private AffineTransform baseTX;
  private CoreMetrics cm;

  Rectangle2D lb;
  Rectangle2D ab;
  Rectangle2D vb;
  Rectangle2D ib;
  StandardGlyphVector gv;
  float[] charinfo;

  /**
   * Create from a TextSource.
   */
  public ExtendedTextSourceLabel(TextSource source, Decoration decorator) {
    this.source = source;
    this.decorator = decorator;
    finishInit();
  }

  /**
   * Create from a TextSource, optionally using cached data from oldLabel starting at the offset.
   * If present oldLabel must have been created from a run of text that includes the text used in
   * the new label.  Start in source corresponds to logical character offset in oldLabel.
   */
  public ExtendedTextSourceLabel(TextSource source, ExtendedTextSourceLabel oldLabel, int offset) {
    // currently no optimization.
    this.source = source;
    this.decorator = oldLabel.decorator;
    finishInit();
  }

  private void finishInit() {
    font = source.getFont();

    Map<TextAttribute, ?> atts = font.getAttributes();
    baseTX = AttributeValues.getBaselineTransform(atts);
    if (baseTX == null){
        cm = source.getCoreMetrics();
    } else {
      AffineTransform charTX = AttributeValues.getCharTransform(atts);
      if (charTX == null) {
          charTX = new AffineTransform();
      }
      font = font.deriveFont(charTX);

      LineMetrics lm = font.getLineMetrics(source.getChars(), source.getStart(),
          source.getStart() + source.getLength(), source.getFRC());
      cm = CoreMetrics.get(lm);
    }
  }


  // TextLabel API

  public Rectangle2D getLogicalBounds() {
    return getLogicalBounds(0, 0);
  }

  public Rectangle2D getLogicalBounds(float x, float y) {
    if (lb == null) {
      lb = createLogicalBounds();
    }
    return new Rectangle2D.Float((float)(lb.getX() + x),
                                 (float)(lb.getY() + y),
                                 (float)lb.getWidth(),
                                 (float)lb.getHeight());
  }

    public float getAdvance() {
        if (lb == null) {
            lb = createLogicalBounds();
        }
        return (float)lb.getWidth();
    }

  public Rectangle2D getVisualBounds(float x, float y) {
    if (vb == null) {
      vb = decorator.getVisualBounds(this);
    }
    return new Rectangle2D.Float((float)(vb.getX() + x),
                                 (float)(vb.getY() + y),
                                 (float)vb.getWidth(),
                                 (float)vb.getHeight());
  }

  public Rectangle2D getAlignBounds(float x, float y) {
    if (ab == null) {
      ab = createAlignBounds();
    }
    return new Rectangle2D.Float((float)(ab.getX() + x),
                                 (float)(ab.getY() + y),
                                 (float)ab.getWidth(),
                                 (float)ab.getHeight());

  }

  public Rectangle2D getItalicBounds(float x, float y) {
    if (ib == null) {
      ib = createItalicBounds();
    }
    return new Rectangle2D.Float((float)(ib.getX() + x),
                                 (float)(ib.getY() + y),
                                 (float)ib.getWidth(),
                                 (float)ib.getHeight());

  }

  public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
      return getGV().getPixelBounds(frc, x, y);
  }

  public boolean isSimple() {
      return decorator == Decoration.getPlainDecoration() &&
             baseTX == null;
  }

  public AffineTransform getBaselineTransform() {
      return baseTX; // passing internal object, caller must not modify!
  }

  public Shape handleGetOutline(float x, float y) {
    return getGV().getOutline(x, y);
  }

  public Shape getOutline(float x, float y) {
    return decorator.getOutline(this, x, y);
  }

  public void handleDraw(Graphics2D g, float x, float y) {
    g.drawGlyphVector(getGV(), x, y);
  }

  public void draw(Graphics2D g, float x, float y) {
    decorator.drawTextAndDecorations(this, g, x, y);
  }

  /**
   * The logical bounds extends from the origin of the glyphvector to the
   * position at which a following glyphvector's origin should be placed.
   * We always assume glyph vectors are rendered from left to right, so
   * the origin is always to the left.
   * <p> On a left-to-right run, combining marks and 'ligatured away'
   * characters are to the right of their base characters.  The charinfo
   * array will record the character positions for these 'missing' characters
   * as being at the origin+advance of the base glyph, with zero advance.
   * (This is not necessarily the same as the glyph position, for example,
   * an umlaut glyph may have a position to the left of this point, it depends
   * on whether the font was designed so that such glyphs overhang to the left
   * of their origin, or whether it presumes some kind of kerning to position
   * the glyphs).  Anyway, the left of the bounds is the origin of the first
   * logical (leftmost) character, and the right is the origin + advance of the
   * last logical (rightmost) character.
   * <p> On a right-to-left run, these special characters are to the left
   * of their base characters.  Again, since 'glyph position' has been abstracted
   * away, we can use the origin of the leftmost character, and the origin +
   * advance of the rightmost character.
   * <p> On a mixed run (hindi) we can't rely on the first logical character
   * being the leftmost character.  However we can again rely on the leftmost
   * character origin and the rightmost character + advance.
   */
  protected Rectangle2D createLogicalBounds() {
    return getGV().getLogicalBounds();
  }

  public Rectangle2D handleGetVisualBounds() {
    return getGV().getVisualBounds();
  }

  /**
   * Like createLogicalBounds except ignore leading and logically trailing white space.
   * this assumes logically trailing whitespace is also visually trailing.
   * Whitespace is anything that has a zero visual width, regardless of its advance.
   * <p> We make the same simplifying assumptions as in createLogicalBounds, namely
   * that we can rely on the charinfo to shield us from any glyph positioning oddities
   * in the font that place the glyph for a character at other than the pos + advance
   * of the character to its left.  So we no longer need to skip chars with zero
   * advance, as their bounds (right and left) are already correct.
   */
  protected Rectangle2D createAlignBounds() {
    float[] info = getCharinfo();

    float al = 0f;
    float at = -cm.ascent;
    float aw = 0f;
    float ah = cm.ascent + cm.descent;

    if (charinfo == null || charinfo.length == 0) {
        return new Rectangle2D.Float(al, at, aw, ah);
    }

    boolean lineIsLTR = (source.getLayoutFlags() & 0x8) == 0;
    int rn = info.length - numvals;
    if (lineIsLTR) {
      while (rn > 0 && info[rn+visw] == 0) {
        rn -= numvals;
      }
    }

    if (rn >= 0) {
      int ln = 0;
      while (ln < rn && ((info[ln+advx] == 0) || (!lineIsLTR && info[ln+visw] == 0))) {
        ln += numvals;
      }

      al = Math.max(0f, info[ln+posx]);
      aw = info[rn+posx] + info[rn+advx] - al;
    }

    /*
      boolean lineIsLTR = source.lineIsLTR();
      int rn = info.length - numvals;
      while (rn > 0 && ((info[rn+advx] == 0) || (lineIsLTR && info[rn+visw] == 0))) {
      rn -= numvals;
      }

      if (rn >= 0) {
      int ln = 0;
      while (ln < rn && ((info[ln+advx] == 0) || (!lineIsLTR && info[ln+visw] == 0))) {
      ln += numvals;
      }

      al = Math.max(0f, info[ln+posx]);
      aw = info[rn+posx] + info[rn+advx] - al;
      }
      */

    return new Rectangle2D.Float(al, at, aw, ah);
  }

  public Rectangle2D createItalicBounds() {
    float ia = cm.italicAngle;

    Rectangle2D lb = getLogicalBounds();
    float l = (float)lb.getMinX();
    float t = -cm.ascent;
    float r = (float)lb.getMaxX();
    float b = cm.descent;
    if (ia != 0) {
        if (ia > 0) {
            l -= ia * (b - cm.ssOffset);
            r -= ia * (t - cm.ssOffset);
        } else {
            l -= ia * (t - cm.ssOffset);
            r -= ia * (b - cm.ssOffset);
        }
    }
    return new Rectangle2D.Float(l, t, r - l, b - t);
  }

  private final StandardGlyphVector getGV() {
    if (gv == null) {
      gv = createGV();
    }

    return gv;
  }

  protected StandardGlyphVector createGV() {
    FontRenderContext frc = source.getFRC();
    int flags = source.getLayoutFlags();
    char[] context = source.getChars();
    int start = source.getStart();
    int length = source.getLength();

    GlyphLayout gl = GlyphLayout.get(null); // !!! no custom layout engines
    gv = gl.layout(font, frc, context, start, length, flags, null); // ??? use textsource
    GlyphLayout.done(gl);

    return gv;
  }

  // ExtendedTextLabel API

  private static final int posx = 0,
    posy = 1,
    advx = 2,
    advy = 3,
    visx = 4,
    visy = 5,
    visw = 6,
    vish = 7;
  private static final int numvals = 8;

  public int getNumCharacters() {
    return source.getLength();
  }

  public CoreMetrics getCoreMetrics() {
    return cm;
  }

  public float getCharX(int index) {
    validate(index);
    float[] charinfo = getCharinfo();
    int idx = l2v(index) * numvals + posx;
    if (charinfo == null || idx >= charinfo.length) {
        return 0f;
    } else {
        return charinfo[idx];
    }
  }

  public float getCharY(int index) {
    validate(index);
    float[] charinfo = getCharinfo();
    int idx = l2v(index) * numvals + posy;
    if (charinfo == null || idx >= charinfo.length) {
        return 0f;
    } else {
        return charinfo[idx];
    }
  }

  public float getCharAdvance(int index) {
    validate(index);
    float[] charinfo = getCharinfo();
    int idx = l2v(index) * numvals + advx;
    if (charinfo == null || idx >= charinfo.length) {
        return 0f;
    } else {
        return charinfo[idx];
    }
  }

  public Rectangle2D handleGetCharVisualBounds(int index) {
    validate(index);
    float[] charinfo = getCharinfo();
    index = l2v(index) * numvals;
    if (charinfo == null || (index+vish) >= charinfo.length) {
        return new Rectangle2D.Float();
    }
    return new Rectangle2D.Float(
                                 charinfo[index + visx],
                                 charinfo[index + visy],
                                 charinfo[index + visw],
                                 charinfo[index + vish]);
  }

  public Rectangle2D getCharVisualBounds(int index, float x, float y) {

    Rectangle2D bounds = decorator.getCharVisualBounds(this, index);
    if (x != 0 || y != 0) {
        bounds.setRect(bounds.getX()+x,
                       bounds.getY()+y,
                       bounds.getWidth(),
                       bounds.getHeight());
    }
    return bounds;
  }

  private void validate(int index) {
    if (index < 0) {
      throw new IllegalArgumentException("index " + index + " < 0");
    } else if (index >= source.getLength()) {
      throw new IllegalArgumentException("index " + index + " < " + source.getLength());
    }
  }

  /*
    public int hitTestChar(float x, float y) {
    // !!! return index of char hit, for swing
    // result is negative for trailing-edge hits
    // no italics so no problem at margins.
    // for now, ignore y since we assume horizontal text

    // find non-combining char origin to right of x
    float[] charinfo = getCharinfo();

    int n = 0;
    int e = source.getLength();
    while (n < e && charinfo[n + advx] != 0 && charinfo[n + posx] > x) {
    n += numvals;
    }
    float rightx = n < e ? charinfo[n+posx] : charinfo[e - numvals + posx] + charinfo[e - numvals + advx];

    // find non-combining char to left of that char
    n -= numvals;
    while (n >= 0 && charinfo[n+advx] == 0) {
    n -= numvals;
    }
    float leftx = n >= 0 ? charinfo[n+posx] : 0;
    float lefta = n >= 0 ? charinfo[n+advx] : 0;

    n /= numvals;

    boolean left = true;
    if (x < leftx + lefta / 2f) {
    // left of prev char
    } else if (x < (leftx + lefta + rightx) / 2f) {
    // right of prev char
    left = false;
    } else {
    // left of follow char
    n += 1;
    }

    if ((source.getLayoutFlags() & 0x1) != 0) {
    n = getNumCharacters() - 1 - n;
    left = !left;
    }

    return left ? n : -n;
    }
    */

  public int logicalToVisual(int logicalIndex) {
    validate(logicalIndex);
    return l2v(logicalIndex);
  }

  public int visualToLogical(int visualIndex) {
    validate(visualIndex);
    return v2l(visualIndex);
  }

  public int getLineBreakIndex(int start, float width) {
    float[] charinfo = getCharinfo();
    int length = source.getLength();
    --start;
    while (width >= 0 && ++start < length) {
      int cidx = l2v(start) * numvals + advx;
      if (cidx >= charinfo.length) {
          break; // layout bailed for some reason
      }
      float adv = charinfo[cidx];
      width -= adv;
    }

    return start;
  }

  public float getAdvanceBetween(int start, int limit) {
    float a = 0f;

    float[] charinfo = getCharinfo();
    --start;
    while (++start < limit) {
      int cidx = l2v(start) * numvals + advx;
      if (cidx >= charinfo.length) {
          break; // layout bailed for some reason
      }
      a += charinfo[cidx];
    }

    return a;
  }

  public boolean caretAtOffsetIsValid(int offset) {
      // REMIND: improve this implementation

      // Ligature formation can either be done in logical order,
      // with the ligature glyph logically preceding the null
      // chars;  or in visual order, with the ligature glyph to
      // the left of the null chars.  This method's implementation
      // must reflect which strategy is used.

      if (offset == 0 || offset == source.getLength()) {
          return true;
      }
      char c = source.getChars()[source.getStart() + offset];
      if (c == '\t' || c == '\n' || c == '\r') { // hack
          return true;
      }
      int v = l2v(offset);

      // If ligatures are always to the left, do this stuff:
      //if (!(source.getLayoutFlags() & 0x1) == 0) {
      //    v += 1;
      //    if (v == source.getLength()) {
      //        return true;
      //    }
      //}

      int idx = v * numvals + advx;
      float[] charinfo = getCharinfo();
      if (charinfo == null || idx >= charinfo.length) {
          return false;
      } else {
          return charinfo[idx] != 0;
      }
  }

  private final float[] getCharinfo() {
    if (charinfo == null) {
      charinfo = createCharinfo();
    }
    return charinfo;
  }

/*
* This takes the glyph info record obtained from the glyph vector and converts it into a similar record
* adjusted to represent character data instead.  For economy we don't use glyph info records in this processing.
*
* Here are some constraints:
* - there can be more glyphs than characters (glyph insertion, perhaps based on normalization, has taken place)
* - there can not be fewer glyphs than characters (0xffff glyphs are inserted for characters ligaturized away)
* - each glyph maps to a single character, when multiple glyphs exist for a character they all map to it, but
*   no two characters map to the same glyph
* - multiple glyphs mapping to the same character need not be in sequence (thai, tamil have split characters)
* - glyphs may be arbitrarily reordered (Indic reorders glyphs)
* - all glyphs share the same bidi level
* - all glyphs share the same horizontal (or vertical) baseline
* - combining marks visually follow their base character in the glyph array-- i.e. in an rtl gv they are
*   to the left of their base character-- and have zero advance.
*
* The output maps this to character positions, and therefore caret positions, via the following assumptions:
* - zero-advance glyphs do not contribute to the advance of their character (i.e. position is ignored), conversely
*   if a glyph is to contribute to the advance of its character it must have a non-zero (float) advance
* - no carets can appear between a zero width character and its preceding character, where 'preceding' is
*   defined logically.
* - no carets can appear within a split character
* - no carets can appear within a local reordering (i.e. Indic reordering, or non-adjacent split characters)
* - all characters lie on the same baseline, and it is either horizontal or vertical
* - the charinfo is in uniform ltr or rtl order (visual order), since local reorderings and split characters are removed
*
* The algorithm works in the following way:
* 1) we scan the glyphs ltr or rtl based on the bidi run direction
* 2) we can work in place, since we always consume a glyph for each char we write
*    a) if the line is ltr, we start writing at position 0 until we finish, there may be leftver space
*    b) if the line is rtl and 1-1, we start writing at position numChars/glyphs - 1 until we finish at 0
*    c) otherwise if we don't finish at 0, we have to copy the data down
* 3) we consume clusters in the following way:
*    a) the first element is always consumed
*    b) subsequent elements are consumed if:
*       i) their advance is zero
*       ii) their character index <= the character index of any character seen in this cluster
*       iii) the minimum character index seen in this cluster isn't adjacent to the previous cluster
*    c) character data is written as follows for horizontal lines (x/y and w/h are exchanged on vertical lines)
*       i) the x position is the position of the leftmost glyph whose advance is not zero
*       ii)the y position is the baseline
*       iii) the x advance is the distance to the maximum x + adv of all glyphs whose advance is not zero
*       iv) the y advance is the baseline
*       v) vis x,y,w,h tightly encloses the vis x,y,w,h of all the glyphs with nonzero w and h
* 4) we can make some simple optimizations if we know some things:
*    a) if the mapping is 1-1, unidirectional, and there are no zero-adv glyphs, we just return the glyphinfo
*    b) if the mapping is 1-1, unidirectional, we just adjust the remaining glyphs to originate at right/left of the base
*    c) if the mapping is 1-1, we compute the base position and advance as we go, then go back to adjust the remaining glyphs
*    d) otherwise we keep separate track of the write position as we do (c) since no glyph in the cluster may be in the
*    position we are writing.
*    e) most clusters are simply the single base glyph in the same position as its character, so we try to avoid
*    copying its data unnecessarily.
* 5) the glyph vector ought to provide access to these 'global' attributes to enable these optimizations.  A single
*    int with flags set is probably ok, we could also provide accessors for each attribute.  This doesn't map to
*    the GlyphMetrics flags very well, so I won't attempt to keep them similar.  It might be useful to add those
*    in addition to these.
*    int FLAG_HAS_ZERO_ADVANCE_GLYPHS = 1; // set if there are zero-advance glyphs
*    int FLAG_HAS_NONUNIFORM_ORDER = 2; // set if some glyphs are rearranged out of character visual order
*    int FLAG_HAS_SPLIT_CHARACTERS = 4; // set if multiple glyphs per character
*    int getDescriptionFlags(); // return an int containing the above flags
*    boolean hasZeroAdvanceGlyphs();
*    boolean hasNonuniformOrder();
*    boolean hasSplitCharacters();
*    The optimized cases in (4) correspond to values 0, 1, 3, and 7 returned by getDescriptionFlags().
*/
  protected float[] createCharinfo() {
    StandardGlyphVector gv = getGV();
    float[] glyphinfo = null;
    try {
        glyphinfo = gv.getGlyphInfo();
    }
    catch (Exception e) {
        System.out.println(source);
    }

    /*
    if ((gv.getDescriptionFlags() & 0x7) == 0) {
        return glyphinfo;
    }
    */

    int numGlyphs = gv.getNumGlyphs();
    if (numGlyphs == 0) {
        return glyphinfo;
    }
    int[] indices = gv.getGlyphCharIndices(0, numGlyphs, null);

    boolean DEBUG = false;
    if (DEBUG) {
      System.err.println("number of glyphs: " + numGlyphs);
      for (int i = 0; i < numGlyphs; ++i) {
        System.err.println("g: " + i +
            ", x: " + glyphinfo[i*numvals+posx] +
            ", a: " + glyphinfo[i*numvals+advx] +
            ", n: " + indices[i]);
      }
    }

    int minIndex = indices[0];  // smallest index seen this cluster
    int maxIndex = minIndex;    // largest index seen this cluster
    int nextMin = 0;            // expected smallest index for this cluster
    int cp = 0;                 // character position
    int cx = 0;                 // character index (logical)
    int gp = 0;                 // glyph position
    int gx = 0;                 // glyph index (visual)
    int gxlimit = numGlyphs;    // limit of gx, when we reach this we're done
    int pdelta = numvals;       // delta for incrementing positions
    int xdelta = 1;             // delta for incrementing indices

    boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
    if (!ltr) {
        minIndex = indices[numGlyphs - 1];
        maxIndex = minIndex;
        nextMin  = 0; // still logical
        cp = glyphinfo.length - numvals;
        cx = 0; // still logical
        gp = glyphinfo.length - numvals;
        gx = numGlyphs - 1;
        gxlimit = -1;
        pdelta = -numvals;
        xdelta = -1;
    }

    /*
    // to support vertical, use 'ixxxx' indices and swap horiz and vertical components
    if (source.isVertical()) {
        iposx = posy;
        iposy = posx;
        iadvx = advy;
        iadvy = advx;
        ivisx = visy;
        ivisy = visx;
        ivish = visw;
        ivisw = vish;
    } else {
        // use standard values
    }
    */

    // use intermediates to reduce array access when we need to
    float cposl = 0, cposr = 0, cvisl = 0, cvist = 0, cvisr = 0, cvisb = 0;
    float baseline = 0;

    // record if we have to copy data even when no cluster
    boolean mustCopy = false;

    while (gx != gxlimit) {
        // start of new cluster
        boolean haveCopy = false;
        int clusterExtraGlyphs = 0;

        minIndex = indices[gx];
        maxIndex = minIndex;

        // advance to next glyph
        gx += xdelta;
        gp += pdelta;

 /*
        while (gx != gxlimit && (glyphinfo[gp + advx] == 0 ||
                           minIndex != nextMin || indices[gx] <= maxIndex)) {
  */
        while (gx != gxlimit &&
               ((glyphinfo[gp + advx] == 0) ||
               (minIndex != nextMin) ||
               (indices[gx] <= maxIndex) ||
               (maxIndex - minIndex > clusterExtraGlyphs))) {
            // initialize base data first time through, using base glyph
            if (!haveCopy) {
                int gps = gp - pdelta;

                cposl = glyphinfo[gps + posx];
                cposr = cposl + glyphinfo[gps + advx];
                cvisl = glyphinfo[gps + visx];
                cvist = glyphinfo[gps + visy];
                cvisr = cvisl + glyphinfo[gps + visw];
                cvisb = cvist + glyphinfo[gps + vish];

                haveCopy = true;
            }

            // have an extra glyph in this cluster
            ++clusterExtraGlyphs;

            // adjust advance only if new glyph has non-zero advance
            float radvx = glyphinfo[gp + advx];
            if (radvx != 0) {
                float rposx = glyphinfo[gp + posx];
                cposl = Math.min(cposl, rposx);
                cposr = Math.max(cposr, rposx + radvx);
            }

            // adjust visible bounds only if new glyph has non-empty bounds
            float rvisw = glyphinfo[gp + visw];
            if (rvisw != 0) {
                float rvisx = glyphinfo[gp + visx];
                float rvisy = glyphinfo[gp + visy];
                cvisl = Math.min(cvisl, rvisx);
                cvist = Math.min(cvist, rvisy);
                cvisr = Math.max(cvisr, rvisx + rvisw);
                cvisb = Math.max(cvisb, rvisy + glyphinfo[gp + vish]);
            }

            // adjust min, max index
            minIndex = Math.min(minIndex, indices[gx]);
            maxIndex = Math.max(maxIndex, indices[gx]);

            // get ready to examine next glyph
            gx += xdelta;
            gp += pdelta;
        }
        // done with cluster, gx and gp are set for next glyph

        if (DEBUG) {
            System.out.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
        }

        nextMin = maxIndex + 1;

        // do common character adjustments
        glyphinfo[cp + posy] = baseline;
        glyphinfo[cp + advy] = 0;

        if (haveCopy) {
            // save adjustments to the base character
            glyphinfo[cp + posx] = cposl;
            glyphinfo[cp + advx] = cposr - cposl;
            glyphinfo[cp + visx] = cvisl;
            glyphinfo[cp + visy] = cvist;
            glyphinfo[cp + visw] = cvisr - cvisl;
            glyphinfo[cp + vish] = cvisb - cvist;

            // compare number of chars read with number of glyphs read.
            // if more glyphs than chars, set mustCopy to true, as we'll always have
            // to copy the data from here on out.
            if (maxIndex - minIndex < clusterExtraGlyphs) {
                mustCopy = true;
            }

            // Fix the characters that follow the base character.
            // New values are all the same.  Note we fix the number of characters
            // we saw, not the number of glyphs we saw.
            if (minIndex < maxIndex) {
                if (!ltr) {
                    // if rtl, characters to left of base, else to right.  reuse cposr.
                    cposr = cposl;
                }
                cvisr -= cvisl; // reuse, convert to deltas.
                cvisb -= cvist;

                int iMinIndex = minIndex, icp = cp / 8;

                while (minIndex < maxIndex) {
                    ++minIndex;
                    cx += xdelta;
                    cp += pdelta;

                    if (cp < 0 || cp >= glyphinfo.length) {
                        if (DEBUG) System.out.println("minIndex = " + iMinIndex + ", maxIndex = " + maxIndex + ", cp = " + icp);
                    }

                    glyphinfo[cp + posx] = cposr;
                    glyphinfo[cp + posy] = baseline;
                    glyphinfo[cp + advx] = 0;
                    glyphinfo[cp + advy] = 0;
                    glyphinfo[cp + visx] = cvisl;
                    glyphinfo[cp + visy] = cvist;
                    glyphinfo[cp + visw] = cvisr;
                    glyphinfo[cp + vish] = cvisb;
                }
            }

            // no longer using this copy
            haveCopy = false;
        } else if (mustCopy) {
            // out of synch, so we have to copy all the time now
            int gpr = gp - pdelta;

            glyphinfo[cp + posx] = glyphinfo[gpr + posx];
            glyphinfo[cp + advx] = glyphinfo[gpr + advx];
            glyphinfo[cp + visx] = glyphinfo[gpr + visx];
            glyphinfo[cp + visy] = glyphinfo[gpr + visy];
            glyphinfo[cp + visw] = glyphinfo[gpr + visw];
            glyphinfo[cp + vish] = glyphinfo[gpr + vish];
        }
        // else glyphinfo is already at the correct character position, and is unchanged, so just leave it

        // reset for new cluster
        cp += pdelta;
        cx += xdelta;
    }

    if (mustCopy && !ltr) {
        // data written to wrong end of array, need to shift down

        cp -= pdelta; // undo last increment, get start of valid character data in array
        System.arraycopy(glyphinfo, cp, glyphinfo, 0, glyphinfo.length - cp);
    }

    if (DEBUG) {
      char[] chars = source.getChars();
      int start = source.getStart();
      int length = source.getLength();
      System.out.println("char info for " + length + " characters");
      for(int i = 0; i < length * numvals;) {
        System.out.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
                           " x: " + glyphinfo[i++] +
                           " y: " + glyphinfo[i++] +
                           " xa: " + glyphinfo[i++] +
                           " ya: " + glyphinfo[i++] +
                           " l: " + glyphinfo[i++] +
                           " t: " + glyphinfo[i++] +
                           " w: " + glyphinfo[i++] +
                           " h: " + glyphinfo[i++]);
      }
    }

    return glyphinfo;
  }

  /**
   * Map logical character index to visual character index.
   * <p>
   * This ignores hindi reordering.  @see createCharinfo
   */
  protected int l2v(int index) {
    return (source.getLayoutFlags() & 0x1) == 0 ? index : source.getLength() - 1 - index;
  }

  /**
   * Map visual character index to logical character index.
   * <p>
   * This ignores hindi reordering.  @see createCharinfo
   */
  protected int v2l(int index) {
    return (source.getLayoutFlags() & 0x1) == 0 ? index : source.getLength() - 1 - index;
  }

  public TextLineComponent getSubset(int start, int limit, int dir) {
    return new ExtendedTextSourceLabel(source.getSubSource(start, limit-start, dir), decorator);
  }

  public String toString() {
    if (true) {
        return source.toString(source.WITHOUT_CONTEXT);
    }
    StringBuffer buf = new StringBuffer();
    buf.append(super.toString());
    buf.append("[source:");
    buf.append(source.toString(source.WITHOUT_CONTEXT));
    buf.append(", lb:");
    buf.append(lb);
    buf.append(", ab:");
    buf.append(ab);
    buf.append(", vb:");
    buf.append(vb);
    buf.append(", gv:");
    buf.append(gv);
    buf.append(", ci: ");
    if (charinfo == null) {
      buf.append("null");
    } else {
      buf.append(charinfo[0]);
      for (int i = 1; i < charinfo.length;) {
        buf.append(i % numvals == 0 ? "; " : ", ");
        buf.append(charinfo[i]);
      }
    }
    buf.append("]");

    return buf.toString();
  }

  //public static ExtendedTextLabel create(TextSource source) {
  //  return new ExtendedTextSourceLabel(source);
  //}

  public int getNumJustificationInfos() {
    return getGV().getNumGlyphs();
  }


  public void getJustificationInfos(GlyphJustificationInfo[] infos, int infoStart, int charStart, int charLimit) {
    // This simple implementation only uses spaces for justification.
    // Since regular characters aren't justified, we don't need to deal with
    // special infos for combining marks or ligature substitution glyphs.
    // added character justification for kanjii only 2/22/98

    StandardGlyphVector gv = getGV();

    float[] charinfo = getCharinfo();

    float size = gv.getFont().getSize2D();

    GlyphJustificationInfo nullInfo =
      new GlyphJustificationInfo(0,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0);

    GlyphJustificationInfo spaceInfo =
      new GlyphJustificationInfo(size,
                                 true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, size,
                                 true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, size / 4f);

    GlyphJustificationInfo kanjiInfo =
      new GlyphJustificationInfo(size,
                                 true, GlyphJustificationInfo.PRIORITY_INTERCHAR, size, size,
                                 false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0);

    char[] chars = source.getChars();
    int offset = source.getStart();

    // assume data is 1-1 and either all rtl or all ltr, for now

    int numGlyphs = gv.getNumGlyphs();
    int minGlyph = 0;
    int maxGlyph = numGlyphs;
    boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
    if (charStart != 0 || charLimit != source.getLength()) {
      if (ltr) {
        minGlyph = charStart;
        maxGlyph = charLimit;
      } else {
        minGlyph = numGlyphs - charLimit;
        maxGlyph = numGlyphs - charStart;
      }
    }

    for (int i = 0; i < numGlyphs; ++i) {
      GlyphJustificationInfo info = null;
      if (i >= minGlyph && i < maxGlyph) {
        if (charinfo[i * numvals + advx] == 0) { // combining marks don't justify
          info = nullInfo;
        } else {
          int ci = v2l(i); // 1-1 assumption again
          char c = chars[offset + ci];
          if (Character.isWhitespace(c)) {
            info = spaceInfo;
            // CJK, Hangul, CJK Compatibility areas
          } else if (c >= 0x4e00 &&
                     (c < 0xa000) ||
                     (c >= 0xac00 && c < 0xd7b0) ||
                     (c >= 0xf900 && c < 0xfb00)) {
            info = kanjiInfo;
          } else {
            info = nullInfo;
          }
        }
      }
      infos[infoStart + i] = info;
    }
  }

  public TextLineComponent applyJustificationDeltas(float[] deltas, int deltaStart, boolean[] flags) {

    // when we justify, we need to adjust the charinfo since spaces
    // change their advances.  preserve the existing charinfo.

    float[] newCharinfo = (float[])getCharinfo().clone();

    // we only push spaces, so never need to rejustify
    flags[0] = false;

    // preserve the existing gv.

    StandardGlyphVector newgv = (StandardGlyphVector)getGV().clone();
    float[] newPositions = newgv.getGlyphPositions(null);
    int numGlyphs = newgv.getNumGlyphs();

    /*
    System.out.println("oldgv: " + getGV() + ", newgv: " + newgv);
    System.out.println("newpositions: " + newPositions);
    for (int i = 0; i < newPositions.length; i += 2) {
      System.out.println("[" + (i/2) + "] " + newPositions[i] + ", " + newPositions[i+1]);
    }

    System.out.println("deltas: " + deltas + " start: " + deltaStart);
    for (int i = deltaStart; i < deltaStart + numGlyphs; i += 2) {
      System.out.println("[" + (i/2) + "] " + deltas[i] + ", " + deltas[i+1]);
    }
    */

    char[] chars = source.getChars();
    int offset = source.getStart();

    // accumulate the deltas to adjust positions and advances.
    // handle whitespace by modifying advance,
    // handle everything else by modifying position before and after

    float deltaPos = 0;
    for (int i = 0; i < numGlyphs; ++i) {
      if (Character.isWhitespace(chars[offset + v2l(i)])) {
        newPositions[i*2] += deltaPos;

        float deltaAdv = deltas[deltaStart + i*2] + deltas[deltaStart + i*2 + 1];

        newCharinfo[i * numvals + posx] += deltaPos;
        newCharinfo[i * numvals + visx] += deltaPos;
        newCharinfo[i * numvals + advx] += deltaAdv;

        deltaPos += deltaAdv;
      } else {
        deltaPos += deltas[deltaStart + i*2];

        newPositions[i*2] += deltaPos;
        newCharinfo[i * numvals + posx] += deltaPos;
        newCharinfo[i * numvals + visx] += deltaPos;

        deltaPos += deltas[deltaStart + i*2 + 1];
      }
    }
    newPositions[numGlyphs * 2] += deltaPos;

    newgv.setGlyphPositions(newPositions);

    /*
    newPositions = newgv.getGlyphPositions(null);
    System.out.println(">> newpositions: " + newPositions);
    for (int i = 0; i < newPositions.length; i += 2) {
      System.out.println("[" + (i/2) + "] " + newPositions[i] + ", " + newPositions[i+1]);
    }
    */

    ExtendedTextSourceLabel result = new ExtendedTextSourceLabel(source, decorator);
    result.gv = newgv;
    result.charinfo = newCharinfo;

    return result;
  }
}
