/*
 * Copyright (c) 1998, 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.util.Vector;
import java.awt.*;
import javax.swing.event.*;

/**
 * ZoneView is a View implementation that creates zones for which
 * the child views are not created or stored until they are needed
 * for display or model/view translations.  This enables a substantial
 * reduction in memory consumption for situations where the model
 * being represented is very large, by building view objects only for
 * the region being actively viewed/edited.  The size of the children
 * can be estimated in some way, or calculated asynchronously with
 * only the result being saved.
 * <p>
 * ZoneView extends BoxView to provide a box that implements
 * zones for its children.  The zones are special View implementations
 * (the children of an instance of this class) that represent only a
 * portion of the model that an instance of ZoneView is responsible
 * for.  The zones don't create child views until an attempt is made
 * to display them. A box shaped view is well suited to this because:
 *   <ul>
 *   <li>
 *   Boxes are a heavily used view, and having a box that
 *   provides this behavior gives substantial opportunity
 *   to plug the behavior into a view hierarchy from the
 *   view factory.
 *   <li>
 *   Boxes are tiled in one direction, so it is easy to
 *   divide them into zones in a reliable way.
 *   <li>
 *   Boxes typically have a simple relationship to the model (i.e. they
 *   create child views that directly represent the child elements).
 *   <li>
 *   Boxes are easier to estimate the size of than some other shapes.
 *   </ul>
 * <p>
 * The default behavior is controled by two properties, maxZoneSize
 * and maxZonesLoaded.  Setting maxZoneSize to Integer.MAX_VALUE would
 * have the effect of causing only one zone to be created.  This would
 * effectively turn the view into an implementation of the decorator
 * pattern.  Setting maxZonesLoaded to a value of Integer.MAX_VALUE would
 * cause zones to never be unloaded.  For simplicity, zones are created on
 * boundaries represented by the child elements of the element the view is
 * responsible for.  The zones can be any View implementation, but the
 * default implementation is based upon AsyncBoxView which supports fairly
 * large zones efficiently.
 *
 * @author  Timothy Prinzing
 * @see     View
 * @since   1.3
 */
public class ZoneView extends BoxView {

    int maxZoneSize = 8 * 1024;
    int maxZonesLoaded = 3;
    Vector<View> loadedZones;

    /**
     * Constructs a ZoneView.
     *
     * @param elem the element this view is responsible for
     * @param axis either View.X_AXIS or View.Y_AXIS
     */
    public ZoneView(Element elem, int axis) {
        super(elem, axis);
        loadedZones = new Vector<View>();
    }

    /**
     * Get the current maximum zone size.
     */
    public int getMaximumZoneSize() {
        return maxZoneSize;
    }

    /**
     * Set the desired maximum zone size.  A
     * zone may get larger than this size if
     * a single child view is larger than this
     * size since zones are formed on child view
     * boundaries.
     *
     * @param size the number of characters the zone
     * may represent before attempting to break
     * the zone into a smaller size.
     */
    public void setMaximumZoneSize(int size) {
        maxZoneSize = size;
    }

    /**
     * Get the current setting of the number of zones
     * allowed to be loaded at the same time.
     */
    public int getMaxZonesLoaded() {
        return maxZonesLoaded;
    }

    /**
     * Sets the current setting of the number of zones
     * allowed to be loaded at the same time. This will throw an
     * <code>IllegalArgumentException</code> if <code>mzl</code> is less
     * than 1.
     *
     * @param mzl the desired maximum number of zones
     *  to be actively loaded, must be greater than 0
     * @exception IllegalArgumentException if <code>mzl</code> is < 1
     */
    public void setMaxZonesLoaded(int mzl) {
        if (mzl < 1) {
            throw new IllegalArgumentException("ZoneView.setMaxZonesLoaded must be greater than 0.");
        }
        maxZonesLoaded = mzl;
        unloadOldZones();
    }

    /**
     * Called by a zone when it gets loaded.  This happens when
     * an attempt is made to display or perform a model/view
     * translation on a zone that was in an unloaded state.
     * This is imlemented to check if the maximum number of
     * zones was reached and to unload the oldest zone if so.
     *
     * @param zone the child view that was just loaded.
     */
    protected void zoneWasLoaded(View zone) {
        //System.out.println("loading: " + zone.getStartOffset() + "," + zone.getEndOffset());
        loadedZones.addElement(zone);
        unloadOldZones();
    }

