/* FlowView.java -- A composite View
   Copyright (C) 2005  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.Rectangle;
import java.awt.Shape;

import javax.swing.SizeRequirements;
import javax.swing.event.DocumentEvent;

/**
 * A <code>View</code> that can flows it's children into it's layout space.
 *
 * The <code>FlowView</code> manages a set of logical views (that are
 * the children of the {@link #layoutPool} field). These are translated
 * at layout time into a set of physical views. These are the views that
 * are managed as the real child views. Each of these child views represents
 * a row and are laid out within a box using the superclasses behaviour.
 * The concrete implementation of the rows must be provided by subclasses.
 *
 * @author Roman Kennke (roman@kennke.org)
 */
public abstract class FlowView extends BoxView
{
  /**
   * A strategy for translating the logical views of a <code>FlowView</code>
   * into the real views.
   */
  public static class FlowStrategy
  {
    /**
     * Creates a new instance of <code>FlowStragegy</code>.
     */
    public FlowStrategy()
    {
      // Nothing to do here.
    }

    /**
     * Receives notification from a <code>FlowView</code> that some content
     * has been inserted into the document at a location that the
     * <code>FlowView</code> is responsible for.
     *
     * The default implementation simply calls {@link #layout}.
     *
     * @param fv the flow view that sends the notification
     * @param e the document event describing the change
     * @param alloc the current allocation of the flow view
     */
    public void insertUpdate(FlowView fv, DocumentEvent e, Rectangle alloc)
    {
      // The default implementation does nothing.
    }

    /**
     * Receives notification from a <code>FlowView</code> that some content
     * has been removed from the document at a location that the
     * <code>FlowView</code> is responsible for.
     *
     * The default implementation simply calls {@link #layout}.
     *
     * @param fv the flow view that sends the notification
     * @param e the document event describing the change
     * @param alloc the current allocation of the flow view
     */
    public void removeUpdate(FlowView fv, DocumentEvent e, Rectangle alloc)
    {
      // The default implementation does nothing.
    }

    /**
     * Receives notification from a <code>FlowView</code> that some attributes
     * have changed in the document at a location that the
     * <code>FlowView</code> is responsible for.
     *
     * The default implementation simply calls {@link #layout}.
     *
     * @param fv the flow view that sends the notification
     * @param e the document event describing the change
     * @param alloc the current allocation of the flow view
     */
    public void changedUpdate(FlowView fv, DocumentEvent e, Rectangle alloc)
    {
      // The default implementation does nothing.
    }

    /**
     * Returns the logical view of the managed <code>FlowView</code>.
     *
     * @param fv the flow view for which to return the logical view
     *
     * @return the logical view of the managed <code>FlowView</code>
     */
    protected View getLogicalView(FlowView fv)
    {
      return fv.layoutPool;
    }

    /**
     * Performs the layout for the whole view. By default this rebuilds
     * all the physical views from the logical views of the managed FlowView.
     *
     * This is called by {@link FlowView#layout} to update the layout of
     * the view.
     *
     * @param fv the flow view for which we perform the layout
     */
    public void layout(FlowView fv)
    {
      fv.removeAll();
      Element el = fv.getElement();

      int rowStart = el.getStartOffset();
      int end = el.getEndOffset();
      int rowIndex = 0;
      while (rowStart >= 0 && rowStart < end)
        {
          View row = fv.createRow();
          fv.append(row);
          rowStart = layoutRow(fv, rowIndex, rowStart);
          rowIndex++;
        }
    }

