/*
 * Copyright (c) 1999, 2008, 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.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 = width;
        } else {
            newSpan = height;
        }
        if (layoutSpan != newSpan) {
            layoutChanged(faxis);
            layoutChanged(getAxis());
            layoutSpan = newSpan;
        }

        // repair the flow if necessary
        if (! isLayoutValid(faxis)) {
            final int heightAxis = getAxis();
            int oldFlowHeight = (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 {
        Position damageStart = null;
        Vector<View> viewBuffer;

        void addDamage(FlowView fv, int offset) {
            if (offset >= fv.getStartOffset() && offset < fv.getEndOffset()) {
                if (damageStart == null || offset < damageStart.getOffset()) {
                    try {
                        damageStart = fv.getDocument().createPosition(offset);
                    } catch (BadLocationException e) {
                        // shouldn't happen since offset is inside view bounds
                        assert(false);
                    }
                }
            }
        }

        void unsetDamage() {
            damageStart = null;
        }

        /**
         * 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 == null) {
                    return;
                }
                // In some cases there's no view at position damageStart, so
                // step back and search again. See 6452106 for details.
                int offset = damageStart.getOffset();
                while ((rowIndex = fv.getViewIndexAtPosition(offset)) < 0) {
                    offset--;
                }
                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) {
        }
    }


}