    void unloadOldZones() {
        while (loadedZones.size() > getMaxZonesLoaded()) {
            View zone = loadedZones.elementAt(0);
            loadedZones.removeElementAt(0);
            unloadZone(zone);
        }
    }

    /**
     * Unload a zone (Convert the zone to its memory saving state).
     * The zones are expected to represent a subset of the
     * child elements of the element this view is responsible for.
     * Therefore, the default implementation is to simple remove
     * all the children.
     *
     * @param zone the child view desired to be set to an
     *  unloaded state.
     */
    protected void unloadZone(View zone) {
        //System.out.println("unloading: " + zone.getStartOffset() + "," + zone.getEndOffset());
        zone.removeAll();
    }

    /**
     * Determine if a zone is in the loaded state.
     * The zones are expected to represent a subset of the
     * child elements of the element this view is responsible for.
     * Therefore, the default implementation is to return
     * true if the view has children.
     */
    protected boolean isZoneLoaded(View zone) {
        return (zone.getViewCount() > 0);
    }

    /**
     * Create a view to represent a zone for the given
     * range within the model (which should be within
     * the range of this objects responsibility).  This
     * is called by the zone management logic to create
     * new zones.  Subclasses can provide a different
     * implementation for a zone by changing this method.
     *
     * @param p0 the start of the desired zone.  This should
     *  be >= getStartOffset() and < getEndOffset().  This
     *  value should also be < p1.
     * @param p1 the end of the desired zone.  This should
     *  be > getStartOffset() and <= getEndOffset().  This
     *  value should also be > p0.
     */
    protected View createZone(int p0, int p1) {
        Document doc = getDocument();
        View zone;
        try {
            zone = new Zone(getElement(),
                            doc.createPosition(p0),
                            doc.createPosition(p1));
        } catch (BadLocationException ble) {
            // this should puke in some way.
            throw new StateInvariantError(ble.getMessage());
        }
        return zone;
    }

    /**
     * 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 by the zones).  This method creates
     * the initial set of zones.  Zones don't actually get
     * populated however until an attempt is made to display
     * them or to do model/view coordinate translation.
     *
     * @param f the view factory
     */
    protected void loadChildren(ViewFactory f) {
        // build the first zone.
        Document doc = getDocument();
        int offs0 = getStartOffset();
        int offs1 = getEndOffset();
        append(createZone(offs0, offs1));
        handleInsert(offs0, offs1 - offs0);
    }

    /**
     * Returns 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) {
        // PENDING(prinz) this could be done as a binary
        // search, and probably should be.
        int n = getViewCount();
        if (pos == getEndOffset()) {
            return n - 1;
        }
        for(int i = 0; i < n; i++) {
            View v = getView(i);
            if(pos >= v.getStartOffset() &&
               pos < v.getEndOffset()) {
                return i;
            }
        }
        return -1;
    }

    void handleInsert(int pos, int length) {
        int index = getViewIndex(pos, Position.Bias.Forward);
        View v = getView(index);
        int offs0 = v.getStartOffset();
        int offs1 = v.getEndOffset();
        if ((offs1 - offs0) > maxZoneSize) {
            splitZone(index, offs0, offs1);
        }
    }

    void handleRemove(int pos, int length) {
        // IMPLEMENT
    }

    /**
     * Break up the zone at the given index into pieces
     * of an acceptable size.
     */
    void splitZone(int index, int offs0, int offs1) {
        // divide the old zone into a new set of bins
        Element elem = getElement();
        Document doc = elem.getDocument();
        Vector<View> zones = new Vector<View>();
        int offs = offs0;
        do {
            offs0 = offs;
            offs = Math.min(getDesiredZoneEnd(offs0), offs1);
            zones.addElement(createZone(offs0, offs));
        } while (offs < offs1);
        View oldZone = getView(index);
        View[] newZones = new View[zones.size()];
        zones.copyInto(newZones);
        replace(index, 1, newZones);
    }

