/*
 * Copyright (c) 1999, 2006, 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.
 */
package javax.swing.text;

import java.awt.*;
import java.text.BreakIterator;
import javax.swing.event.*;
import java.util.BitSet;
import java.util.Locale;

import javax.swing.UIManager;
import sun.swing.SwingUtilities2;

/**
 * A GlyphView is a styled chunk of text that represents a view
 * mapped over an element in the text model. This view is generally
 * responsible for displaying text glyphs using character level
 * attributes in some way.
 * An implementation of the GlyphPainter class is used to do the
 * actual rendering and model/view translations.  This separates
 * rendering from layout and management of the association with
 * the model.
 * <p>
 * The view supports breaking for the purpose of formatting.
 * The fragments produced by breaking share the view that has
 * primary responsibility for the element (i.e. they are nested
 * classes and carry only a small amount of state of their own)
 * so they can share its resources.
 * <p>
 * Since this view
 * represents text that may have tabs embedded in it, it implements the
 * <code>TabableView</code> interface.  Tabs will only be
 * expanded if this view is embedded in a container that does
 * tab expansion.  ParagraphView is an example of a container
 * that does tab expansion.
 * <p>
 *
 * @since 1.3
 *
 * @author  Timothy Prinzing
 */
public class GlyphView extends View implements TabableView, Cloneable {

    /**
     * Constructs a new view wrapped on an element.
     *
     * @param elem the element
     */
    public GlyphView(Element elem) {
        super(elem);
        offset = 0;
        length = 0;
        Element parent = elem.getParentElement();
        AttributeSet attr = elem.getAttributes();

        //         if there was an implied CR
        impliedCR = (attr != null && attr.getAttribute(IMPLIED_CR) != null &&
        //         if this is non-empty paragraph
                   parent != null && parent.getElementCount() > 1);
        skipWidth = elem.getName().equals("br");
    }

    /**
     * Creates a shallow copy.  This is used by the
     * createFragment and breakView methods.
     *
     * @return the copy
     */
    protected final Object clone() {
        Object o;
        try {
            o = super.clone();
        } catch (CloneNotSupportedException cnse) {
            o = null;
        }
        return o;
    }

    /**
     * Fetch the currently installed glyph painter.
     * If a painter has not yet been installed, and
     * a default was not yet needed, null is returned.
     */
    public GlyphPainter getGlyphPainter() {
        return painter;
    }

    /**
     * Sets the painter to use for rendering glyphs.
     */
    public void setGlyphPainter(GlyphPainter p) {
        painter = p;
    }

    /**
     * Fetch a reference to the text that occupies
     * the given range.  This is normally used by
     * the GlyphPainter to determine what characters
     * it should render glyphs for.
     *
     * @param p0  the starting document offset >= 0
     * @param p1  the ending document offset >= p0
     * @return    the <code>Segment</code> containing the text
     */
     public Segment getText(int p0, int p1) {
         // When done with the returned Segment it should be released by
         // invoking:
         //    SegmentCache.releaseSharedSegment(segment);
         Segment text = SegmentCache.getSharedSegment();
         try {
             Document doc = getDocument();
             doc.getText(p0, p1 - p0, text);
         } catch (BadLocationException bl) {
             throw new StateInvariantError("GlyphView: Stale view: " + bl);
         }
         return text;
     }

    /**
     * Fetch the background color to use to render the
     * glyphs.  If there is no background color, null should
     * be returned.  This is implemented to call
     * <code>StyledDocument.getBackground</code> if the associated
     * document is a styled document, otherwise it returns null.
     */
    public Color getBackground() {
        Document doc = getDocument();
        if (doc instanceof StyledDocument) {
            AttributeSet attr = getAttributes();
            if (attr.isDefined(StyleConstants.Background)) {
                return ((StyledDocument)doc).getBackground(attr);
            }
        }
        return null;
    }

    /**
     * Fetch the foreground color to use to render the
     * glyphs.  If there is no foreground color, null should
     * be returned.  This is implemented to call
     * <code>StyledDocument.getBackground</code> if the associated
     * document is a StyledDocument.  If the associated document
     * is not a StyledDocument, the associated components foreground
     * color is used.  If there is no associated component, null
     * is returned.
     */
    public Color getForeground() {
        Document doc = getDocument();
        if (doc instanceof StyledDocument) {
            AttributeSet attr = getAttributes();
            return ((StyledDocument)doc).getForeground(attr);
        }
        Component c = getContainer();
        if (c != null) {
            return c.getForeground();
        }
        return null;
    }

    /**
     * Fetch the font that the glyphs should be based
     * upon.  This is implemented to call
     * <code>StyledDocument.getFont</code> if the associated
     * document is a StyledDocument.  If the associated document
     * is not a StyledDocument, the associated components font
     * is used.  If there is no associated component, null
     * is returned.
     */
    public Font getFont() {
        Document doc = getDocument();
        if (doc instanceof StyledDocument) {
            AttributeSet attr = getAttributes();
            return ((StyledDocument)doc).getFont(attr);
        }
        Component c = getContainer();
        if (c != null) {
            return c.getFont();
        }
        return null;
    }

