/*
 * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing.text;

import java.util.Vector;
import java.awt.*;
import javax.swing.event.*;
import javax.swing.SwingConstants;

/**
 * <code>CompositeView</code> is an abstract <code>View</code>
 * implementation which manages one or more child views.
 * (Note that <code>CompositeView</code> is intended
 * for managing relatively small numbers of child views.)
 * <code>CompositeView</code> is intended to be used as
 * a starting point for <code>View</code> implementations,
 * such as <code>BoxView</code>, that will contain child
 * <code>View</code>s. Subclasses that wish to manage the
 * collection of child <code>View</code>s should use the
 * {@link #replace} method.  As <code>View</code> invokes
 * <code>replace</code> during <code>DocumentListener</code>
 * notification, you normally won't need to directly
 * invoke <code>replace</code>.
 *
 * <p>While <code>CompositeView</code>
 * does not impose a layout policy on its child <code>View</code>s,
 * it does allow for inseting the child <code>View</code>s
 * it will contain.  The insets can be set by either
 * {@link #setInsets} or {@link #setParagraphInsets}.
 *
 * <p>In addition to the abstract methods of
 * {@link javax.swing.text.View},
 * subclasses of <code>CompositeView</code> will need to
 * override:
 * <ul>
 * <li>{@link #isBefore} - Used to test if a given
 *     <code>View</code> location is before the visual space
 *     of the <code>CompositeView</code>.
 * <li>{@link #isAfter} - Used to test if a given
 *     <code>View</code> location is after the visual space
 *     of the <code>CompositeView</code>.
 * <li>{@link #getViewAtPoint} - Returns the view at
 *     a given visual location.
 * <li>{@link #childAllocation} - Returns the bounds of
 *     a particular child <code>View</code>.
 *     <code>getChildAllocation</code> will invoke
 *     <code>childAllocation</code> after offseting
 *     the bounds by the <code>Inset</code>s of the
 *     <code>CompositeView</code>.
 * </ul>
 *
 * @author  Timothy Prinzing
 */
public abstract class CompositeView extends View {

    /**
     * Constructs a <code>CompositeView</code> for the given element.
     *
     * @param elem  the element this view is responsible for
     */
    public CompositeView(Element elem) {
        super(elem);
        children = new View[1];
        nchildren = 0;
        childAlloc = new Rectangle();
    }

    /**
     * Loads all of the children to initialize the view.
     * This is called by the {@link #setParent}
     * method.  Subclasses can reimplement this to initialize
     * their child views in a different manner.  The default
     * implementation creates a child view for each
     * child element.
     *
     * @param f the view factory
     * @see #setParent
     */
    protected void loadChildren(ViewFactory f) {
        if (f == null) {
            // No factory. This most likely indicates the parent view
            // has changed out from under us, bail!
            return;
        }
        Element e = getElement();
        int n = e.getElementCount();
        if (n > 0) {
            View[] added = new View[n];
            for (int i = 0; i < n; i++) {
                added[i] = f.create(e.getElement(i));
            }
            replace(0, 0, added);
        }
    }

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

    /**
     * Sets the parent of the view.
     * This is reimplemented to provide the superclass
     * behavior as well as calling the <code>loadChildren</code>
     * method if this view does not already have children.
     * The children should not be loaded in the
     * constructor because the act of setting the parent
     * may cause them to try to search up the hierarchy
     * (to get the hosting <code>Container</code> for example).
     * If this view has children (the view is being moved
     * from one place in the view hierarchy to another),
     * the <code>loadChildren</code> method will not be called.
     *
     * @param parent the parent of the view, <code>null</code> if none
     */
    public void setParent(View parent) {
        super.setParent(parent);
        if ((parent != null) && (nchildren == 0)) {
            ViewFactory f = getViewFactory();
            loadChildren(f);
        }
    }

    /**
     * Returns the number of child views of this view.
     *
     * @return the number of views >= 0
     * @see #getView
     */
    public int getViewCount() {
        return nchildren;
    }

    /**
     * Returns the n-th view in this container.
     *
     * @param n the number of the desired view, >= 0 && < getViewCount()
     * @return the view at index <code>n</code>
     */
    public View getView(int n) {
        return children[n];
    }

