/*
 * Copyright 1999-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.awt.*;
import java.util.Vector;
import javax.swing.event.*;
import javax.swing.SizeRequirements;

/**
 * A View that tries to flow it's children into some
 * partially constrained space.  This can be used to
 * build things like paragraphs, pages, etc.  The
 * flow is made up of the following pieces of functionality.
 * <ul>
 * <li>A logical set of child views, which as used as a
 * layout pool from which a physical view is formed.
 * <li>A strategy for translating the logical view to
 * a physical (flowed) view.
 * <li>Constraints for the strategy to work against.
 * <li>A physical structure, that represents the flow.
 * The children of this view are where the pieces of
 * of the logical views are placed to create the flow.
 * </ul>
 *
 * @author  Timothy Prinzing
 * @see     View
 * @since 1.3
 */
public abstract class FlowView extends BoxView {

    /**
     * Constructs a FlowView for the given element.
     *
     * @param elem the element that this view is responsible for
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     */
    public FlowView(Element elem, int axis) {
        super(elem, axis);
        layoutSpan = Integer.MAX_VALUE;
        strategy = new FlowStrategy();
    }

    /**
     * Fetches the axis along which views should be
     * flowed.  By default, this will be the axis
     * orthogonal to the axis along which the flow
     * rows are tiled (the axis of the default flow
     * rows themselves).  This is typically used
     * by the <code>FlowStrategy</code>.
     */
    public int getFlowAxis() {
        if (getAxis() == Y_AXIS) {
            return X_AXIS;
        }
        return Y_AXIS;
    }

    /**
     * Fetch the constraining span to flow against for
     * the given child index.  This is called by the
     * FlowStrategy while it is updating the flow.
     * A flow can be shaped by providing different values
     * for the row constraints.  By default, the entire
     * span inside of the insets along the flow axis
     * is returned.
     *
     * @param index the index of the row being updated.
     *   This should be a value >= 0 and < getViewCount().
     * @see #getFlowStart
     */
    public int getFlowSpan(int index) {
        return layoutSpan;
    }

    /**
     * Fetch the location along the flow axis that the
     * flow span will start at.  This is called by the
     * FlowStrategy while it is updating the flow.
     * A flow can be shaped by providing different values
     * for the row constraints.

     * @param index the index of the row being updated.
     *   This should be a value >= 0 and < getViewCount().
     * @see #getFlowSpan
     */
    public int getFlowStart(int index) {
        return 0;
    }

    /**
     * Create a View that should be used to hold a
     * a rows worth of children in a flow.  This is
     * called by the FlowStrategy when new children
     * are added or removed (i.e. rows are added or
     * removed) in the process of updating the flow.
     */
    protected abstract View createRow();

    // ---- BoxView methods -------------------------------------

    /**
     * Loads all of the children to initialize the view.
     * This is called by the <code>setParent</code> method.
     * This is reimplemented to not load any children directly
     * (as they are created in the process of formatting).
     * If the layoutPool variable is null, an instance of
     * LogicalView is created to represent the logical view
     * that is used in the process of formatting.
     *
     * @param f the view factory
     */
    protected void loadChildren(ViewFactory f) {
        if (layoutPool == null) {
            layoutPool = new LogicalView(getElement());
        }
        layoutPool.setParent(this);

        // This synthetic insertUpdate call gives the strategy a chance
        // to initialize.
        strategy.insertUpdate(this, null, null);
    }