    /**
     * Determine if the glyphs should be underlined.  If true,
     * an underline should be drawn through the baseline.
     */
    public boolean isUnderline() {
        AttributeSet attr = getAttributes();
        return StyleConstants.isUnderline(attr);
    }

    /**
     * Determine if the glyphs should have a strikethrough
     * line.  If true, a line should be drawn through the center
     * of the glyphs.
     */
    public boolean isStrikeThrough() {
        AttributeSet attr = getAttributes();
        return StyleConstants.isStrikeThrough(attr);
    }

    /**
     * Determine if the glyphs should be rendered as superscript.
     */
    public boolean isSubscript() {
        AttributeSet attr = getAttributes();
        return StyleConstants.isSubscript(attr);
    }

    /**
     * Determine if the glyphs should be rendered as subscript.
     */
    public boolean isSuperscript() {
        AttributeSet attr = getAttributes();
        return StyleConstants.isSuperscript(attr);
    }

    /**
     * Fetch the TabExpander to use if tabs are present in this view.
     */
    public TabExpander getTabExpander() {
        return expander;
    }

    /**
     * Check to see that a glyph painter exists.  If a painter
     * doesn't exist, a default glyph painter will be installed.
     */
    protected void checkPainter() {
        if (painter == null) {
            if (defaultPainter == null) {
                // the classname should probably come from a property file.
                String classname = "javax.swing.text.GlyphPainter1";
                try {
                    Class c;
                    ClassLoader loader = getClass().getClassLoader();
                    if (loader != null) {
                        c = loader.loadClass(classname);
                    } else {
                        c = Class.forName(classname);
                    }
                    Object o = c.newInstance();
                    if (o instanceof GlyphPainter) {
                        defaultPainter = (GlyphPainter) o;
                    }
                } catch (Throwable e) {
                    throw new StateInvariantError("GlyphView: Can't load glyph painter: "
                                                  + classname);
                }
            }
            setGlyphPainter(defaultPainter.getPainter(this, getStartOffset(),
                                                      getEndOffset()));
        }
    }

    // --- TabableView methods --------------------------------------

    /**
     * Determines the desired span when using the given
     * tab expansion implementation.
     *
     * @param x the position the view would be located
     *  at for the purpose of tab expansion >= 0.
     * @param e how to expand the tabs when encountered.
     * @return the desired span >= 0
     * @see TabableView#getTabbedSpan
     */
    public float getTabbedSpan(float x, TabExpander e) {
        checkPainter();

        TabExpander old = expander;
        expander = e;

        if (expander != old) {
            // setting expander can change horizontal span of the view,
            // so we have to call preferenceChanged()
            preferenceChanged(null, true, false);
        }

        this.x = (int) x;
        int p0 = getStartOffset();
        int p1 = getEndOffset();
        float width = painter.getSpan(this, p0, p1, expander, x);
        return width;
    }

    /**
     * Determines the span along the same axis as tab
     * expansion for a portion of the view.  This is
     * intended for use by the TabExpander for cases
     * where the tab expansion involves aligning the
     * portion of text that doesn't have whitespace
     * relative to the tab stop.  There is therefore
     * an assumption that the range given does not
     * contain tabs.
     * <p>
     * This method can be called while servicing the
     * getTabbedSpan or getPreferredSize.  It has to
     * arrange for its own text buffer to make the
     * measurements.
     *
     * @param p0 the starting document offset >= 0
     * @param p1 the ending document offset >= p0
     * @return the span >= 0
     */
    public float getPartialSpan(int p0, int p1) {
        checkPainter();
        float width = painter.getSpan(this, p0, p1, expander, x);
        return width;
    }

    // --- View methods ---------------------------------------------

    /**
     * Fetches the portion of the model that this view is responsible for.
     *
     * @return the starting offset into the model
     * @see View#getStartOffset
     */
    public int getStartOffset() {
        Element e = getElement();
        return (length > 0) ? e.getStartOffset() + offset : e.getStartOffset();
    }

    /**
     * Fetches the portion of the model that this view is responsible for.
     *
     * @return the ending offset into the model
     * @see View#getEndOffset
     */
    public int getEndOffset() {
        Element e = getElement();
        return (length > 0) ? e.getStartOffset() + offset + length : e.getEndOffset();
    }

    /**
     * Lazily initializes the selections field
     */
    private void initSelections(int p0, int p1) {
        int viewPosCount = p1 - p0 + 1;
        if (selections == null || viewPosCount > selections.length) {
            selections = new byte[viewPosCount];
            return;
        }
        for (int i = 0; i < viewPosCount; selections[i++] = 0);
    }