    /**
     * Lays out one row of the flow view. This is called by {@link #layout} to
     * fill one row with child views until the available span is exhausted. The
     * default implementation fills the row by calling
     * {@link #createView(FlowView, int, int, int)} until the available space is
     * exhausted, a forced break is encountered or there are no more views in
     * the logical view. If the available space is exhausted,
     * {@link #adjustRow(FlowView, int, int, int)} is called to fit the row into
     * the available span.
     * 
     * @param fv the flow view for which we perform the layout
     * @param rowIndex the index of the row
     * @param pos the model position for the beginning of the row
     * @return the start position of the next row
     */
    protected int layoutRow(FlowView fv, int rowIndex, int pos)
    {
      View row = fv.getView(rowIndex);
      int axis = fv.getFlowAxis();
      int span = fv.getFlowSpan(rowIndex);
      int x = fv.getFlowStart(rowIndex);
      int offset = pos;
      View logicalView = getLogicalView(fv);
      // Special case when span == 0. We need to layout the row as if it had
      // a span of Integer.MAX_VALUE.
      if (span == 0)
        span = Integer.MAX_VALUE;

      Row: while (span > 0)
        {
          if (logicalView.getViewIndex(offset, Position.Bias.Forward) == - 1)
            break;
          View view = createView(fv, offset, span, rowIndex);
          if (view == null)
            break;

          int viewSpan = (int) view.getPreferredSpan(axis);
          int breakWeight = view.getBreakWeight(axis, x, span);

          row.append(view);
          offset += (view.getEndOffset() - view.getStartOffset());
          x += viewSpan;
          span -= viewSpan;

          // Break if the line if the view does not fit in this row or the
          // line just must be broken.
          if (span < 0 || breakWeight >= View.ForcedBreakWeight)
            {
              int flowStart = fv.getFlowStart(axis);
              int flowSpan = fv.getFlowSpan(axis);
              adjustRow(fv, rowIndex, flowSpan, flowStart);
              int rowViewCount = row.getViewCount();
              if (rowViewCount > 0)
                offset = row.getView(rowViewCount - 1).getEndOffset();
              else
                offset = - 1;
              break Row;
            }
        }

      return offset != pos ? offset : - 1;
    }

    /**
     * Creates physical views that form the rows of the flow view. This
     * can be an entire view from the logical view (if it fits within the
     * available span), a fragment of such a view (if it doesn't fit in the
     * available span and can be broken down) or <code>null</code> (if it does
     * not fit in the available span and also cannot be broken down).
     *
     * The default implementation fetches the logical view at the specified
     * <code>startOffset</code>. If that view has a different startOffset than
     * specified in the argument, a fragment is created using
     * {@link View#createFragment(int, int)} that has the correct startOffset
     * and the logical view's endOffset.
     *
     * @param fv the flow view
     * @param startOffset the start offset for the view to be created
     * @param spanLeft the available span
     * @param rowIndex the index of the row
     *
     * @return a view to fill the row with, or <code>null</code> if there
     *         is no view or view fragment that fits in the available span
     */
    protected View createView(FlowView fv, int startOffset, int spanLeft,
                              int rowIndex)
    {
       View logicalView = getLogicalView(fv);
       // FIXME: Handle the bias thing correctly.
       int index = logicalView.getViewIndex(startOffset, Position.Bias.Forward);
       View retVal = null;
       if (index >= 0)
         {
           retVal = logicalView.getView(index);
           if (retVal.getStartOffset() != startOffset)
             retVal = retVal.createFragment(startOffset, retVal.getEndOffset());
         }
       return retVal;
    }

    /**
     * Tries to adjust the specified row to fit within the desired span. The
     * default implementation iterates through the children of the specified
     * row to find the view that has the highest break weight and - if there
     * is more than one view with such a break weight - which is nearest to
     * the end of the row. If there is such a view that has a break weight >
     * {@link View#BadBreakWeight}, this view is broken using the
     * {@link View#breakView(int, int, float, float)} method and this view and
     * all views after the now broken view are replaced by the broken view.
     *
     * @param fv the flow view
     * @param rowIndex the index of the row to be adjusted
     * @param desiredSpan the layout span
     * @param x the X location at which the row starts
     */
    protected void adjustRow(FlowView fv, int rowIndex, int desiredSpan, int x) {
      // Determine the last view that has the highest break weight.
      int axis = fv.getFlowAxis();
      View row = fv.getView(rowIndex);
      int count = row.getViewCount();
      int breakIndex = -1;
      int maxBreakWeight = View.BadBreakWeight;
      int breakX = x;
      int breakSpan = desiredSpan;
      int currentX = x;
      int currentSpan = desiredSpan;
      for (int i = 0; i < count; ++i)
        {
          View view = row.getView(i);
          int weight = view.getBreakWeight(axis, currentX, currentSpan);
          if (weight >= maxBreakWeight)
            {
              breakIndex = i;
              breakX = currentX;
              breakSpan = currentSpan;
              maxBreakWeight = weight;
            }
          int size = (int) view.getPreferredSpan(axis);
          currentX += size;
          currentSpan -= size;
        }

      // If there is a potential break location found, break the row at
      // this location.
      if (breakIndex > -1)
        {
          View toBeBroken = row.getView(breakIndex);
          View brokenView = toBeBroken.breakView(axis,
                                                 toBeBroken.getStartOffset(),
                                                 breakX, breakSpan);
          row.replace(breakIndex, count - breakIndex,
                      new View[]{brokenView});
        }
    }
  }