    /**
     * Fetches the child view index representing the given position in
     * the model.
     *
     * @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) {
        if (pos >= getStartOffset() && (pos < getEndOffset())) {
            for (int counter = 0; counter < getViewCount(); counter++) {
                View v = getView(counter);
                if(pos >= v.getStartOffset() &&
                   pos < v.getEndOffset()) {
                    return counter;
                }
            }
        }
        return -1;
    }

    /**
     * Lays out the children.  If the span along the flow
     * axis has changed, layout is marked as invalid which
     * which will cause the superclass behavior to recalculate
     * the layout along the box axis.  The FlowStrategy.layout
     * method will be called to rebuild the flow rows as
     * appropriate.  If the height of this view changes
     * (determined by the perferred size along the box axis),
     * a preferenceChanged is called.  Following all of that,
     * the normal box layout of the superclass is performed.
     *
     * @param width  the width to lay out against >= 0.  This is
     *   the width inside of the inset area.
     * @param height the height to lay out against >= 0 This
     *   is the height inside of the inset area.
     */
    protected void layout(int width, int height) {
        final int faxis = getFlowAxis();
        int newSpan;
        if (faxis == X_AXIS) {
            newSpan = (int)width;
        } else {
            newSpan = (int)height;
        }
        if (layoutSpan != newSpan) {
            layoutChanged(faxis);
            layoutChanged(getAxis());
            layoutSpan = newSpan;
        }

        // repair the flow if necessary
        if (! isLayoutValid(faxis)) {
            final int heightAxis = getAxis();
            int oldFlowHeight = (int)((heightAxis == X_AXIS)? getWidth() : getHeight());
            strategy.layout(this);
            int newFlowHeight = (int) getPreferredSpan(heightAxis);
            if (oldFlowHeight != newFlowHeight) {
                View p = getParent();
                if (p != null) {
                    p.preferenceChanged(this, (heightAxis == X_AXIS), (heightAxis == Y_AXIS));
                }

                // PENDING(shannonh)
                // Temporary fix for 4250847
                // Can be removed when TraversalContext is added
                Component host = getContainer();
                if (host != null) {
                    //nb idk 12/12/2001 host should not be equal to null. We need to add assertion here
                    host.repaint();
                }
            }
        }

        super.layout(width, height);
    }