    /**
     * Renders a portion of a text style run.
     *
     * @param g the rendering surface to use
     * @param a the allocated region to render into
     */
    public void paint(Graphics g, Shape a) {
        checkPainter();

        boolean paintedText = false;
        Component c = getContainer();
        int p0 = getStartOffset();
        int p1 = getEndOffset();
        Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
        Color bg = getBackground();
        Color fg = getForeground();

        if (c != null && ! c.isEnabled()) {
            fg = (c instanceof JTextComponent ?
                ((JTextComponent)c).getDisabledTextColor() :
                UIManager.getColor("textInactiveText"));
        }
        if (bg != null) {
            g.setColor(bg);
            g.fillRect(alloc.x, alloc.y, alloc.width, alloc.height);
        }
        if (c instanceof JTextComponent) {
            JTextComponent tc = (JTextComponent) c;
            Highlighter h = tc.getHighlighter();
            if (h instanceof LayeredHighlighter) {
                ((LayeredHighlighter)h).paintLayeredHighlights
                    (g, p0, p1, a, tc, this);
            }
        }

        if (Utilities.isComposedTextElement(getElement())) {
            Utilities.paintComposedText(g, a.getBounds(), this);
            paintedText = true;
        } else if(c instanceof JTextComponent) {
            JTextComponent tc = (JTextComponent) c;
            Color selFG = tc.getSelectedTextColor();

            if (// there's a highlighter (bug 4532590), and
                (tc.getHighlighter() != null) &&
                // selected text color is different from regular foreground
                (selFG != null) && !selFG.equals(fg)) {

                Highlighter.Highlight[] h = tc.getHighlighter().getHighlights();
                if(h.length != 0) {
                    boolean initialized = false;
                    int viewSelectionCount = 0;
                    for (int i = 0; i < h.length; i++) {
                        Highlighter.Highlight highlight = h[i];
                        int hStart = highlight.getStartOffset();
                        int hEnd = highlight.getEndOffset();
                        if (hStart > p1 || hEnd < p0) {
                            // the selection is out of this view
                            continue;
                        }
                        if (!SwingUtilities2.useSelectedTextColor(highlight, tc)) {
                            continue;
                        }
                        if (hStart <= p0 && hEnd >= p1){
                            // the whole view is selected
                            paintTextUsingColor(g, a, selFG, p0, p1);
                            paintedText = true;
                            break;
                        }
                        // the array is lazily created only when the view
                        // is partially selected
                        if (!initialized) {
                            initSelections(p0, p1);
                            initialized = true;
                        }
                        hStart = Math.max(p0, hStart);
                        hEnd = Math.min(p1, hEnd);
                        paintTextUsingColor(g, a, selFG, hStart, hEnd);
                        // the array represents view positions [0, p1-p0+1]
                        // later will iterate this array and sum its
                        // elements. Positions with sum == 0 are not selected.
                        selections[hStart-p0]++;
                        selections[hEnd-p0]--;

                        viewSelectionCount++;
                    }

                    if (!paintedText && viewSelectionCount > 0) {
                        // the view is partially selected
                        int curPos = -1;
                        int startPos = 0;
                        int viewLen = p1 - p0;
                        while (curPos++ < viewLen) {
                            // searching for the next selection start
                            while(curPos < viewLen &&
                                    selections[curPos] == 0) curPos++;
                            if (startPos != curPos) {
                                // paint unselected text
                                paintTextUsingColor(g, a, fg,
                                        p0 + startPos, p0 + curPos);
                            }
                            int checkSum = 0;
                            // searching for next start position of unselected text
                            while (curPos < viewLen &&
                                    (checkSum += selections[curPos]) != 0) curPos++;
                            startPos = curPos;
                        }
                        paintedText = true;
                    }
                }
            }
        }
        if(!paintedText)
            paintTextUsingColor(g, a, fg, p0, p1);
    }

    /**
     * Paints the specified region of text in the specified color.
     */
    final void paintTextUsingColor(Graphics g, Shape a, Color c, int p0, int p1) {
        // render the glyphs
        g.setColor(c);
        painter.paint(this, g, a, p0, p1);

        // render underline or strikethrough if set.
        boolean underline = isUnderline();
        boolean strike = isStrikeThrough();
        if (underline || strike) {
            // calculate x coordinates
            Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
            View parent = getParent();
            if ((parent != null) && (parent.getEndOffset() == p1)) {
                // strip whitespace on end
                Segment s = getText(p0, p1);
                while (Character.isWhitespace(s.last())) {
                    p1 -= 1;
                    s.count -= 1;
                }
                SegmentCache.releaseSharedSegment(s);
            }
            int x0 = alloc.x;
            int p = getStartOffset();
            if (p != p0) {
                x0 += (int) painter.getSpan(this, p, p0, getTabExpander(), x0);
            }
            int x1 = x0 + (int) painter.getSpan(this, p0, p1, getTabExpander(), x0);

            // calculate y coordinate
            int y = alloc.y + alloc.height - (int) painter.getDescent(this);
            if (underline) {
                int yTmp = y + 1;
                g.drawLine(x0, yTmp, x1, yTmp);
            }
            if (strike) {
                // move y coordinate above baseline
                int yTmp = y - (int) (painter.getAscent(this) * 0.3f);
                g.drawLine(x0, yTmp, x1, yTmp);
            }

        }
    }