    /**
     * Returns the zone position to use for the
     * end of a zone that starts at the given
     * position.  By default this returns something
     * close to half the max zone size.
     */
    int getDesiredZoneEnd(int pos) {
        Element elem = getElement();
        int index = elem.getElementIndex(pos + (maxZoneSize / 2));
        Element child = elem.getElement(index);
        int offs0 = child.getStartOffset();
        int offs1 = child.getEndOffset();
        if ((offs1 - pos) > maxZoneSize) {
            if (offs0 > pos) {
                return offs0;
            }
        }
        return offs1;
    }

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

    /**
     * The superclass behavior will try to update the child views
     * which is not desired in this case, since the children are
     * zones and not directly effected by the changes to the
     * associated element.  This is reimplemented to do nothing
     * and return false.
     */
    protected boolean updateChildren(DocumentEvent.ElementChange ec,
                                     DocumentEvent e, ViewFactory f) {
        return false;
    }

    /**
     * Gives notification that something was inserted into the document
     * in a location that this view is responsible for.  This is largely
     * delegated to the superclass, but is reimplemented to update the
     * relevant zone (i.e. determine if a zone needs to be split into a
     * set of 2 or more zones).
     *
     * @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) {
        handleInsert(changes.getOffset(), changes.getLength());
        super.insertUpdate(changes, a, f);
    }

    /**
     * Gives notification that something was removed from the document
     * in a location that this view is responsible for.  This is largely
     * delegated to the superclass, but is reimplemented to update the
     * relevant zones (i.e. determine if zones need to be removed or
     * joined with another zone).
     *
     * @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) {
        handleRemove(changes.getOffset(), changes.getLength());
        super.removeUpdate(changes, a, f);
    }

    /**
     * Internally created view that has the purpose of holding
     * the views that represent the children of the ZoneView
     * that have been arranged in a zone.
     */
    class Zone extends AsyncBoxView {

        private Position start;
        private Position end;

        public Zone(Element elem, Position start, Position end) {
            super(elem, ZoneView.this.getAxis());
            this.start = start;
            this.end = end;
        }

        /**
         * Creates the child views and populates the
         * zone with them.  This is done by translating
         * the positions to child element index locations
         * and building views to those elements.  If the
         * zone is already loaded, this does nothing.
         */
        public void load() {
            if (! isLoaded()) {
                setEstimatedMajorSpan(true);
                Element e = getElement();
                ViewFactory f = getViewFactory();
                int index0 = e.getElementIndex(getStartOffset());
                int index1 = e.getElementIndex(getEndOffset());
                View[] added = new View[index1 - index0 + 1];
                for (int i = index0; i <= index1; i++) {
                    added[i - index0] = f.create(e.getElement(i));
                }
                replace(0, 0, added);

                zoneWasLoaded(this);
            }
        }

        /**
         * Removes the child views and returns to a
         * state of unloaded.
         */
        public void unload() {
            setEstimatedMajorSpan(true);
            removeAll();
        }

        /**
         * Determines if the zone is in the loaded state
         * or not.
         */
        public boolean isLoaded() {
            return (getViewCount() != 0);
        }

        /**
         * This method is reimplemented to not build the children
         * since the children are created when the zone is loaded
         * rather then when it is placed in the view hierarchy.
         * The major span is estimated at this point by building
         * the first child (but not storing it), and calling
         * setEstimatedMajorSpan(true) followed by setSpan for
         * the major axis with the estimated span.
         */
        protected void loadChildren(ViewFactory f) {
            // mark the major span as estimated
            setEstimatedMajorSpan(true);

            // estimate the span
            Element elem = getElement();
            int index0 = elem.getElementIndex(getStartOffset());
            int index1 = elem.getElementIndex(getEndOffset());
            int nChildren = index1 - index0;

            // replace this with something real
            //setSpan(getMajorAxis(), nChildren * 10);

            View first = f.create(elem.getElement(index0));
            first.setParent(this);
            float w = first.getPreferredSpan(X_AXIS);
            float h = first.getPreferredSpan(Y_AXIS);
            if (getMajorAxis() == X_AXIS) {
                w *= nChildren;
            } else {
                h += nChildren;
            }

            setSize(w, h);
        }

        /**
         * Publish the changes in preferences upward to the parent
         * view.
         * <p>
         * This is reimplemented to stop the superclass behavior
         * if the zone has not yet been loaded.  If the zone is
         * unloaded for example, the last seen major span is the
         * best estimate and a calculated span for no children
         * is undesirable.
         */
        protected void flushRequirementChanges() {
            if (isLoaded()) {
                super.flushRequirementChanges();
            }
        }