  /**
   * This special subclass of <code>View</code> is used to represent
   * the logical representation of this view. It does not support any
   * visual representation, this is handled by the physical view implemented
   * in the <code>FlowView</code>.
   */
  class LogicalView extends BoxView
  {
    /**
     * Creates a new LogicalView instance.
     */
    LogicalView(Element el, int axis)
    {
      super(el, axis);
    }
  }

  /**
   * The shared instance of FlowStrategy.
   */
  static final FlowStrategy sharedStrategy = new FlowStrategy();

  /**
   * The span of the <code>FlowView</code> that should be flowed.
   */
  protected int layoutSpan;

  /**
   * Represents the logical child elements of this view, encapsulated within
   * one parent view (an instance of a package private <code>LogicalView</code>
   * class). These will be translated to a set of real views that are then
   * displayed on screen. This translation is performed by the inner class
   * {@link FlowStrategy}.
   */
  protected View layoutPool;

  /**
   * The <code>FlowStrategy</code> to use for translating between the
   * logical and physical view.
   */
  protected FlowStrategy strategy;

  /**
   * Indicates if the flow should be rebuild during the next layout.
   */
  private boolean layoutDirty;

  /**
   * Creates a new <code>FlowView</code> for the given
   * <code>Element</code> and <code>axis</code>.
   *
   * @param element the element that is rendered by this FlowView
   * @param axis the axis along which the view is tiled, either
   *        <code>View.X_AXIS</code> or <code>View.Y_AXIS</code>, the flow
   *        axis is orthogonal to this one
   */
  public FlowView(Element element, int axis)
  {
    super(element, axis);
    strategy = sharedStrategy;
    layoutDirty = true;
  }

  /**
   * Returns the axis along which the view should be flowed. This is
   * orthogonal to the axis along which the boxes are tiled.
   *
   * @return the axis along which the view should be flowed
   */
  public int getFlowAxis()
  {
    int axis = getAxis();
    int flowAxis;
 
    if (axis == X_AXIS)
      flowAxis = Y_AXIS;
    else
      flowAxis = X_AXIS;

    return flowAxis;

  }

  /**
   * Returns the span of the flow for the specified child view. A flow
   * layout can be shaped by providing different span values for different
   * child indices. The default implementation returns the entire available
   * span inside the view.
   *
   * @param index the index of the child for which to return the span
   *
   * @return the span of the flow for the specified child view
   */
  public int getFlowSpan(int index)
  {
    return layoutSpan;
  }

  /**
   * Returns the location along the flow axis where the flow span starts
   * given a child view index. The flow can be shaped by providing
   * different values here.
   *
   * @param index the index of the child for which to return the flow location
   *
   * @return the location along the flow axis where the flow span starts
   */
  public int getFlowStart(int index)
  {
    return getLeftInset(); // TODO: Is this correct?
  }

  /**
   * Creates a new view that represents a row within a flow.
   *
   * @return a view for a new row
   */
  protected abstract View createRow();

  /**
   * Loads the children of this view. The <code>FlowView</code> does not
   * directly load its children. Instead it creates a logical view
   * ({@link #layoutPool}) which is filled by the logical child views.
   * The real children are created at layout time and each represent one
   * row.
   *
   * This method is called by {@link View#setParent} in order to initialize
   * the view.
   *
   * @param vf the view factory to use for creating the child views
   */
  protected void loadChildren(ViewFactory vf)
  {
    if (layoutPool == null)
      {
        layoutPool = new LogicalView(getElement(), getAxis());
        layoutPool.setParent(this);
      }
  }

