/* AsyncBoxView.java -- A box view that performs layout asynchronously
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;

import javax.swing.event.DocumentEvent;
import javax.swing.text.Position.Bias;

/**
 * A {@link View} implementation that lays out its child views in a box, either
 * vertically or horizontally. The difference to {@link BoxView} is that the
 * layout is performed in an asynchronous manner. This helps to keep the
 * eventqueue free from non-GUI related tasks.
 *
 * This view is currently not used in standard text components. In order to
 * use it you would have to implement a special {@link EditorKit} with a
 * {@link ViewFactory} that returns this view. For example:
 *
 * <pre>
 * static class AsyncEditorKit extends StyledEditorKit implements ViewFactory
 * {
 *   public View create(Element el)
 *   {
 *     if (el.getName().equals(AbstractDocument.SectionElementName))
 *       return new AsyncBoxView(el, View.Y_AXIS);
 *     return super.getViewFactory().create(el);
 *   }
 *   public ViewFactory getViewFactory() {
 *     return this;
 *   }
 * }
 * </pre>
 *
 * @author Roman Kennke (kennke@aicas.com)
 *
 * @since 1.3
 */
public class AsyncBoxView
  extends View
{

  /**
   * Manages the effective position of child views. That keeps the visible
   * layout stable while the AsyncBoxView might be changing until the layout
   * thread decides to publish the new layout.
   */
  public class ChildLocator
  {

    /**
     * The last valid location.
     */
    protected ChildState lastValidOffset;

    /**
     * The last allocation.
     */
    protected Rectangle lastAlloc;

    /**
     * A Rectangle used for child allocation calculation to avoid creation
     * of lots of garbage Rectangle objects.
     */
    protected Rectangle childAlloc;

    /**
     * Creates a new ChildLocator.
     */
    public ChildLocator()
    {
      lastAlloc = new Rectangle();
      childAlloc = new Rectangle();
    }

    /**
     * Receives notification that a child has changed. This is called by
     * child state objects that have changed it's major span.
     *
     * This sets the {@link #lastValidOffset} field to <code>cs</code> if
     * the new child state's view start offset is smaller than the start offset
     * of the current child state's view or when <code>lastValidOffset</code>
     * is <code>null</code>.
     *
     * @param cs the child state object that has changed
     */
    public synchronized void childChanged(ChildState cs)
    {
      if (lastValidOffset == null
          || cs.getChildView().getStartOffset()
             < lastValidOffset.getChildView().getStartOffset())
        {
          lastValidOffset = cs;
        }
    }

    /**
     * Returns the view index of the view that occupies the specified area, or
     * <code>-1</code> if there is no such child view.
     *
     * @param x the x coordinate (relative to <code>a</code>)
     * @param y the y coordinate (relative to <code>a</code>)
     * @param a the current allocation of this view
     *
     * @return the view index of the view that occupies the specified area, or
     *         <code>-1</code> if there is no such child view
     */
    public int getViewIndexAtPoint(float x, float y, Shape a)
    {
      setAllocation(a);
      float targetOffset = (getMajorAxis() == X_AXIS) ? x - lastAlloc.x
                                                      : y - lastAlloc.y;
      int index = getViewIndexAtVisualOffset(targetOffset);
      return index;
    }

    /**
     * Returns the current allocation for a child view. This updates the
     * offsets for all children <em>before</em> the requested child view.
     *
     * @param index the index of the child view
     * @param a the current allocation of this view
     * 
     * @return the current allocation for a child view
     */
    public synchronized Shape getChildAllocation(int index, Shape a)
    {
      if (a == null)
        return null;
      setAllocation(a);
      ChildState cs = getChildState(index);
      if (cs.getChildView().getStartOffset()
          > lastValidOffset.getChildView().getStartOffset())
        {
          updateChildOffsetsToIndex(index);
        }
      Shape ca = getChildAllocation(index);
      return ca;
    }

    /**
     * Paints all child views.
     *
     * @param g the graphics context to use
     */
    public synchronized void paintChildren(Graphics g)
    {
      Rectangle clip = g.getClipBounds();
      float targetOffset = (getMajorAxis() == X_AXIS) ? clip.x - lastAlloc.x
                                                      : clip.y - lastAlloc.y;
      int index = getViewIndexAtVisualOffset(targetOffset);
      int n = getViewCount();
      float offs = getChildState(index).getMajorOffset();
      for (int i = index; i < n; i++)
        {
          ChildState cs = getChildState(i);
          cs.setMajorOffset(offs);
          Shape ca = getChildAllocation(i);
          if (ca.intersects(clip))
            {
              synchronized (cs)
                {
                  View v = cs.getChildView();
                  v.paint(g, ca);
                }
            }
          else
            {
              // done painting intersection
              break;
            }
          offs += cs.getMajorSpan();
        }
    }

    /**
     * Returns the current allocation of the child view with the specified
     * index. Note that this will <em>not</em> update any location information.
     * 
     * @param index the index of the requested child view
     *
     * @return the current allocation of the child view with the specified
     *         index
     */
    protected Shape getChildAllocation(int index)
    {
      ChildState cs = getChildState(index);
      if (! cs.isLayoutValid())
          cs.run();

      if (getMajorAxis() == X_AXIS)
        {
          childAlloc.x = lastAlloc.x + (int) cs.getMajorOffset();
          childAlloc.y = lastAlloc.y + (int) cs.getMinorOffset();
          childAlloc.width = (int) cs.getMajorSpan();
          childAlloc.height = (int) cs.getMinorSpan();
        }
      else
        {
          childAlloc.y = lastAlloc.y + (int) cs.getMajorOffset();
          childAlloc.x = lastAlloc.x + (int) cs.getMinorOffset();
          childAlloc.height = (int) cs.getMajorSpan();
          childAlloc.width = (int) cs.getMinorSpan();
        }
      return childAlloc;
    }

    /**
     * Sets the current allocation for this view.
     *
     * @param a the allocation to set
     */
    protected void setAllocation(Shape a)
    {
      if (a instanceof Rectangle)
        lastAlloc.setBounds((Rectangle) a);
      else
        lastAlloc.setBounds(a.getBounds());

      setSize(lastAlloc.width, lastAlloc.height);
    }

    /**
     * Returns the index of the view at the specified offset along the major
     * layout axis.
     *
     * @param targetOffset the requested offset
     *
     * @return the index of the view at the specified offset along the major
     * layout axis
     */
    protected int getViewIndexAtVisualOffset(float targetOffset)
    {
      int n = getViewCount();
      if (n > 0)
        {
          if (lastValidOffset == null)
            lastValidOffset = getChildState(0);
          if (targetOffset > majorSpan)
            return 0;
          else if (targetOffset > lastValidOffset.getMajorOffset())
            return updateChildOffsets(targetOffset);
          else
            {
              float offs = 0f;
              for (int i = 0; i < n; i++)
                {
                  ChildState cs = getChildState(i);
                  float nextOffs = offs + cs.getMajorSpan();
                  if (targetOffset < nextOffs)
                    return i;
                  offs = nextOffs;
                }
            }
        }
      return n - 1;
    }

    /**
     * Updates all the child view offsets up to the specified targetOffset.
     *
     * @param targetOffset the offset up to which the child view offsets are
     *        updated
     *
     * @return the index of the view at the specified offset
     */
    private int updateChildOffsets(float targetOffset)
    {
      int n = getViewCount();
      int targetIndex = n - 1;;
      int pos = lastValidOffset.getChildView().getStartOffset();
      int startIndex = getViewIndexAtPosition(pos, Position.Bias.Forward);
      float start = lastValidOffset.getMajorOffset();
      float lastOffset = start;
      for (int i = startIndex; i < n; i++)
        {
          ChildState cs = getChildState(i);
          cs.setMajorOffset(lastOffset);
          lastOffset += cs.getMajorSpan();
          if (targetOffset < lastOffset)
            {
              targetIndex = i;
              lastValidOffset = cs;
              break;
            }
        }
      return targetIndex;
    }

    /**
     * Updates the offsets of the child views up to the specified index.
     *
     * @param index the index up to which the offsets are updated
     */
    private void updateChildOffsetsToIndex(int index)
    {
      int pos = lastValidOffset.getChildView().getStartOffset();
      int startIndex = getViewIndexAtPosition(pos, Position.Bias.Forward);
      float lastOffset = lastValidOffset.getMajorOffset();
      for (int i = startIndex; i <= index; i++)
        {
          ChildState cs = getChildState(i);
          cs.setMajorOffset(lastOffset);
          lastOffset += cs.getMajorSpan();
        }
    }
  }

  /**
   * Represents the layout state of a child view.
   */
  public class ChildState
    implements Runnable
  {

    /**
     * The child view for this state record.
     */
    private View childView;

    /**
     * Indicates if the minor axis requirements of this child view are valid
     * or not.
     */
    private boolean minorValid;

    /**
     * Indicates if the major axis requirements of this child view are valid
     * or not.
     */
    private boolean majorValid;

    /**
     * Indicates if the current child size is valid. This is package private
     * to avoid synthetic accessor method.
     */
    boolean childSizeValid;

    /**
     * The child views minimumSpan. This is package private to avoid accessor
     * method.
     */
    float minimum;

    /**
     * The child views preferredSpan. This is package private to avoid accessor
     * method.
     */
    float preferred;

    /**
     * The current span of the child view along the major axis.
     */
    private float majorSpan;

    /**
     * The current offset of the child view along the major axis.
     */
    private float majorOffset;

    /**
     * The current span of the child view along the minor axis.
     */
    private float minorSpan;

    /**
     * The current offset of the child view along the major axis.
     */
    private float minorOffset;

    /**
     * The child views maximumSpan.
     */
    private float maximum;

    /**
     * Creates a new <code>ChildState</code> object for the specified child
     * view.
     *
     * @param view the child view for which to create the state record
     */
    public ChildState(View view)
    {
      childView = view;
    }

    /**
     * Returns the child view for which this <code>ChildState</code> represents
     * the layout state.
     *
     * @return the child view for this child state object 
     */
    public View getChildView()
    {
      return childView;
    }

    /**
     * Returns <code>true</code> if the current layout information is valid,
     * <code>false</code> otherwise.
     *
     * @return <code>true</code> if the current layout information is valid,
     *         <code>false</code> otherwise
     */
    public boolean isLayoutValid()
    {
      return minorValid && majorValid && childSizeValid;
    }

    /**
     * Performs the layout update for the child view managed by this
     * <code>ChildState</code>.
     */
    public void run()
    {
      Document doc = getDocument();
      if (doc instanceof AbstractDocument)
        {
          AbstractDocument abstractDoc = (AbstractDocument) doc;
          abstractDoc.readLock();
        }

      try
        {

          if (!(minorValid &&  majorValid && childSizeValid)
              && childView.getParent() == AsyncBoxView.this)
            {
              synchronized(AsyncBoxView.this)
              {
                changing = this;
              }
              update();
              synchronized(AsyncBoxView.this)
              {
                changing = null;
              }
              // Changing the major axis may cause the minor axis
              // requirements to have changed, so we need to do this again.
              update();
            }
        }
      finally
        {
          if (doc instanceof AbstractDocument)
            {
              AbstractDocument abstractDoc = (AbstractDocument) doc;
              abstractDoc.readUnlock();
            }
        }
    }

    /**
     * Performs the actual update after the run methods has made its checks
     * and locked the document.
     */
    private void update()
    {
      int majorAxis = getMajorAxis();
      boolean minorUpdated = false;
      synchronized (this)
        {
          if (! minorValid)
            {
              int minorAxis = getMinorAxis();
              minimum = childView.getMinimumSpan(minorAxis);
              preferred = childView.getPreferredSpan(minorAxis);
              maximum = childView.getMaximumSpan(minorAxis);
              minorValid = true;
              minorUpdated = true;
            }
        }
      if (minorUpdated)
        minorRequirementChange(this);

      boolean majorUpdated = false;
      float delta = 0.0F;
      synchronized (this)
        {
          if (! majorValid)
            {
              float oldSpan = majorSpan;
              majorSpan = childView.getPreferredSpan(majorAxis);
              delta = majorSpan - oldSpan;
              majorValid = true;
              majorUpdated = true;
            }
        }
      if (majorUpdated)
        {
          majorRequirementChange(this, delta);
          locator.childChanged(this);
        }

      synchronized (this)
        {
          if (! childSizeValid)
            {
              float w;
              float h;
              if (majorAxis == X_AXIS)
                {
                  w = majorSpan;
                  h = getMinorSpan();
                }
              else
                {
                  w = getMinorSpan();
                  h = majorSpan;
                }
              childSizeValid = true;
              childView.setSize(w, h);
            }
        }
    }

    /**
     * Returns the span of the child view along the minor layout axis.
     *
     * @return the span of the child view along the minor layout axis
     */
    public float getMinorSpan()
    {
      float retVal;
      if (maximum < minorSpan)
        retVal = maximum;
      else
        retVal = Math.max(minimum, minorSpan);
      return retVal;
    }

    /**
     * Returns the offset of the child view along the minor layout axis.
     *
     * @return the offset of the child view along the minor layout axis
     */
    public float getMinorOffset()
    {
      float retVal;
      if (maximum < minorSpan)
        {
          float align = childView.getAlignment(getMinorAxis());
          retVal = ((minorSpan - maximum) * align);
        }
      else
        retVal = 0f;

      return retVal;
    }

    /**
     * Returns the span of the child view along the major layout axis.
     *
     * @return the span of the child view along the major layout axis
     */

    public float getMajorSpan()
    {
      return majorSpan;
    }

    /**
     * Returns the offset of the child view along the major layout axis.
     *
     * @return the offset of the child view along the major layout axis
     */
    public float getMajorOffset()
    {
      return majorOffset;
    }

    /**
     * Sets the offset of the child view along the major layout axis. This
     * should only be called by the ChildLocator of that child view.
     *
     * @param offset the offset to set
     */
    public void setMajorOffset(float offset)
    {
      majorOffset = offset;
    }

    /**
     * Mark the preferences changed for that child. This forwards to
     * {@link AsyncBoxView#preferenceChanged}.
     *
     * @param width <code>true</code> if the width preference has changed
     * @param height <code>true</code> if the height preference has changed
     */
    public void preferenceChanged(boolean width, boolean height)
    {
      if (getMajorAxis() == X_AXIS)
        {
          if (width)
            majorValid = false;
          if (height)
            minorValid = false;
        }
      else
        {
          if (width)
            minorValid = false;
          if (height)
            majorValid = false;
        }
      childSizeValid = false;
    }
  }

  /**
   * Flushes the requirements changes upwards asynchronously.
   */
  private class FlushTask implements Runnable
  {
    /**
     * Starts the flush task. This obtains a readLock on the document
     * and then flushes all the updates using
     * {@link AsyncBoxView#flushRequirementChanges()} after updating the
     * requirements.
     */
    public void run()
    {
      try
        {
          // Acquire a lock on the document.
          Document doc = getDocument();
          if (doc instanceof AbstractDocument)
            {
              AbstractDocument abstractDoc = (AbstractDocument) doc;
              abstractDoc.readLock();
            }

          int n = getViewCount();
          if (minorChanged && (n > 0))
            {
              LayoutQueue q = getLayoutQueue();
              ChildState min = getChildState(0);
              ChildState pref = getChildState(0);
              for (int i = 1; i < n; i++)
                {
                  ChildState cs = getChildState(i);
                  if (cs.minimum > min.minimum)
                    min = cs;
                  if (cs.preferred > pref.preferred)
                    pref = cs;
                }
              synchronized (AsyncBoxView.this)
              {
                minReq = min;
                prefReq = pref;
              }
            }

          flushRequirementChanges();
        }
      finally
      {
        // Release the lock on the document.
        Document doc = getDocument();
        if (doc instanceof AbstractDocument)
          {
            AbstractDocument abstractDoc = (AbstractDocument) doc;
            abstractDoc.readUnlock();
          }
      }
    }

  }

  /**
   * The major layout axis.
   */
  private int majorAxis;

  /**
   * The top inset.
   */
  private float topInset;

  /**
   * The bottom inset.
   */
  private float bottomInset;

  /**
   * The left inset.
   */
  private float leftInset;

  /**
   * Indicates if the major span should be treated as beeing estimated or not.
   */
  private boolean estimatedMajorSpan;

  /**
   * The right inset.
   */
  private float rightInset;

  /**
   * The children and their layout statistics.
   */
  private ArrayList childStates;

  /**
   * The currently changing child state. May be null if there is no child state
   * updating at the moment. This is package private to avoid a synthetic
   * accessor method inside ChildState.
   */
  ChildState changing;

  /**
   * Represents the minimum requirements. This is used in
   * {@link #getMinimumSpan(int)}.
   */
  ChildState minReq;

  /**
   * Represents the minimum requirements. This is used in
   * {@link #getPreferredSpan(int)}.
   */
  ChildState prefReq;

  /**
   * Indicates that the major axis requirements have changed.
   */
  private boolean majorChanged;

  /**
   * Indicates that the minor axis requirements have changed. This is package
   * private to avoid synthetic accessor method.
   */
  boolean minorChanged;

  /**
   * The current span along the major layout axis. This is package private to
   * avoid synthetic accessor method.
   */
  float majorSpan;

  /**
   * The current span along the minor layout axis. This is package private to
   * avoid synthetic accessor method.
   */
  float minorSpan;

  /**
   * This tasked is placed on the layout queue to flush updates up to the
   * parent view.
   */
  private Runnable flushTask;

  /**
   * The child locator for this view.
   */
  protected ChildLocator locator;

  /**
   * Creates a new <code>AsyncBoxView</code> that represents the specified
   * element and layouts its children along the specified axis.
   *
   * @param elem the element
   * @param axis the layout axis
   */
  public AsyncBoxView(Element elem, int axis)
  {
    super(elem);
    majorAxis = axis;
    childStates = new ArrayList();
    flushTask = new FlushTask();
    locator = new ChildLocator();
    minorSpan = Short.MAX_VALUE;
  }

  /**
   * Returns the major layout axis.
   *
   * @return the major layout axis
   */
  public int getMajorAxis()
  {
    return majorAxis;
  }

  /**
   * Returns the minor layout axis, that is the axis orthogonal to the major
   * layout axis.
   *
   * @return the minor layout axis
   */
  public int getMinorAxis()
  {
    return majorAxis == X_AXIS ? Y_AXIS : X_AXIS;
  }

  /**
   * Returns the view at the specified <code>index</code>.
   *
   * @param index the index of the requested child view
   *
   * @return the view at the specified <code>index</code>
   */
  public View getView(int index)
  {
    View view = null;
    synchronized(childStates)
      {
        if ((index >= 0) && (index < childStates.size()))
          {
            ChildState cs = (ChildState) childStates.get(index);
            view = cs.getChildView();
          }
      }
    return view;
  }

  /**
   * Returns the number of child views.
   *
   * @return the number of child views
   */
  public int getViewCount()
  {
    synchronized(childStates)
    {
      return childStates.size();
    }
  }

  /**
   * Returns the view index of the child view that represents the specified
   * model position.
   *
   * @param pos the model position for which we search the view index
   * @param bias the bias
   *
   * @return the view index of the child view that represents the specified
   *         model position
   */
  public int getViewIndex(int pos, Position.Bias bias)
  {
    int retVal = -1;

    if (bias == Position.Bias.Backward)
      pos = Math.max(0, pos - 1);

    // TODO: A possible optimization would be to implement a binary search
    // here.
    int numChildren = childStates.size();
    if (numChildren > 0)
      {
        for (int i = 0; i < numChildren; ++i)
          {
            View child = ((ChildState) childStates.get(i)).getChildView();
            if (child.getStartOffset() <= pos && child.getEndOffset() > pos)
              {
                retVal = i;
                break;
              }
          }
      }
    return retVal;
  }

  /**
   * Returns the top inset.
   *
   * @return the top inset
   */
  public float getTopInset()
  {
    return topInset;
  }

  /**
   * Sets the top inset.
   *
   * @param top the top inset
   */
  public void setTopInset(float top)
  {
    topInset = top;
  }

  /**
   * Returns the bottom inset.
   *
   * @return the bottom inset
   */
  public float getBottomInset()
  {
    return bottomInset;
  }

  /**
   * Sets the bottom inset.
   *
   * @param bottom the bottom inset
   */
  public void setBottomInset(float bottom)
  {
    bottomInset = bottom;
  }

  /**
   * Returns the left inset.
   *
   * @return the left inset
   */
  public float getLeftInset()
  {
    return leftInset;
  }

  /**
   * Sets the left inset.
   *
   * @param left the left inset
   */
  public void setLeftInset(float left)
  {
    leftInset = left;
  }

  /**
   * Returns the right inset.
   *
   * @return the right inset
   */
  public float getRightInset()
  {
    return rightInset;
  }

  /**
   * Sets the right inset.
   *
   * @param right the right inset
   */
  public void setRightInset(float right)
  {
    rightInset = right;
  }

  /**
   * Loads the child views of this view. This is triggered by
   * {@link #setParent(View)}.
   *
   * @param f the view factory to build child views with
   */
  protected void loadChildren(ViewFactory f)
  {
    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);
      }
  }
  
  /**
   * Returns the span along an axis that is taken up by the insets.
   *
   * @param axis the axis
   *
   * @return the span along an axis that is taken up by the insets
   *
   * @since 1.4
   */
  protected float getInsetSpan(int axis)
  {
    float span;
    if (axis == X_AXIS)
      span = leftInset + rightInset;
    else
      span = topInset + bottomInset;
    return span;
  }

  /**
   * Sets the <code>estimatedMajorSpan</code> property that determines if
   * the major span should be treated as beeing estimated.
   *
   * @param estimated if the major span should be treated as estimated or not
   *
   * @since 1.4
   */
  protected void setEstimatedMajorSpan(boolean estimated)
  {
    estimatedMajorSpan = estimated;
  }

  /**
   * Determines whether the major span should be treated as estimated or as
   * beeing accurate.
   *
   * @return <code>true</code> if the major span should be treated as
   *         estimated, <code>false</code> if the major span should be treated
   *         as accurate
   *
   * @since 1.4
   */
  protected boolean getEstimatedMajorSpan()
  {
    return estimatedMajorSpan;
  }

  /**
   * Receives notification from the child states that the requirements along
   * the minor axis have changed.
   *
   * @param cs the child state from which this notification is messaged
   */
  protected synchronized void minorRequirementChange(ChildState cs)
  {
    minorChanged = true;
  }

  /**
   * Receives notification from the child states that the requirements along
   * the major axis have changed.
   *
   * @param cs the child state from which this notification is messaged
   */
  protected void majorRequirementChange(ChildState cs, float delta)
  {
    if (! estimatedMajorSpan)
      majorSpan += delta;
    majorChanged = true;
  }

  /**
   * Sets the parent for this view. This calls loadChildren if
   * <code>parent</code> is not <code>null</code> and there have not been any
   * child views initializes.
   *
   * @param parent the new parent view; <code>null</code> if this view is
   *        removed from the view hierarchy
   *
   * @see View#setParent(View)
   */
  public void setParent(View parent)
  {
    super.setParent(parent);
    if ((parent != null) && (getViewCount() == 0))
      {
        ViewFactory f = getViewFactory();
        loadChildren(f);
      }
  }

  /**
   * Sets the size of this view. This is ususally called before {@link #paint}
   * is called to make sure the view has a valid layout.
   *
   * This implementation queues layout requests for every child view if the
   * minor axis span has changed. (The major axis span is requested to never
   * change for this view).
   *
   * @param width the width of the view
   * @param height the height of the view
   */
  public void setSize(float width, float height)
  {
    float targetSpan;
    if (majorAxis == X_AXIS)
      targetSpan = height - getTopInset() - getBottomInset();
    else
      targetSpan = width - getLeftInset() - getRightInset();

    if (targetSpan != minorSpan)
      {
        minorSpan = targetSpan;

        int n = getViewCount();
        LayoutQueue q = getLayoutQueue();
        for (int i = 0; i < n; i++)
          {
            ChildState cs = getChildState(i);
            cs.childSizeValid = false;
            q.addTask(cs);
          }
        q.addTask(flushTask);
    }
  }

  /**
   * Replaces child views with new child views.
   *
   * This creates ChildState objects for all the new views and adds layout
   * requests for them to the layout queue.
   *
   * @param offset the offset at which to remove/insert
   * @param length the number of child views to remove
   * @param views the new child views to insert
   */
  public void replace(int offset, int length, View[] views)
  {
    synchronized(childStates)
      {
        LayoutQueue q = getLayoutQueue();
        for (int i = 0; i < length; i++)
          childStates.remove(offset);

        for (int i = views.length - 1; i >= 0; i--)
          childStates.add(offset, createChildState(views[i]));

        // We need to go through the new child states _after_ they have been
        // added to the childStates list, otherwise the layout tasks may find
        // an incomplete child list. That means we have to loop through
        // them again, but what else can we do?
        if (views.length != 0)
          {
            for (int i = 0; i < views.length; i++)
              {
                ChildState cs = (ChildState) childStates.get(i + offset);
                cs.getChildView().setParent(this);
                q.addTask(cs);
              }
            q.addTask(flushTask);
          }
      }
  }

  /**
   * Paints the view. This requests the {@link ChildLocator} to paint the views
   * after setting the allocation on it.
   *
   * @param g the graphics context to use
   * @param s the allocation for this view
   */
  public void paint(Graphics g, Shape s)
  {
    synchronized (locator)
      {
        locator.setAllocation(s);
        locator.paintChildren(g);
      }
  }

  /**
   * Returns the preferred span of this view along the specified layout axis.
   *
   * @return the preferred span of this view along the specified layout axis
   */
  public float getPreferredSpan(int axis)
  {
    float retVal;
    if (majorAxis == axis)
      retVal = majorSpan;

    else if (prefReq != null)
      {
        View child = prefReq.getChildView();
        retVal = child.getPreferredSpan(axis);
      }

    // If we have no layout information yet, then return insets + 30 as
    // an estimation.
    else
      {
        if (axis == X_AXIS)
          retVal = getLeftInset() + getRightInset() + 30;
        else
          retVal = getTopInset() + getBottomInset() + 30;
      }
    return retVal;
  }

  /**
   * Maps a model location to view coordinates.
   *
   * @param pos the model location
   * @param a the current allocation of this view
   * @param b the bias
   *
   * @return the view allocation for the specified model location
   */
  public Shape modelToView(int pos, Shape a, Bias b)
    throws BadLocationException
  {
    int index = getViewIndexAtPosition(pos, b);
    Shape ca = locator.getChildAllocation(index, a);

    ChildState cs = getChildState(index);
    synchronized (cs)
      {
        View cv = cs.getChildView();
        Shape v = cv.modelToView(pos, ca, b);
        return v;
      }
  }

  /**
   * Maps view coordinates to a model location.
   *
   * @param x the x coordinate (relative to <code>a</code>)
   * @param y the y coordinate (relative to <code>a</code>)
   * @param b holds the bias of the model location on method exit
   *
   * @return the model location for the specified view location
   */
  public int viewToModel(float x, float y, Shape a, Bias[] b)
  {
    int pos;
    int index;
    Shape ca;

    synchronized (locator)
      {
        index = locator.getViewIndexAtPoint(x, y, a);
        ca = locator.getChildAllocation(index, a);
      }

    ChildState cs = getChildState(index);
    synchronized (cs)
      {
        View v = cs.getChildView();
        pos = v.viewToModel(x, y, ca, b);
      }
    return pos;
  }

  /**
   * Returns the child allocation for the child view with the specified
   * <code>index</code>.
   *
   * @param index the index of the child view
   * @param a the current allocation of this view
   *
   * @return the allocation of the child view
   */
  public Shape getChildAllocation(int index, Shape a)
  {
    Shape ca = locator.getChildAllocation(index, a);
    return ca;
  }

  /**
   * Returns the maximum span of this view along the specified axis.
   * This is implemented to return the <code>preferredSpan</code> for the
   * major axis (that means the box can't be resized along the major axis) and
   * {@link Short#MAX_VALUE} for the minor axis.
   *
   * @param axis the axis
   *
   * @return the maximum span of this view along the specified axis
   */
  public float getMaximumSpan(int axis)
  {
    float max;
    if (axis == majorAxis)
      max = getPreferredSpan(axis);
    else
      max = Short.MAX_VALUE;
    return max;
  }

  /**
   * Returns the minimum span along the specified axis.
   */
  public float getMinimumSpan(int axis)
  {
    float min;
    if (axis == majorAxis)
      min = getPreferredSpan(axis);
    else
      {
        if (minReq != null)
          {
            View child = minReq.getChildView();
            min = child.getMinimumSpan(axis);
          }
        else
          {
            // No layout information yet. Return insets + 5 as some kind of
            // estimation.
            if (axis == X_AXIS)
              min = getLeftInset() + getRightInset() + 5;
            else
              min = getTopInset() + getBottomInset() + 5;
          }
      }
    return min;
  }

  /**
   * Receives notification that one of the child views has changed its
   * layout preferences along one or both axis.
   *
   * This queues a layout request for that child view if necessary.
   *
   * @param view the view that has changed its preferences
   * @param width <code>true</code> if the width preference has changed
   * @param height <code>true</code> if the height preference has changed
   */
  public synchronized void preferenceChanged(View view, boolean width,
                                             boolean height)
  {
    if (view == null)
      getParent().preferenceChanged(this, width, height);
    else
      {
        if (changing != null)
          {
            View cv = changing.getChildView();
            if (cv == view)
              {
                changing.preferenceChanged(width, height);
                return;
              }
          }
        int index = getViewIndexAtPosition(view.getStartOffset(), 
                                           Position.Bias.Forward);
        ChildState cs = getChildState(index);
        cs.preferenceChanged(width, height);
        LayoutQueue q = getLayoutQueue();
        q.addTask(cs);
        q.addTask(flushTask);
      }    
  }

  /**
   * Updates the layout for this view. This is implemented to trigger
   * {@link ChildLocator#childChanged} for the changed view, if there is
   * any.
   *
   * @param ec the element change, may be <code>null</code> if there were
   *        no changes to the element of this view
   * @param e the document event
   * @param a the current allocation of this view
   */
  protected void updateLayout(DocumentEvent.ElementChange ec, 
                              DocumentEvent e, Shape a)
  {
    if (ec != null)
      {
        int index = Math.max(ec.getIndex() - 1, 0);
        ChildState cs = getChildState(index);
        locator.childChanged(cs);
      }
  }
  
  
  /**
   * Returns the <code>ChildState</code> object associated with the child view
   * at the specified <code>index</code>.
   *
   * @param index the index of the child view for which to query the state
   *
   * @return the child state for the specified child view
   */
  protected ChildState getChildState(int index) {
    synchronized (childStates)
      {
        return (ChildState) childStates.get(index);
      }
  }

  /**
   * Returns the <code>LayoutQueue</code> used for layouting the box view.
   * This simply returns {@link LayoutQueue#getDefaultQueue()}.
   *
   * @return the <code>LayoutQueue</code> used for layouting the box view
   */
  protected LayoutQueue getLayoutQueue()
  {
    return LayoutQueue.getDefaultQueue();
  }

  /**
   * Returns the child view index of the view that represents the specified
   * position in the document model.
   * 
   * @param pos the position in the model
   * @param b the bias
   *
   * @return the child view index of the view that represents the specified
   *         position in the document model
   */
  protected synchronized int getViewIndexAtPosition(int pos, Position.Bias b)
  {
    if (b == Position.Bias.Backward)
      pos = Math.max(0, pos - 1);
    Element elem = getElement();
    return elem.getElementIndex(pos);
  }

  /**
   * Creates a <code>ChildState</code> object for the specified view.
   *
   * @param v the view for which to create a child state object
   *
   * @return the created child state
   */
  protected ChildState createChildState(View v)
  {
    return new ChildState(v);
  }

  /**
   * Flushes the requirements changes upwards to the parent view. This is
   * called from the layout thread.
   */
  protected synchronized void flushRequirementChanges()
  {
    if (majorChanged || minorChanged)
      {
        View p = getParent();
        if (p != null)
          {
            boolean horizontal;
            boolean vertical;
            if (majorAxis == X_AXIS)
              {
                horizontal = majorChanged;
                vertical = minorChanged;
              }
            else
              {
                vertical = majorChanged;
                horizontal = minorChanged;
              }

            p.preferenceChanged(this, horizontal, vertical);
            majorChanged = false;
            minorChanged = false;

            Component c = getContainer();
            if (c != null)
              c.repaint();
          }
      }
  }
}