    /**
     * Calculate equirements along the minor axis.  This
     * is implemented to forward the request to the logical
     * view by calling getMinimumSpan, getPreferredSpan, and
     * getMaximumSpan on it.
     */
    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
        if (r == null) {
            r = new SizeRequirements();
        }
        float pref = layoutPool.getPreferredSpan(axis);
        float min = layoutPool.getMinimumSpan(axis);
        // Don't include insets, Box.getXXXSpan will include them.
        r.minimum = (int)min;
        r.preferred = Math.max(r.minimum, (int) pref);
        r.maximum = Integer.MAX_VALUE;
        r.alignment = 0.5f;
        return r;
    }

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

    /**
     * Gives notification that something was inserted into the document
     * in a location that this view is responsible for.
     *
     * @param changes 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 changes, Shape a, ViewFactory f) {
        layoutPool.insertUpdate(changes, a, f);
        strategy.insertUpdate(this, changes, getInsideAllocation(a));
    }

    /**
     * Gives notification that something was removed from the document
     * in a location that this view is responsible for.
     *
     * @param changes 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 changes, Shape a, ViewFactory f) {
        layoutPool.removeUpdate(changes, a, f);
        strategy.removeUpdate(this, changes, getInsideAllocation(a));
    }

    /**
     * Gives notification from the document that attributes were changed
     * in a location that this view is responsible for.
     *
     * @param changes 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 changes, Shape a, ViewFactory f) {
        layoutPool.changedUpdate(changes, a, f);
        strategy.changedUpdate(this, changes, getInsideAllocation(a));
    }

    /** {@inheritDoc} */
    public void setParent(View parent) {
        super.setParent(parent);
        if (parent == null
                && layoutPool != null ) {
            layoutPool.setParent(null);
        }
    }

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

    /**
     * Default constraint against which the flow is
     * created against.
     */
    protected int layoutSpan;

    /**
     * These are the views that represent the child elements
     * of the element this view represents (The logical view
     * to translate to a physical view).  These are not
     * directly children of this view.  These are either
     * placed into the rows directly or used for the purpose
     * of breaking into smaller chunks, to form the physical
     * view.
     */
    protected View layoutPool;

    /**
     * The behavior for keeping the flow updated.  By
     * default this is a singleton shared by all instances
     * of FlowView (FlowStrategy is stateless).  Subclasses
     * can create an alternative strategy, which might keep
     * state.
     */
    protected FlowStrategy strategy;

    /**
     * Strategy for maintaining the physical form
     * of the flow.  The default implementation is
     * completely stateless, and recalculates the
     * entire flow if the layout is invalid on the
     * given FlowView.  Alternative strategies can
     * be implemented by subclassing, and might
     * perform incrementatal repair to the layout
     * or alternative breaking behavior.
     * @since 1.3
     */
    public static class FlowStrategy {
        int damageStart = Integer.MAX_VALUE;
        Vector<View> viewBuffer;

        void addDamage(FlowView fv, int offset) {
            if (offset >= fv.getStartOffset() && offset < fv.getEndOffset()) {
                damageStart = Math.min(damageStart, offset);
            }
        }

        void unsetDamage() {
            damageStart = Integer.MAX_VALUE;
        }

        /**
         * Gives notification that something was inserted into the document
         * in a location that the given flow view is responsible for.  The
         * strategy should update the appropriate changed region (which
         * depends upon the strategy used for repair).
         *
         * @param e the change information from the associated document
         * @param alloc the current allocation of the view inside of the insets.
         *   This value will be null if the view has not yet been displayed.
         * @see View#insertUpdate
         */
        public void insertUpdate(FlowView fv, DocumentEvent e, Rectangle alloc) {
            // FlowView.loadChildren() makes a synthetic call into this,
            // passing null as e
            if (e != null) {
                addDamage(fv, e.getOffset());
            }

            if (alloc != null) {
                Component host = fv.getContainer();
                if (host != null) {
                    host.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
                }
            } else {
                fv.preferenceChanged(null, true, true);
            }
        }

        /**
         * Gives notification that something was removed from the document
         * in a location that the given flow view is responsible for.
         *
         * @param e the change information from the associated document
         * @param alloc the current allocation of the view inside of the insets.
         * @see View#removeUpdate
         */
        public void removeUpdate(FlowView fv, DocumentEvent e, Rectangle alloc) {
            addDamage(fv, e.getOffset());
            if (alloc != null) {
                Component host = fv.getContainer();
                if (host != null) {
                    host.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
                }
            } else {
                fv.preferenceChanged(null, true, true);
            }
        }

        /**
         * Gives notification from the document that attributes were changed
         * in a location that this view is responsible for.
         *
         * @param fv     the <code>FlowView</code> containing the changes
         * @param e      the <code>DocumentEvent</code> describing the changes
         *               done to the Document
         * @param alloc  Bounds of the View
         * @see View#changedUpdate
         */
        public void changedUpdate(FlowView fv, DocumentEvent e, Rectangle alloc) {
            addDamage(fv, e.getOffset());
            if (alloc != null) {
                Component host = fv.getContainer();
                if (host != null) {
                    host.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
                }
            } else {
                fv.preferenceChanged(null, true, true);
            }
        }

        /**
         * This method gives flow strategies access to the logical
         * view of the FlowView.
         */
        protected View getLogicalView(FlowView fv) {
            return fv.layoutPool;
        }

        /**
         * Update the flow on the given FlowView.  By default, this causes
         * all of the rows (child views) to be rebuilt to match the given
         * constraints for each row.  This is called by a FlowView.layout
         * to update the child views in the flow.
         *
         * @param fv the view to reflow
         */
        public void layout(FlowView fv) {
            View pool = getLogicalView(fv);
            int rowIndex, p0;
            int p1 = fv.getEndOffset();

            if (fv.majorAllocValid) {
                if (damageStart == Integer.MAX_VALUE) {
                    return;
                }
                // In some cases there's no view at position damageStart, so
                // step back and search again. See 6452106 for details.
                while ((rowIndex = fv.getViewIndexAtPosition(damageStart)) < 0) {
                    damageStart--;
                }
                if (rowIndex > 0) {
                    rowIndex--;
                }
                p0 = fv.getView(rowIndex).getStartOffset();
            } else {
                rowIndex = 0;
                p0 = fv.getStartOffset();
            }
            reparentViews(pool, p0);

            viewBuffer = new Vector<View>(10, 10);
            int rowCount = fv.getViewCount();
            while (p0 < p1) {
                View row;
                if (rowIndex >= rowCount) {
                    row = fv.createRow();
                    fv.append(row);
                } else {
                    row = fv.getView(rowIndex);
                }
                p0 = layoutRow(fv, rowIndex, p0);
                rowIndex++;
            }
            viewBuffer = null;

            if (rowIndex < rowCount) {
                fv.replace(rowIndex, rowCount - rowIndex, null);
            }
            unsetDamage();
        }

        /**
         * Creates a row of views that will fit within the
         * layout span of the row.  This is called by the layout method.
         * This is implemented to fill the row by repeatedly calling
         * the createView method until the available span has been
         * exhausted, a forced break was encountered, or the createView
         * method returned null.  If the remaining span was exhaused,
         * the adjustRow method will be called to perform adjustments
         * to the row to try and make it fit into the given span.
         *
         * @param rowIndex the index of the row to fill in with views.  The
         *   row is assumed to be empty on entry.
         * @param pos  The current position in the children of
         *   this views element from which to start.
         * @return the position to start the next row
         */
        protected int layoutRow(FlowView fv, int rowIndex, int pos) {
            View row = fv.getView(rowIndex);
            float x = fv.getFlowStart(rowIndex);
            float spanLeft = fv.getFlowSpan(rowIndex);
            int end = fv.getEndOffset();
            TabExpander te = (fv instanceof TabExpander) ? (TabExpander)fv : null;
            final int flowAxis = fv.getFlowAxis();

            int breakWeight = BadBreakWeight;
            float breakX = 0f;
            float breakSpan = 0f;
            int breakIndex = -1;
            int n = 0;

            viewBuffer.clear();
            while (pos < end && spanLeft >= 0) {
                View v = createView(fv, pos, (int)spanLeft, rowIndex);
                if (v == null) {
                    break;
                }

                int bw = v.getBreakWeight(flowAxis, x, spanLeft);
                if (bw >= ForcedBreakWeight) {
                    View w = v.breakView(flowAxis, pos, x, spanLeft);
                    if (w != null) {
                        viewBuffer.add(w);
                    } else if (n == 0) {
                        // if the view does not break, and it is the only view
                        // in a row, use the whole view
                        viewBuffer.add(v);
                    }
                    break;
                } else if (bw >= breakWeight && bw > BadBreakWeight) {
                    breakWeight = bw;
                    breakX = x;
                    breakSpan = spanLeft;
                    breakIndex = n;
                }

                float chunkSpan;
                if (flowAxis == X_AXIS && v instanceof TabableView) {
                    chunkSpan = ((TabableView)v).getTabbedSpan(x, te);
                } else {
                    chunkSpan = v.getPreferredSpan(flowAxis);
                }

                if (chunkSpan > spanLeft && breakIndex >= 0) {
                    // row is too long, and we may break
                    if (breakIndex < n) {
                        v = viewBuffer.get(breakIndex);
                    }
                    for (int i = n - 1; i >= breakIndex; i--) {
                        viewBuffer.remove(i);
                    }
                    v = v.breakView(flowAxis, v.getStartOffset(), breakX, breakSpan);
                }

                spanLeft -= chunkSpan;
                x += chunkSpan;
                viewBuffer.add(v);
                pos = v.getEndOffset();
                n++;
            }

            View[] views = new View[viewBuffer.size()];
            viewBuffer.toArray(views);
            row.replace(0, row.getViewCount(), views);
            return (views.length > 0 ? row.getEndOffset() : pos);
        }

        /**
         * Adjusts the given row if possible to fit within the
         * layout span.  By default this will try to find the
         * highest break weight possible nearest the end of
         * the row.  If a forced break is encountered, the
         * break will be positioned there.
         *
         * @param rowIndex the row to adjust to the current layout
         *  span.
         * @param desiredSpan the current layout span >= 0
         * @param x the location r starts at.
         */
        protected void adjustRow(FlowView fv, int rowIndex, int desiredSpan, int x) {
            final int flowAxis = fv.getFlowAxis();
            View r = fv.getView(rowIndex);
            int n = r.getViewCount();
            int span = 0;
            int bestWeight = BadBreakWeight;
            int bestSpan = 0;
            int bestIndex = -1;
            View v;
            for (int i = 0; i < n; i++) {
                v = r.getView(i);
                int spanLeft = desiredSpan - span;

                int w = v.getBreakWeight(flowAxis, x + span, spanLeft);
                if ((w >= bestWeight) && (w > BadBreakWeight)) {
                    bestWeight = w;
                    bestIndex = i;
                    bestSpan = span;
                    if (w >= ForcedBreakWeight) {
                        // it's a forced break, so there is
                        // no point in searching further.
                        break;
                    }
                }
                span += v.getPreferredSpan(flowAxis);
            }
            if (bestIndex < 0) {
                // there is nothing that can be broken, leave
                // it in it's current state.
                return;
            }

            // Break the best candidate view, and patch up the row.
            int spanLeft = desiredSpan - bestSpan;
            v = r.getView(bestIndex);
            v = v.breakView(flowAxis, v.getStartOffset(), x + bestSpan, spanLeft);
            View[] va = new View[1];
            va[0] = v;
            View lv = getLogicalView(fv);
            int p0 = r.getView(bestIndex).getStartOffset();
            int p1 = r.getEndOffset();
            for (int i = 0; i < lv.getViewCount(); i++) {
                View tmpView = lv.getView(i);
                if (tmpView.getEndOffset() > p1) {
                    break;
                }
                if (tmpView.getStartOffset() >= p0) {
                    tmpView.setParent(lv);
                }
            }
            r.replace(bestIndex, n - bestIndex, va);
        }

        void reparentViews(View pool, int startPos) {
            int n = pool.getViewIndex(startPos, Position.Bias.Forward);
            if (n >= 0) {
                for (int i = n; i < pool.getViewCount(); i++) {
                    pool.getView(i).setParent(pool);
                }
            }
        }

        /**
         * Creates a view that can be used to represent the current piece
         * of the flow.  This can be either an entire view from the
         * logical view, or a fragment of the logical view.
         *
         * @param fv the view holding the flow
         * @param startOffset the start location for the view being created
         * @param spanLeft the about of span left to fill in the row
         * @param rowIndex the row the view will be placed into
         */
        protected View createView(FlowView fv, int startOffset, int spanLeft, int rowIndex) {
            // Get the child view that contains the given starting position
            View lv = getLogicalView(fv);
            int childIndex = lv.getViewIndex(startOffset, Position.Bias.Forward);
            View v = lv.getView(childIndex);
            if (startOffset==v.getStartOffset()) {
                // return the entire view
                return v;
            }

            // return a fragment.
            v = v.createFragment(startOffset, v.getEndOffset());
            return v;
        }
    }

    /**
     * This class can be used to represent a logical view for
     * a flow.  It keeps the children updated to reflect the state
     * of the model, gives the logical child views access to the
     * view hierarchy, and calculates a preferred span.  It doesn't
     * do any rendering, layout, or model/view translation.
     */
    static class LogicalView extends CompositeView {

        LogicalView(Element elem) {
            super(elem);
        }

        protected int getViewIndexAtPosition(int pos) {
            Element elem = getElement();
            if (elem.isLeaf()) {
                return 0;
            }
            return super.getViewIndexAtPosition(pos);
        }

        protected void loadChildren(ViewFactory f) {
            Element elem = getElement();
            if (elem.isLeaf()) {
                View v = new LabelView(elem);
                append(v);
            } else {
                super.loadChildren(f);
            }
        }

        /**
         * Fetches the attributes to use when rendering.  This view
         * isn't directly responsible for an element so it returns
         * the outer classes attributes.
         */
        public AttributeSet getAttributes() {
            View p = getParent();
            return (p != null) ? p.getAttributes() : null;
        }

        /**
         * 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.
         *           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.
         * @see View#getPreferredSpan
         */
        public float getPreferredSpan(int axis) {
            float maxpref = 0;
            float pref = 0;
            int n = getViewCount();
            for (int i = 0; i < n; i++) {
                View v = getView(i);
                pref += v.getPreferredSpan(axis);
                if (v.getBreakWeight(axis, 0, Integer.MAX_VALUE) >= ForcedBreakWeight) {
                    maxpref = Math.max(maxpref, pref);
                    pref = 0;
                }
            }
            maxpref = Math.max(maxpref, pref);
            return maxpref;
        }

        /**
         * Determines the minimum span for this view along an
         * axis.  The is implemented to find the minimum unbreakable
         * span.
         *
         * @param axis may be either View.X_AXIS or View.Y_AXIS
         * @return  the span the view would like to be rendered into.
         *           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.
         * @see View#getPreferredSpan
         */
        public float getMinimumSpan(int axis) {
            float maxmin = 0;
            float min = 0;
            boolean nowrap = false;
            int n = getViewCount();
            for (int i = 0; i < n; i++) {
                View v = getView(i);
                if (v.getBreakWeight(axis, 0, Integer.MAX_VALUE) == BadBreakWeight) {
                    min += v.getPreferredSpan(axis);
                    nowrap = true;
                } else if (nowrap) {
                    maxmin = Math.max(min, maxmin);
                    nowrap = false;
                    min = 0;
                }
                if (v instanceof ComponentView) {
                    maxmin = Math.max(maxmin, v.getMinimumSpan(axis));
                }
            }
            maxmin = Math.max(maxmin, min);
            return maxmin;
        }

        /**
         * Forward the DocumentEvent to the given child view.  This
         * is implemented to reparent the child to the logical view
         * (the children may have been parented by a row in the flow
         * if they fit without breaking) and then execute the superclass
         * behavior.
         *
         * @param v the child view to forward the event to.
         * @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 #forwardUpdate
         * @since 1.3
         */
        protected void forwardUpdateToView(View v, DocumentEvent e,
                                           Shape a, ViewFactory f) {
            View parent = v.getParent();
            v.setParent(this);
            super.forwardUpdateToView(v, e, a, f);
            v.setParent(parent);
        }

        // The following methods don't do anything useful, they
        // simply keep the class from being abstract.

        /**
         * Renders using the given rendering surface and area on that
         * surface.  This is implemented to do nothing, the logical
         * view is never visible.
         *
         * @param g the rendering surface to use
         * @param allocation the allocated region to render into
         * @see View#paint
         */
        public void paint(Graphics g, Shape allocation) {
        }

        /**
         * Tests whether a point lies before the rectangle range.
         * Implemented to return false, as hit detection is not
         * performed on the logical view.
         *
         * @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 boolean isBefore(int x, int y, Rectangle alloc) {
            return false;
        }

        /**
         * Tests whether a point lies after the rectangle range.
         * Implemented to return false, as hit detection is not
         * performed on the logical view.
         *
         * @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 boolean isAfter(int x, int y, Rectangle alloc) {
            return false;
        }

        /**
         * Fetches the child view at the given point.
         * Implemented to return null, as hit detection is not
         * performed on the logical view.
         *
         * @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 View getViewAtPoint(int x, int y, Rectangle alloc) {
            return null;
        }

        /**
         * Returns the allocation for a given child.
         * Implemented to do nothing, as the logical view doesn't
         * perform layout on the children.
         *
         * @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 void childAllocation(int index, Rectangle a) {
        }
    }


}