    /**
     * Replaces child views.  If there are no views to remove
     * this acts as an insert.  If there are no views to
     * add this acts as a remove.  Views being removed will
     * have the parent set to <code>null</code>,
     * and the internal reference to them removed so that they
     * may be garbage collected.
     *
     * @param offset the starting index into the child views to insert
     *   the new views; >= 0 and <= getViewCount
     * @param length the number of existing child views to remove;
     *   this should be a value >= 0 and <= (getViewCount() - offset)
     * @param views the child views to add; this value can be
     *  <code>null</code>
     *   to indicate no children are being added (useful to remove)
     */
    public void replace(int offset, int length, View[] views) {
        // make sure an array exists
        if (views == null) {
            views = ZERO;
        }

        // update parent reference on removed views
        for (int i = offset; i < offset + length; i++) {
            if (children[i].getParent() == this) {
                // in FlowView.java view might be referenced
                // from two super-views as a child. see logicalView
                children[i].setParent(null);
            }
            children[i] = null;
        }

        // update the array
        int delta = views.length - length;
        int src = offset + length;
        int nmove = nchildren - src;
        int dest = src + delta;
        if ((nchildren + delta) >= children.length) {
            // need to grow the array
            int newLength = Math.max(2*children.length, nchildren + delta);
            View[] newChildren = new View[newLength];
            System.arraycopy(children, 0, newChildren, 0, offset);
            System.arraycopy(views, 0, newChildren, offset, views.length);
            System.arraycopy(children, src, newChildren, dest, nmove);
            children = newChildren;
        } else {
            // patch the existing array
            System.arraycopy(children, src, children, dest, nmove);
            System.arraycopy(views, 0, children, offset, views.length);
        }
        nchildren = nchildren + delta;

        // update parent reference on added views
        for (int i = 0; i < views.length; i++) {
            views[i].setParent(this);
        }
    }

    /**
     * Fetches the allocation for the given child view to
     * render into. This enables finding out where various views
     * are located.
     *
     * @param index the index of the child, >= 0 && < getViewCount()
     * @param a  the allocation to this view
     * @return the allocation to the child
     */
    public Shape getChildAllocation(int index, Shape a) {
        Rectangle alloc = getInsideAllocation(a);
        childAllocation(index, alloc);
        return alloc;
    }