        /**
         * Returns the child view index representing the given position in
         * the model.  Since the zone contains a cluster of the overall
         * set of child elements, we can determine the index fairly
         * quickly from the model by subtracting the index of the
         * start offset from the index of the position given.
         *
         * @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) {
            boolean isBackward = (b == Position.Bias.Backward);
            pos = (isBackward) ? Math.max(0, pos - 1) : pos;
            Element elem = getElement();
            int index1 = elem.getElementIndex(pos);
            int index0 = elem.getElementIndex(getStartOffset());
            return index1 - index0;
        }

        protected boolean updateChildren(DocumentEvent.ElementChange ec,
                                         DocumentEvent e, ViewFactory f) {
            // the structure of this element changed.
            Element[] removedElems = ec.getChildrenRemoved();
            Element[] addedElems = ec.getChildrenAdded();
            Element elem = getElement();
            int index0 = elem.getElementIndex(getStartOffset());
            int index1 = elem.getElementIndex(getEndOffset()-1);
            int index = ec.getIndex();
            if ((index >= index0) && (index <= index1)) {
                // The change is in this zone
                int replaceIndex = index - index0;
                int nadd = Math.min(index1 - index0 + 1, addedElems.length);
                int nremove = Math.min(index1 - index0 + 1, removedElems.length);
                View[] added = new View[nadd];
                for (int i = 0; i < nadd; i++) {
                    added[i] = f.create(addedElems[i]);
                }
                replace(replaceIndex, nremove, added);
            }
            return true;
        }

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

        /**
         * 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() {
            return ZoneView.this.getAttributes();
        }

        /**
         * Renders using the given rendering surface and area on that
         * surface.  This is implemented to load the zone if its not
         * already loaded, and then perform the superclass behavior.
         *
         * @param g the rendering surface to use
         * @param a the allocated region to render into
         * @see View#paint
         */
        public void paint(Graphics g, Shape a) {
            load();
            super.paint(g, a);
        }

        /**
         * Provides a mapping from the view coordinate space to the logical
         * coordinate space of the model.  This is implemented to first
         * make sure the zone is loaded before providing the superclass
         * behavior.
         *
         * @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
         * @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) {
            load();
            return super.viewToModel(x, y, a, bias);
        }

        /**
         * Provides a mapping from the document model coordinate space
         * to the coordinate space of the view mapped to it.  This is
         * implemented to provide the superclass behavior after first
         * making sure the zone is loaded (The zone must be loaded to
         * make this calculation).
         *
         * @param pos the position to convert
         * @param a the allocated region to render into
         * @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 {
            load();
            return super.modelToView(pos, a, b);
        }

        /**
         * Start of the zones range.
         *
         * @see View#getStartOffset
         */
        public int getStartOffset() {
            return start.getOffset();
        }

        /**
         * End of the zones range.
         */
        public int getEndOffset() {
            return end.getOffset();
        }

        /**
         * Gives notification that something was inserted into
         * the document in a location that this view is responsible for.
         * If the zone has been loaded, the superclass behavior is
         * invoked, otherwise this does nothing.
         *
         * @param e the change information from the associated document
         * @param a the current allocation of the view
         * @param f the factory to use to rebuild if the view has children
         * @see View#insertUpdate
         */
        public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) {
            if (isLoaded()) {
                super.insertUpdate(e, a, f);
            }
        }

        /**
         * Gives notification that something was removed from the document
         * in a location that this view is responsible for.
         * If the zone has been loaded, the superclass behavior is
         * invoked, otherwise this does nothing.
         *
         * @param e the change information from the associated document
         * @param a the current allocation of the view
         * @param f the factory to use to rebuild if the view has children
         * @see View#removeUpdate
         */
        public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) {
            if (isLoaded()) {
                super.removeUpdate(e, a, f);
            }
        }

        /**
         * Gives notification from the document that attributes were changed
         * in a location that this view is responsible for.
         * If the zone has been loaded, the superclass behavior is
         * invoked, otherwise this does nothing.
         *
         * @param e the change information from the associated document
         * @param a the current allocation of the view
         * @param f the factory to use to rebuild if the view has children
         * @see View#removeUpdate
         */
        public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
            if (isLoaded()) {
                super.changedUpdate(e, a, f);
            }
        }

    }
}