    /**
     * Determines the minimum span for this view along an axis.
     *
     * <p>This implementation returns the longest non-breakable area within
     * the view as a minimum span for {@code View.X_AXIS}.</p>
     *
     * @param axis  may be either {@code View.X_AXIS} or {@code View.Y_AXIS}
     * @return      the minimum span the view can be rendered into
     * @throws IllegalArgumentException if the {@code axis} parameter is invalid
     * @see         javax.swing.text.View#getMinimumSpan
     */
    @Override
    public float getMinimumSpan(int axis) {
        return super.getMinimumSpan(axis);
    }

    /**
     * Determines the preferred span for this view along an
     * axis.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return   the span the view would like to be rendered into >= 0.
     *           Typically the view is told to render into the span
     *           that is returned, although there is no guarantee.
     *           The parent may choose to resize or break the view.
     */
    public float getPreferredSpan(int axis) {
        if (impliedCR) {
            return 0;
        }
        checkPainter();
        int p0 = getStartOffset();
        int p1 = getEndOffset();
        switch (axis) {
        case View.X_AXIS:
            if (skipWidth) {
                return 0;
            }
            return painter.getSpan(this, p0, p1, expander, this.x);
        case View.Y_AXIS:
            float h = painter.getHeight(this);
            if (isSuperscript()) {
                h += h/3;
            }
            return h;
        default:
            throw new IllegalArgumentException("Invalid axis: " + axis);
        }
    }

    /**
     * Determines the desired alignment for this view along an
     * axis.  For the label, the alignment is along the font
     * baseline for the y axis, and the superclasses alignment
     * along the x axis.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return the desired alignment.  This should be a value
     *   between 0.0 and 1.0 inclusive, where 0 indicates alignment at the
     *   origin and 1.0 indicates alignment to the full span
     *   away from the origin.  An alignment of 0.5 would be the
     *   center of the view.
     */
    public float getAlignment(int axis) {
        checkPainter();
        if (axis == View.Y_AXIS) {
            boolean sup = isSuperscript();
            boolean sub = isSubscript();
            float h = painter.getHeight(this);
            float d = painter.getDescent(this);
            float a = painter.getAscent(this);
            float align;
            if (sup) {
                align = 1.0f;
            } else if (sub) {
                align = (h > 0) ? (h - (d + (a / 2))) / h : 0;
            } else {
                align = (h > 0) ? (h - d) / h : 0;
            }
            return align;
        }
        return super.getAlignment(axis);
    }