  /**
   * Performs the layout of this view. If the span along the flow axis changed,
   * this first calls {@link FlowStrategy#layout} in order to rebuild the
   * rows of this view. Then the superclass's behaviour is called to arrange
   * the rows within the box.
   *
   * @param width the width of the view
   * @param height the height of the view
   */
  protected void layout(int width, int height)
  {
    int flowAxis = getFlowAxis();
    if (flowAxis == X_AXIS)
      {
        if (layoutSpan != width)
          {
            layoutChanged(Y_AXIS);
            layoutSpan = width;
          }
      }
    else
      {
        if (layoutSpan != height)
          {
            layoutChanged(X_AXIS);
            layoutSpan = height;
          }
      }

    if (layoutDirty)
      {
        strategy.layout(this);
        layoutDirty = false;
      }

    if (getPreferredSpan(getAxis()) != height)
      preferenceChanged(this, false, true);

    super.layout(width, height);
  }

  /**
   * Receice notification that some content has been inserted in the region
   * that this view is responsible for. This calls
   * {@link FlowStrategy#insertUpdate}.
   *
   * @param changes the document event describing the changes
   * @param a the current allocation of the view
   * @param vf the view factory that is used for creating new child views
   */
  public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory vf)
  {
    // First we must send the insertUpdate to the logical view so it can
    // be updated accordingly.
    layoutPool.insertUpdate(changes, a, vf);
    strategy.insertUpdate(this, changes, getInsideAllocation(a));
    layoutDirty = true;
  }

  /**
   * Receice notification that some content has been removed from the region
   * that this view is responsible for. This calls
   * {@link FlowStrategy#removeUpdate}.
   *
   * @param changes the document event describing the changes
   * @param a the current allocation of the view
   * @param vf the view factory that is used for creating new child views
   */
  public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory vf)
  {
    layoutPool.removeUpdate(changes, a, vf);
    strategy.removeUpdate(this, changes, getInsideAllocation(a));
    layoutDirty = true;
  }

  /**
   * Receice notification that some attributes changed in the region
   * that this view is responsible for. This calls
   * {@link FlowStrategy#changedUpdate}.
   *
   * @param changes the document event describing the changes
   * @param a the current allocation of the view
   * @param vf the view factory that is used for creating new child views
   */
  public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory vf)
  {
    layoutPool.changedUpdate(changes, a, vf);
    strategy.changedUpdate(this, changes, getInsideAllocation(a));
    layoutDirty = true;
  }

  /**
   * Returns the index of the child <code>View</code> for the given model
   * position.
   *
   * This is implemented to iterate over the children of this
   * view (the rows) and return the index of the first view that contains
   * the given position.
   *
   * @param pos the model position for whicht the child <code>View</code> is
   *        queried
   *
   * @return the index of the child <code>View</code> for the given model
   *         position
   */
  protected int getViewIndexAtPosition(int pos)
  {
    // First make sure we have a valid layout.
    if (!isAllocationValid())
      layout(getWidth(), getHeight());

    int count = getViewCount();
    int result = -1;

    for (int i = 0; i < count; ++i)
      {
        View child = getView(i);
        int start = child.getStartOffset();
        int end = child.getEndOffset();
        if (start <= pos && end > pos)
          {
            result = i;
            break;
          }
      }
    return result;
  }

  /**
   * Calculates the size requirements of this <code>BoxView</code> along
   * its minor axis, that is the axis opposite to the axis specified in the
   * constructor.
   *
   * This is overridden and forwards the request to the logical view.
   *
   * @param axis the axis that is examined
   * @param r the <code>SizeRequirements</code> object to hold the result,
   *        if <code>null</code>, a new one is created
   *
   * @return the size requirements for this <code>BoxView</code> along
   *         the specified axis
   */
  protected SizeRequirements calculateMinorAxisRequirements(int axis,
                                                            SizeRequirements r)
  {
    SizeRequirements res = r;
    if (res == null)
      res = new SizeRequirements();
    res.minimum = (int) layoutPool.getMinimumSpan(axis);
    res.preferred = Math.max(res.minimum,
                             (int) layoutPool.getMinimumSpan(axis));
    res.maximum = Integer.MAX_VALUE;
    res.alignment = 0.5F;
    return res;
  }
}