    /**
     * 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 a bias value of 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 {
        boolean isBackward = (b == Position.Bias.Backward);
        int testPos = (isBackward) ? Math.max(0, pos - 1) : pos;
        if(isBackward && testPos < getStartOffset()) {
            return null;
        }
        int vIndex = getViewIndexAtPosition(testPos);
        if ((vIndex != -1) && (vIndex < getViewCount())) {
            View v = getView(vIndex);
            if(v != null && testPos >= v.getStartOffset() &&
               testPos < v.getEndOffset()) {
                Shape childShape = getChildAllocation(vIndex, a);
                if (childShape == null) {
                    // We are likely invalid, fail.
                    return null;
                }
                Shape retShape = v.modelToView(pos, childShape, b);
                if(retShape == null && v.getEndOffset() == pos) {
                    if(++vIndex < getViewCount()) {
                        v = getView(vIndex);
                        retShape = v.modelToView(pos, getChildAllocation(vIndex, a), b);
                    }
                }
                return retShape;
            }
        }
        throw new BadLocationException("Position not represented by view",
                                       pos);
    }

    /**
     * Provides a mapping from the document model coordinate space
     * to the coordinate space of the view mapped to it.
     *
     * @param p0 the position to convert >= 0
     * @param b0 the bias toward the previous character or the
     *  next character represented by p0, in case the
     *  position is a boundary of two views; either
     *  <code>Position.Bias.Forward</code> or
     *  <code>Position.Bias.Backward</code>
     * @param p1 the position to convert >= 0
     * @param b1 the bias toward the previous character or the
     *  next character represented by p1, in case the
     *  position is a boundary of two views
     * @param a the allocated region to render into
     * @return the bounding box of the given position is returned
     * @exception BadLocationException  if the given position does
     *   not represent a valid location in the associated document
     * @exception IllegalArgumentException for an invalid bias argument
     * @see View#viewToModel
     */
    public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, Shape a) throws BadLocationException {
        if (p0 == getStartOffset() && p1 == getEndOffset()) {
            return a;
        }
        Rectangle alloc = getInsideAllocation(a);
        Rectangle r0 = new Rectangle(alloc);
        View v0 = getViewAtPosition((b0 == Position.Bias.Backward) ?
                                    Math.max(0, p0 - 1) : p0, r0);
        Rectangle r1 = new Rectangle(alloc);
        View v1 = getViewAtPosition((b1 == Position.Bias.Backward) ?
                                    Math.max(0, p1 - 1) : p1, r1);
        if (v0 == v1) {
            if (v0 == null) {
                return a;
            }
            // Range contained in one view
            return v0.modelToView(p0, b0, p1, b1, r0);
        }
        // Straddles some views.
        int viewCount = getViewCount();
        int counter = 0;
        while (counter < viewCount) {
            View v;
            // Views may not be in same order as model.
            // v0 or v1 may be null if there is a gap in the range this
            // view contains.
            if ((v = getView(counter)) == v0 || v == v1) {
                View endView;
                Rectangle retRect;
                Rectangle tempRect = new Rectangle();
                if (v == v0) {
                    retRect = v0.modelToView(p0, b0, v0.getEndOffset(),
                                             Position.Bias.Backward, r0).
                              getBounds();
                    endView = v1;
                }
                else {
                    retRect = v1.modelToView(v1.getStartOffset(),
                                             Position.Bias.Forward,
                                             p1, b1, r1).getBounds();
                    endView = v0;
                }

                // Views entirely covered by range.
                while (++counter < viewCount &&
                       (v = getView(counter)) != endView) {
                    tempRect.setBounds(alloc);
                    childAllocation(counter, tempRect);
                    retRect.add(tempRect);
                }

                // End view.
                if (endView != null) {
                    Shape endShape;
                    if (endView == v1) {
                        endShape = v1.modelToView(v1.getStartOffset(),
                                                  Position.Bias.Forward,
                                                  p1, b1, r1);
                    }
                    else {
                        endShape = v0.modelToView(p0, b0, v0.getEndOffset(),
                                                  Position.Bias.Backward, r0);
                    }
                    if (endShape instanceof Rectangle) {
                        retRect.add((Rectangle)endShape);
                    }
                    else {
                        retRect.add(endShape.getBounds());
                    }
                }
                return retRect;
            }
            counter++;
        }
        throw new BadLocationException("Position not represented by view", p0);
    }

    /**
     * Provides a mapping from the view coordinate space to the logical
     * coordinate space of the model.
     *
     * @param x   x coordinate of the view location to convert >= 0
     * @param y   y coordinate of the view location to convert >= 0
     * @param a the allocated region to render into
     * @param bias either <code>Position.Bias.Forward</code> or
     *  <code>Position.Bias.Backward</code>
     * @return the location within the model that best represents the
     *  given point in the view >= 0
     * @see View#viewToModel
     */
    public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
        Rectangle alloc = getInsideAllocation(a);
        if (isBefore((int) x, (int) y, alloc)) {
            // point is before the range represented
            int retValue = -1;

            try {
                retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward,
                                                     a, EAST, bias);
            } catch (BadLocationException ble) { }
            catch (IllegalArgumentException iae) { }
            if(retValue == -1) {
                retValue = getStartOffset();
                bias[0] = Position.Bias.Forward;
            }
            return retValue;
        } else if (isAfter((int) x, (int) y, alloc)) {
            // point is after the range represented.
            int retValue = -1;
            try {
                retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward,
                                                     a, WEST, bias);
            } catch (BadLocationException ble) { }
            catch (IllegalArgumentException iae) { }

            if(retValue == -1) {
                // NOTE: this could actually use end offset with backward.
                retValue = getEndOffset() - 1;
                bias[0] = Position.Bias.Forward;
            }
            return retValue;
        } else {
            // locate the child and pass along the request
            View v = getViewAtPoint((int) x, (int) y, alloc);
            if (v != null) {
              return v.viewToModel(x, y, alloc, bias);
            }
        }
        return -1;
    }

    /**
     * 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.
     * This is a convenience method for {@link #getNextNorthSouthVisualPositionFrom}
     * and {@link #getNextEastWestVisualPositionFrom}.
     *
     * @param pos the position to convert >= 0
     * @param b a bias value of 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 one of the following:
     *  <ul>
     *  <li><code>SwingConstants.WEST</code>
     *  <li><code>SwingConstants.EAST</code>
     *  <li><code>SwingConstants.NORTH</code>
     *  <li><code>SwingConstants.SOUTH</code>
     *  </ul>
     * @param biasRet an array containing the bias that was checked
     * @return the location within the model that best represents the next
     *  location visual position
     * @exception BadLocationException
     * @exception IllegalArgumentException if <code>direction</code> is invalid
     */
    public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a,
                                         int direction, Position.Bias[] biasRet)
      throws BadLocationException {
        Rectangle alloc = getInsideAllocation(a);

        switch (direction) {
        case NORTH:
            return getNextNorthSouthVisualPositionFrom(pos, b, a, direction,
                                                       biasRet);
        case SOUTH:
            return getNextNorthSouthVisualPositionFrom(pos, b, a, direction,
                                                       biasRet);
        case EAST:
            return getNextEastWestVisualPositionFrom(pos, b, a, direction,
                                                     biasRet);
        case WEST:
            return getNextEastWestVisualPositionFrom(pos, b, a, direction,
                                                     biasRet);
        default:
            throw new IllegalArgumentException("Bad direction: " + direction);
        }
    }

    /**
     * Returns the child view index representing the given
     * position in the model.  This is implemented to call the
     * <code>getViewIndexByPosition</code>
     * method for backward compatibility.
     *
     * @param pos the position >= 0
     * @return  index of the view representing the given position, or
     *   -1 if no view represents that position
     * @since 1.3
     */
    public int getViewIndex(int pos, Position.Bias b) {
        if(b == Position.Bias.Backward) {
            pos -= 1;
        }
        if ((pos >= getStartOffset()) && (pos < getEndOffset())) {
            return getViewIndexAtPosition(pos);
        }
        return -1;
    }

    // --- local methods ----------------------------------------------------


    /**
     * Tests whether a point lies before the rectangle range.
     *
     * @param x the X coordinate >= 0
     * @param y the Y coordinate >= 0
     * @param alloc the rectangle
     * @return true if the point is before the specified range
     */
    protected abstract boolean isBefore(int x, int y, Rectangle alloc);

    /**
     * Tests whether a point lies after the rectangle range.
     *
     * @param x the X coordinate >= 0
     * @param y the Y coordinate >= 0
     * @param alloc the rectangle
     * @return true if the point is after the specified range
     */
    protected abstract boolean isAfter(int x, int y, Rectangle alloc);

    /**
     * Fetches the child view at the given coordinates.
     *
     * @param x the X coordinate >= 0
     * @param y the Y coordinate >= 0
     * @param alloc the parent's allocation on entry, which should
     *   be changed to the child's allocation on exit
     * @return the child view
     */
    protected abstract View getViewAtPoint(int x, int y, Rectangle alloc);

    /**
     * Returns the allocation for a given child.
     *
     * @param index the index of the child, >= 0 && < getViewCount()
     * @param a  the allocation to the interior of the box on entry,
     *   and the allocation of the child view at the index on exit.
     */
    protected abstract void childAllocation(int index, Rectangle a);

    /**
     * Fetches the child view that represents the given position in
     * the model.  This is implemented to fetch the view in the case
     * where there is a child view for each child element.
     *
     * @param pos the position >= 0
     * @param a  the allocation to the interior of the box on entry,
     *   and the allocation of the view containing the position on exit
     * @return  the view representing the given position, or
     *   <code>null</code> if there isn't one
     */
    protected View getViewAtPosition(int pos, Rectangle a) {
        int index = getViewIndexAtPosition(pos);
        if ((index >= 0) && (index < getViewCount())) {
            View v = getView(index);
            if (a != null) {
                childAllocation(index, a);
            }
            return v;
        }
        return null;
    }

    /**
     * Fetches the child view index representing the given position in
     * the model.  This is implemented to fetch the view in the case
     * where there is a child view for each child element.
     *
     * @param pos the position >= 0
     * @return  index of the view representing the given position, or
     *   -1 if no view represents that position
     */
    protected int getViewIndexAtPosition(int pos) {
        Element elem = getElement();
        return elem.getElementIndex(pos);
    }

    /**
     * Translates the immutable allocation given to the view
     * to a mutable allocation that represents the interior
     * allocation (i.e. the bounds of the given allocation
     * with the top, left, bottom, and right insets removed.
     * It is expected that the returned value would be further
     * mutated to represent an allocation to a child view.
     * This is implemented to reuse an instance variable so
     * it avoids creating excessive Rectangles.  Typically
     * the result of calling this method would be fed to
     * the <code>childAllocation</code> method.
     *
     * @param a the allocation given to the view
     * @return the allocation that represents the inside of the
     *   view after the margins have all been removed; if the
     *   given allocation was <code>null</code>,
     *   the return value is <code>null</code>
     */
    protected Rectangle getInsideAllocation(Shape a) {
        if (a != null) {
            // get the bounds, hopefully without allocating
            // a new rectangle.  The Shape argument should
            // not be modified... we copy it into the
            // child allocation.
            Rectangle alloc;
            if (a instanceof Rectangle) {
                alloc = (Rectangle) a;
            } else {
                alloc = a.getBounds();
            }

            childAlloc.setBounds(alloc);
            childAlloc.x += getLeftInset();
            childAlloc.y += getTopInset();
            childAlloc.width -= getLeftInset() + getRightInset();
            childAlloc.height -= getTopInset() + getBottomInset();
            return childAlloc;
        }
        return null;
    }

    /**
     * Sets the insets from the paragraph attributes specified in
     * the given attributes.
     *
     * @param attr the attributes
     */
    protected void setParagraphInsets(AttributeSet attr) {
        // Since version 1.1 doesn't have scaling and assumes
        // a pixel is equal to a point, we just cast the point
        // sizes to integers.
        top = (short) StyleConstants.getSpaceAbove(attr);
        left = (short) StyleConstants.getLeftIndent(attr);
        bottom = (short) StyleConstants.getSpaceBelow(attr);
        right = (short) StyleConstants.getRightIndent(attr);
    }

    /**
     * Sets the insets for the view.
     *
     * @param top the top inset >= 0
     * @param left the left inset >= 0
     * @param bottom the bottom inset >= 0
     * @param right the right inset >= 0
     */
    protected void setInsets(short top, short left, short bottom, short right) {
        this.top = top;
        this.left = left;
        this.right = right;
        this.bottom = bottom;
    }

    /**
     * Gets the left inset.
     *
     * @return the inset >= 0
     */
    protected short getLeftInset() {
        return left;
    }

    /**
     * Gets the right inset.
     *
     * @return the inset >= 0
     */
    protected short getRightInset() {
        return right;
    }

    /**
     * Gets the top inset.
     *
     * @return the inset >= 0
     */
    protected short getTopInset() {
        return top;
    }

    /**
     * Gets the bottom inset.
     *
     * @return the inset >= 0
     */
    protected short getBottomInset() {
        return bottom;
    }

    /**
     * Returns the next visual position for the cursor, in either the
     * north or south direction.
     *
     * @param pos the position to convert >= 0
     * @param b a bias value of 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 one of the following:
     *  <ul>
     *  <li><code>SwingConstants.NORTH</code>
     *  <li><code>SwingConstants.SOUTH</code>
     *  </ul>
     * @param biasRet an array containing the bias that was checked
     * @return the location within the model that best represents the next
     *  north or south location
     * @exception BadLocationException
     * @exception IllegalArgumentException if <code>direction</code> is invalid
     * @see #getNextVisualPositionFrom
     *
     * @return the next position west of the passed in position
     */
    protected int getNextNorthSouthVisualPositionFrom(int pos, Position.Bias b,
                                                      Shape a, int direction,
                                                      Position.Bias[] biasRet)
                                                throws BadLocationException {
        return Utilities.getNextVisualPositionFrom(
                            this, pos, b, a, direction, biasRet);
    }

    /**
     * Returns the next visual position for the cursor, in either the
     * east or west direction.
     *
    * @param pos the position to convert >= 0
     * @param b a bias value of 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 one of the following:
     *  <ul>
     *  <li><code>SwingConstants.WEST</code>
     *  <li><code>SwingConstants.EAST</code>
     *  </ul>
     * @param biasRet an array containing the bias that was checked
     * @return the location within the model that best represents the next
     *  west or east location
     * @exception BadLocationException
     * @exception IllegalArgumentException if <code>direction</code> is invalid
     * @see #getNextVisualPositionFrom
     */
    protected int getNextEastWestVisualPositionFrom(int pos, Position.Bias b,
                                                    Shape a,
                                                    int direction,
                                                    Position.Bias[] biasRet)
                                                throws BadLocationException {
        return Utilities.getNextVisualPositionFrom(
                            this, pos, b, a, direction, biasRet);
    }

    /**
     * Determines in which direction the next view lays.
     * Consider the <code>View</code> at index n. Typically the
     * <code>View</code>s are layed out from left to right,
     * so that the <code>View</code> to the EAST will be
     * at index n + 1, and the <code>View</code> to the WEST
     * will be at index n - 1. In certain situations,
     * such as with bidirectional text, it is possible
     * that the <code>View</code> to EAST is not at index n + 1,
     * but rather at index n - 1, or that the <code>View</code>
     * to the WEST is not at index n - 1, but index n + 1.
     * In this case this method would return true, indicating the
     * <code>View</code>s are layed out in descending order.
     * <p>
     * This unconditionally returns false, subclasses should override this
     * method if there is the possibility for laying <code>View</code>s in
     * descending order.
     *
     * @param position position into the model
     * @param bias either <code>Position.Bias.Forward</code> or
     *          <code>Position.Bias.Backward</code>
     * @return false
     */
    protected boolean flipEastAndWestAtEnds(int position,
                                            Position.Bias bias) {
        return false;
    }


    // ---- member variables ---------------------------------------------


    private static View[] ZERO = new View[0];

    private View[] children;
    private int nchildren;
    private short left;
    private short right;
    private short top;
    private short bottom;
    private Rectangle childAlloc;
}