    /**
     * Provides a mapping from the document model coordinate space
     * to the coordinate space of the view mapped to it.
     *
     * @param pos the position to convert >= 0
     * @param a   the allocated region to render into
     * @param b   either <code>Position.Bias.Forward</code>
     *                or <code>Position.Bias.Backward</code>
     * @return the bounding box of the given position
     * @exception BadLocationException  if the given position does not represent a
     *   valid location in the associated document
     * @see View#modelToView
     */
    public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
        checkPainter();
        return painter.modelToView(this, pos, b, a);
    }

    /**
     * Provides a mapping from the view coordinate space to the logical
     * coordinate space of the model.
     *
     * @param x the X coordinate >= 0
     * @param y the Y coordinate >= 0
     * @param a the allocated region to render into
     * @param biasReturn either <code>Position.Bias.Forward</code>
     *  or <code>Position.Bias.Backward</code> is returned as the
     *  zero-th element of this array
     * @return the location within the model that best represents the
     *  given point of view >= 0
     * @see View#viewToModel
     */
    public int viewToModel(float x, float y, Shape a, Position.Bias[] biasReturn) {
        checkPainter();
        return painter.viewToModel(this, x, y, a, biasReturn);
    }

    /**
     * Determines how attractive a break opportunity in
     * this view is.  This can be used for determining which
     * view is the most attractive to call <code>breakView</code>
     * on in the process of formatting.  The
     * higher the weight, the more attractive the break.  A
     * value equal to or lower than <code>View.BadBreakWeight</code>
     * should not be considered for a break.  A value greater
     * than or equal to <code>View.ForcedBreakWeight</code> should
     * be broken.
     * <p>
     * This is implemented to forward to the superclass for
     * the Y_AXIS.  Along the X_AXIS the following values
     * may be returned.
     * <dl>
     * <dt><b>View.ExcellentBreakWeight</b>
     * <dd>if there is whitespace proceeding the desired break
     *   location.
     * <dt><b>View.BadBreakWeight</b>
     * <dd>if the desired break location results in a break
     *   location of the starting offset.
     * <dt><b>View.GoodBreakWeight</b>
     * <dd>if the other conditions don't occur.
     * </dl>
     * This will normally result in the behavior of breaking
     * on a whitespace location if one can be found, otherwise
     * breaking between characters.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @param pos the potential location of the start of the
     *   broken view >= 0.  This may be useful for calculating tab
     *   positions.
     * @param len specifies the relative length from <em>pos</em>
     *   where a potential break is desired >= 0.
     * @return the weight, which should be a value between
     *   View.ForcedBreakWeight and View.BadBreakWeight.
     * @see LabelView
     * @see ParagraphView
     * @see View#BadBreakWeight
     * @see View#GoodBreakWeight
     * @see View#ExcellentBreakWeight
     * @see View#ForcedBreakWeight
     */
    public int getBreakWeight(int axis, float pos, float len) {
        if (axis == View.X_AXIS) {
            checkPainter();
            int p0 = getStartOffset();
            int p1 = painter.getBoundedPosition(this, p0, pos, len);
            return p1 == p0 ? View.BadBreakWeight :
                   getBreakSpot(p0, p1) != BreakIterator.DONE ?
                            View.ExcellentBreakWeight : View.GoodBreakWeight;
        }
        return super.getBreakWeight(axis, pos, len);
    }

    /**
     * Breaks this view on the given axis at the given length.
     * This is implemented to attempt to break on a whitespace
     * location, and returns a fragment with the whitespace at
     * the end.  If a whitespace location can't be found, the
     * nearest character is used.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @param p0 the location in the model where the
     *  fragment should start it's representation >= 0.
     * @param pos the position along the axis that the
     *  broken view would occupy >= 0.  This may be useful for
     *  things like tab calculations.
     * @param len specifies the distance along the axis
     *  where a potential break is desired >= 0.
     * @return the fragment of the view that represents the
     *  given span, if the view can be broken.  If the view
     *  doesn't support breaking behavior, the view itself is
     *  returned.
     * @see View#breakView
     */
    public View breakView(int axis, int p0, float pos, float len) {
        if (axis == View.X_AXIS) {
            checkPainter();
            int p1 = painter.getBoundedPosition(this, p0, pos, len);
            int breakSpot = getBreakSpot(p0, p1);

            if (breakSpot != -1) {
                p1 = breakSpot;
            }
            // else, no break in the region, return a fragment of the
            // bounded region.
            if (p0 == getStartOffset() && p1 == getEndOffset()) {
                return this;
            }
            GlyphView v = (GlyphView) createFragment(p0, p1);
            v.x = (int) pos;
            return v;
        }
        return this;
    }

    /**
     * Returns a location to break at in the passed in region, or
     * BreakIterator.DONE if there isn't a good location to break at
     * in the specified region.
     */
    private int getBreakSpot(int p0, int p1) {
        if (breakSpots == null) {
            // Re-calculate breakpoints for the whole view
            int start = getStartOffset();
            int end = getEndOffset();
            int[] bs = new int[end + 1 - start];
            int ix = 0;

            // Breaker should work on the parent element because there may be
            // a valid breakpoint at the end edge of the view (space, etc.)
            Element parent = getElement().getParentElement();
            int pstart = (parent == null ? start : parent.getStartOffset());
            int pend = (parent == null ? end : parent.getEndOffset());

            Segment s = getText(pstart, pend);
            s.first();
            BreakIterator breaker = getBreaker();
            breaker.setText(s);

            // Backward search should start from end+1 unless there's NO end+1
            int startFrom = end + (pend > end ? 1 : 0);
            for (;;) {
                startFrom = breaker.preceding(s.offset + (startFrom - pstart))
                          + (pstart - s.offset);
                if (startFrom > start) {
                    // The break spot is within the view
                    bs[ix++] = startFrom;
                } else {
                    break;
                }
            }

            SegmentCache.releaseSharedSegment(s);
            breakSpots = new int[ix];
            System.arraycopy(bs, 0, breakSpots, 0, ix);
        }

        int breakSpot = BreakIterator.DONE;
        for (int i = 0; i < breakSpots.length; i++) {
            int bsp = breakSpots[i];
            if (bsp <= p1) {
                if (bsp > p0) {
                    breakSpot = bsp;
                }
                break;
            }
        }
        return breakSpot;
    }

    /**
     * Return break iterator appropriate for the current document.
     *
     * For non-i18n documents a fast whitespace-based break iterator is used.
     */
    private BreakIterator getBreaker() {
        Document doc = getDocument();
        if ((doc != null) && Boolean.TRUE.equals(
                    doc.getProperty(AbstractDocument.MultiByteProperty))) {
            Container c = getContainer();
            Locale locale = (c == null ? Locale.getDefault() : c.getLocale());
            return BreakIterator.getLineInstance(locale);
        } else {
            return new WhitespaceBasedBreakIterator();
        }
    }

    /**
     * Creates a view that represents a portion of the element.
     * This is potentially useful during formatting operations
     * for taking measurements of fragments of the view.  If
     * the view doesn't support fragmenting (the default), it
     * should return itself.
     * <p>
     * This view does support fragmenting.  It is implemented
     * to return a nested class that shares state in this view
     * representing only a portion of the view.
     *
     * @param p0 the starting offset >= 0.  This should be a value
     *   greater or equal to the element starting offset and
     *   less than the element ending offset.
     * @param p1 the ending offset > p0.  This should be a value
     *   less than or equal to the elements end offset and
     *   greater than the elements starting offset.
     * @return the view fragment, or itself if the view doesn't
     *   support breaking into fragments
     * @see LabelView
     */
    public View createFragment(int p0, int p1) {
        checkPainter();
        Element elem = getElement();
        GlyphView v = (GlyphView) clone();
        v.offset = p0 - elem.getStartOffset();
        v.length = p1 - p0;
        v.painter = painter.getPainter(v, p0, p1);
        v.justificationInfo = null;
        return v;
    }

    /**
     * Provides a way to determine the next visually represented model
     * location that one might place a caret.  Some views may not be
     * visible, they might not be in the same order found in the model, or
     * they just might not allow access to some of the locations in the
     * model.
     *
     * @param pos the position to convert >= 0
     * @param a the allocated region to render into
     * @param direction the direction from the current position that can
     *  be thought of as the arrow keys typically found on a keyboard.
     *  This may be SwingConstants.WEST, SwingConstants.EAST,
     *  SwingConstants.NORTH, or SwingConstants.SOUTH.
     * @return the location within the model that best represents the next
     *  location visual position.
     * @exception BadLocationException
     * @exception IllegalArgumentException for an invalid direction
     */
    public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a,
                                         int direction,
                                         Position.Bias[] biasRet)
        throws BadLocationException {

        return painter.getNextVisualPositionFrom(this, pos, b, a, direction, biasRet);
    }

    /**
     * Gives notification that something was inserted into
     * the document in a location that this view is responsible for.
     * This is implemented to call preferenceChanged along the
     * axis the glyphs are rendered.
     *
     * @param e the change information from the associated document
     * @param a the current allocation of the view
     * @param f the factory to use to rebuild if the view has children
     * @see View#insertUpdate
     */
    public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) {
        justificationInfo = null;
        breakSpots = null;
        minimumSpan = -1;
        syncCR();
        preferenceChanged(null, true, false);
    }

    /**
     * Gives notification that something was removed from the document
     * in a location that this view is responsible for.
     * This is implemented to call preferenceChanged along the
     * axis the glyphs are rendered.
     *
     * @param e the change information from the associated document
     * @param a the current allocation of the view
     * @param f the factory to use to rebuild if the view has children
     * @see View#removeUpdate
     */
    public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) {
        justificationInfo = null;
        breakSpots = null;
        minimumSpan = -1;
        syncCR();
        preferenceChanged(null, true, false);
    }

    /**
     * Gives notification from the document that attributes were changed
     * in a location that this view is responsible for.
     * This is implemented to call preferenceChanged along both the
     * horizontal and vertical axis.
     *
     * @param e the change information from the associated document
     * @param a the current allocation of the view
     * @param f the factory to use to rebuild if the view has children
     * @see View#changedUpdate
     */
    public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
        minimumSpan = -1;
        syncCR();
        preferenceChanged(null, true, true);
    }

    // checks if the paragraph is empty and updates impliedCR flag
    // accordingly
    private void syncCR() {
        if (impliedCR) {
            Element parent = getElement().getParentElement();
            impliedCR = (parent != null && parent.getElementCount() > 1);
        }
    }

    /**
     * Class to hold data needed to justify this GlyphView in a PargraphView.Row
     */
    static class JustificationInfo {
        //justifiable content start
        final int start;
        //justifiable content end
        final int end;
        final int leadingSpaces;
        final int contentSpaces;
        final int trailingSpaces;
        final boolean hasTab;
        final BitSet spaceMap;
        JustificationInfo(int start, int end,
                          int leadingSpaces,
                          int contentSpaces,
                          int trailingSpaces,
                          boolean hasTab,
                          BitSet spaceMap) {
            this.start = start;
            this.end = end;
            this.leadingSpaces = leadingSpaces;
            this.contentSpaces = contentSpaces;
            this.trailingSpaces = trailingSpaces;
            this.hasTab = hasTab;
            this.spaceMap = spaceMap;
        }
    }



    JustificationInfo getJustificationInfo(int rowStartOffset) {
        if (justificationInfo != null) {
            return justificationInfo;
        }
        //states for the parsing
        final int TRAILING = 0;
        final int CONTENT  = 1;
        final int SPACES   = 2;
        int startOffset = getStartOffset();
        int endOffset = getEndOffset();
        Segment segment = getText(startOffset, endOffset);
        int txtOffset = segment.offset;
        int txtEnd = segment.offset + segment.count - 1;
        int startContentPosition = txtEnd + 1;
        int endContentPosition = txtOffset - 1;
        int lastTabPosition = txtOffset - 1;
        int trailingSpaces = 0;
        int contentSpaces = 0;
        int leadingSpaces = 0;
        boolean hasTab = false;
        BitSet spaceMap = new BitSet(endOffset - startOffset + 1);

        //we parse conent to the right of the rightmost TAB only.
        //we are looking for the trailing and leading spaces.
        //position after the leading spaces (startContentPosition)
        //position before the trailing spaces (endContentPosition)
        for (int i = txtEnd, state = TRAILING; i >= txtOffset; i--) {
            if (' ' == segment.array[i]) {
                spaceMap.set(i - txtOffset);
                if (state == TRAILING) {
                    trailingSpaces++;
                } else if (state == CONTENT) {
                    state = SPACES;
                    leadingSpaces = 1;
                } else if (state == SPACES) {
                    leadingSpaces++;
                }
            } else if ('\t' == segment.array[i]) {
                hasTab = true;
                break;
            } else {
                if (state == TRAILING) {
                    if ('\n' != segment.array[i]
                          && '\r' != segment.array[i]) {
                        state = CONTENT;
                        endContentPosition = i;
                    }
                } else if (state == CONTENT) {
                    //do nothing
                } else if (state == SPACES) {
                    contentSpaces += leadingSpaces;
                    leadingSpaces = 0;
                }
                startContentPosition = i;
            }
        }

        SegmentCache.releaseSharedSegment(segment);

        int startJustifiableContent = -1;
        if (startContentPosition < txtEnd) {
            startJustifiableContent =
                startContentPosition - txtOffset;
        }
        int endJustifiableContent = -1;
        if (endContentPosition > txtOffset) {
            endJustifiableContent =
                endContentPosition - txtOffset;
        }
        justificationInfo =
            new JustificationInfo(startJustifiableContent,
                                  endJustifiableContent,
                                  leadingSpaces,
                                  contentSpaces,
                                  trailingSpaces,
                                  hasTab,
                                  spaceMap);
        return justificationInfo;
    }

    // --- variables ------------------------------------------------

    /**
    * Used by paint() to store highlighted view positions
    */
    private byte[] selections = null;

    int offset;
    int length;
    // if it is an implied newline character
    boolean impliedCR;
    private static final String IMPLIED_CR = "CR";
    boolean skipWidth;

    /**
     * how to expand tabs
     */
    TabExpander expander;

    /** Cached minimum x-span value  */
    private float minimumSpan = -1;

    /** Cached breakpoints within the view  */
    private int[] breakSpots = null;

    /**
     * location for determining tab expansion against.
     */
    int x;

    /**
     * Glyph rendering functionality.
     */
    GlyphPainter painter;

    /**
     * The prototype painter used by default.
     */
    static GlyphPainter defaultPainter;

    private JustificationInfo justificationInfo = null;

    /**
     * A class to perform rendering of the glyphs.
     * This can be implemented to be stateless, or
     * to hold some information as a cache to
     * facilitate faster rendering and model/view
     * translation.  At a minimum, the GlyphPainter
     * allows a View implementation to perform its
     * duties independant of a particular version
     * of JVM and selection of capabilities (i.e.
     * shaping for i18n, etc).
     *
     * @since 1.3
     */
    public static abstract class GlyphPainter {

        /**
         * Determine the span the glyphs given a start location
         * (for tab expansion).
         */
        public abstract float getSpan(GlyphView v, int p0, int p1, TabExpander e, float x);

        public abstract float getHeight(GlyphView v);

        public abstract float getAscent(GlyphView v);

        public abstract float getDescent(GlyphView v);

        /**
         * Paint the glyphs representing the given range.
         */
        public abstract void paint(GlyphView v, Graphics g, Shape a, int p0, int p1);

        /**
         * Provides a mapping from the document model coordinate space
         * to the coordinate space of the view mapped to it.
         * This is shared by the broken views.
         *
         * @param v     the <code>GlyphView</code> containing the
         *              destination coordinate space
         * @param pos   the position to convert
         * @param bias  either <code>Position.Bias.Forward</code>
         *                  or <code>Position.Bias.Backward</code>
         * @param a     Bounds of the View
         * @return      the bounding box of the given position
         * @exception BadLocationException  if the given position does not represent a
         *   valid location in the associated document
         * @see View#modelToView
         */
        public abstract Shape modelToView(GlyphView v,
                                          int pos, Position.Bias bias,
                                          Shape a) throws BadLocationException;

        /**
         * Provides a mapping from the view coordinate space to the logical
         * coordinate space of the model.
         *
         * @param v          the <code>GlyphView</code> to provide a mapping for
         * @param x          the X coordinate
         * @param y          the Y coordinate
         * @param a          the allocated region to render into
         * @param biasReturn either <code>Position.Bias.Forward</code>
         *                   or <code>Position.Bias.Backward</code>
         *                   is returned as the zero-th element of this array
         * @return the location within the model that best represents the
         *         given point of view
         * @see View#viewToModel
         */
        public abstract int viewToModel(GlyphView v,
                                        float x, float y, Shape a,
                                        Position.Bias[] biasReturn);

        /**
         * Determines the model location that represents the
         * maximum advance that fits within the given span.
         * This could be used to break the given view.  The result
         * should be a location just shy of the given advance.  This
         * differs from viewToModel which returns the closest
         * position which might be proud of the maximum advance.
         *
         * @param v the view to find the model location to break at.
         * @param p0 the location in the model where the
         *  fragment should start it's representation >= 0.
         * @param x  the graphic location along the axis that the
         *  broken view would occupy >= 0.  This may be useful for
         *  things like tab calculations.
         * @param len specifies the distance into the view
         *  where a potential break is desired >= 0.
         * @return the maximum model location possible for a break.
         * @see View#breakView
         */
        public abstract int getBoundedPosition(GlyphView v, int p0, float x, float len);

        /**
         * Create a painter to use for the given GlyphView.  If
         * the painter carries state it can create another painter
         * to represent a new GlyphView that is being created.  If
         * the painter doesn't hold any significant state, it can
         * return itself.  The default behavior is to return itself.
         * @param v  the <code>GlyphView</code> to provide a painter for
         * @param p0 the starting document offset >= 0
         * @param p1 the ending document offset >= p0
         */
        public GlyphPainter getPainter(GlyphView v, int p0, int p1) {
            return this;
        }

        /**
         * Provides a way to determine the next visually represented model
         * location that one might place a caret.  Some views may not be
         * visible, they might not be in the same order found in the model, or
         * they just might not allow access to some of the locations in the
         * model.
         *
         * @param v the view to use
         * @param pos the position to convert >= 0
         * @param b   either <code>Position.Bias.Forward</code>
         *                or <code>Position.Bias.Backward</code>
         * @param a the allocated region to render into
         * @param direction the direction from the current position that can
         *  be thought of as the arrow keys typically found on a keyboard.
         *  This may be SwingConstants.WEST, SwingConstants.EAST,
         *  SwingConstants.NORTH, or SwingConstants.SOUTH.
         * @param biasRet  either <code>Position.Bias.Forward</code>
         *                 or <code>Position.Bias.Backward</code>
         *                 is returned as the zero-th element of this array
         * @return the location within the model that best represents the next
         *  location visual position.
         * @exception BadLocationException
         * @exception IllegalArgumentException for an invalid direction
         */
        public int getNextVisualPositionFrom(GlyphView v, int pos, Position.Bias b, Shape a,
                                             int direction,
                                             Position.Bias[] biasRet)
            throws BadLocationException {

            int startOffset = v.getStartOffset();
            int endOffset = v.getEndOffset();
            Segment text;

            switch (direction) {
            case View.NORTH:
            case View.SOUTH:
                if (pos != -1) {
                    // Presumably pos is between startOffset and endOffset,
                    // since GlyphView is only one line, we won't contain
                    // the position to the nort/south, therefore return -1.
                    return -1;
                }
                Container container = v.getContainer();

                if (container instanceof JTextComponent) {
                    Caret c = ((JTextComponent)container).getCaret();
                    Point magicPoint;
                    magicPoint = (c != null) ? c.getMagicCaretPosition() :null;

                    if (magicPoint == null) {
                        biasRet[0] = Position.Bias.Forward;
                        return startOffset;
                    }
                    int value = v.viewToModel(magicPoint.x, 0f, a, biasRet);
                    return value;
                }
                break;
            case View.EAST:
                if(startOffset == v.getDocument().getLength()) {
                    if(pos == -1) {
                        biasRet[0] = Position.Bias.Forward;
                        return startOffset;
                    }
                    // End case for bidi text where newline is at beginning
                    // of line.
                    return -1;
                }
                if(pos == -1) {
                    biasRet[0] = Position.Bias.Forward;
                    return startOffset;
                }
                if(pos == endOffset) {
                    return -1;
                }
                if(++pos == endOffset) {
                    // Assumed not used in bidi text, GlyphPainter2 will
                    // override as necessary, therefore return -1.
                    return -1;
                }
                else {
                    biasRet[0] = Position.Bias.Forward;
                }
                return pos;
            case View.WEST:
                if(startOffset == v.getDocument().getLength()) {
                    if(pos == -1) {
                        biasRet[0] = Position.Bias.Forward;
                        return startOffset;
                    }
                    // End case for bidi text where newline is at beginning
                    // of line.
                    return -1;
                }
                if(pos == -1) {
                    // Assumed not used in bidi text, GlyphPainter2 will
                    // override as necessary, therefore return -1.
                    biasRet[0] = Position.Bias.Forward;
                    return endOffset - 1;
                }
                if(pos == startOffset) {
                    return -1;
                }
                biasRet[0] = Position.Bias.Forward;
                return (pos - 1);
            default:
                throw new IllegalArgumentException("Bad direction: " + direction);
            }
            return pos;

        }
    }
}
