/* ParagraphView.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.Shape;

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

/**
 * A {@link FlowView} that flows it's children horizontally and boxes the rows
 * vertically.
 *
 * @author Roman Kennke (roman@kennke.org)
 */
public class ParagraphView extends FlowView implements TabExpander
{
  /**
   * A specialized horizontal <code>BoxView</code> that represents exactly
   * one row in a <code>ParagraphView</code>.
   */
  class Row extends BoxView
  {
    /**
     * Creates a new instance of <code>Row</code>.
     */
    Row(Element el)
    {
      super(el, X_AXIS);
    }

    /**
     * Overridden to adjust when we are the first line, and firstLineIndent
     * is not 0.
     */
    public short getLeftInset()
    {
      short leftInset = super.getLeftInset();
      View parent = getParent();
      if (parent != null)
        {
          if (parent.getView(0) == this)
            leftInset += firstLineIndent;
        }
      return leftInset;
    }

    public float getAlignment(int axis)
    {
      float align;
      if (axis == X_AXIS)
        switch (justification)
          {
          case StyleConstants.ALIGN_RIGHT:
            align = 1.0F;
            break;
          case StyleConstants.ALIGN_CENTER:
          case StyleConstants.ALIGN_JUSTIFIED:
            align = 0.5F;
            break;
          case StyleConstants.ALIGN_LEFT:
          default:
            align = 0.0F;
          }
      else
        align = super.getAlignment(axis);
      return align;
    }

    /**
     * Overridden because child views are not necessarily laid out in model
     * order.
     */
    protected int getViewIndexAtPosition(int pos)
    {
      int index = -1;
      if (pos >= getStartOffset() && pos < getEndOffset())
        {
          int nviews = getViewCount();
          for (int i = 0; i < nviews && index == -1; i++)
            {
              View child = getView(i);
              if (pos >= child.getStartOffset() && pos < child.getEndOffset())
                index = i;
            }
        }
      return index;
    }


    /**
     * Overridden to perform a baseline layout. The normal BoxView layout
     * isn't completely suitable for rows.
     */
    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
                                   int[] spans)
    {
      baselineLayout(targetSpan, axis, offsets, spans);
    }

    /**
     * Overridden to perform a baseline layout. The normal BoxView layout
     * isn't completely suitable for rows.
     */
    protected SizeRequirements calculateMinorAxisRequirements(int axis,
                                                            SizeRequirements r)
    {
      return baselineRequirements(axis, r);
    }

    protected void loadChildren(ViewFactory vf)
    {
      // Do nothing here. The children are added while layouting.
    }

    /**
     * Overridden to determine the minimum start offset of the row's children.
     */
    public int getStartOffset()
    {
      // Determine minimum start offset of the children.
      int offset = Integer.MAX_VALUE;
      int n = getViewCount();
      for (int i = 0; i < n; i++)
        {
          View v = getView(i);
          offset = Math.min(offset, v.getStartOffset());
        }
      return offset;
    }

    /**
     * Overridden to determine the maximum end offset of the row's children.
     */
    public int getEndOffset()
    {
      // Determine minimum start offset of the children.
      int offset = 0;
      int n = getViewCount();
      for (int i = 0; i < n; i++)
        {
          View v = getView(i);
          offset = Math.max(offset, v.getEndOffset());
        }
      return offset;
    }
  }

  /**
   * The indentation of the first line of the paragraph.
   */
  protected int firstLineIndent;

  /**
   * The justification of the paragraph.
   */
  private int justification;

  /**
   * The line spacing of this paragraph.
   */
  private float lineSpacing;

  /**
   * The TabSet of this paragraph.
   */
  private TabSet tabSet;

  /**
   * Creates a new <code>ParagraphView</code> for the given
   * <code>Element</code>.
   *
   * @param element the element that is rendered by this ParagraphView
   */
  public ParagraphView(Element element)
  {
    super(element, Y_AXIS);
  }

  public float nextTabStop(float x, int tabOffset)
  {
    throw new InternalError("Not implemented yet");
  }

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

  /**
   * Returns the alignment for this paragraph view for the specified axis.
   * For the X_AXIS the paragraph view will be aligned at it's left edge
   * (0.0F). For the Y_AXIS the paragraph view will be aligned at the
   * center of it's first row.
   *
   * @param axis the axis which is examined
   *
   * @return the alignment for this paragraph view for the specified axis
   */
  public float getAlignment(int axis)
  {
    float align;
    if (axis == X_AXIS)
      align = 0.5F;
    else if (getViewCount() > 0)
      {
        float prefHeight = getPreferredSpan(Y_AXIS);
        float firstRowHeight = getView(0).getPreferredSpan(Y_AXIS);
        align = (firstRowHeight / 2.F) / prefHeight;
      }
    else
      align = 0.5F;
    return align;
  }

  /**
   * Receives notification when some attributes of the displayed element
   * changes. This triggers a refresh of the cached attributes of this
   * paragraph.
   *
   * @param ev the document event
   * @param a the allocation of this view
   * @param vf the view factory to use for creating new child views
   */
  public void changedUpdate(DocumentEvent ev, Shape a, ViewFactory vf)
  {
    setPropertiesFromAttributes();
    layoutChanged(X_AXIS);
    layoutChanged(Y_AXIS);
    super.changedUpdate(ev, a, vf);
  }

  /**
   * Fetches the cached properties from the element's attributes.
   */
  protected void setPropertiesFromAttributes()
  {
    Element el = getElement();
    AttributeSet atts = el.getAttributes();
    setFirstLineIndent(StyleConstants.getFirstLineIndent(atts));
    setLineSpacing(StyleConstants.getLineSpacing(atts));
    setJustification(StyleConstants.getAlignment(atts));
    tabSet = StyleConstants.getTabSet(atts);
  }

  /**
   * Sets the indentation of the first line of the paragraph.
   *
   * @param i the indentation to set
   */
  protected void setFirstLineIndent(float i)
  {
    firstLineIndent = (int) i;
  }

  /**
   * Sets the justification of the paragraph.
   *
   * @param j the justification to set 
   */
  protected void setJustification(int j)
  {
    justification = j;
  }

  /**
   * Sets the line spacing for this paragraph.
   *
   * @param s the line spacing to set
   */
  protected void setLineSpacing(float s)
  {
    lineSpacing = s;
  }

  /**
   * Returns the i-th view from the logical views, before breaking into rows.
   *
   * @param i the index of the logical view to return
   *
   * @return the i-th view from the logical views, before breaking into rows
   */
  protected View getLayoutView(int i)
  {
    return layoutPool.getView(i);
  }

  /**
   * Returns the number of logical child views.
   *
   * @return the number of logical child views
   */
  protected int getLayoutViewCount()
  {
    return layoutPool.getViewCount();
  }

  /**
   * Returns the TabSet used by this ParagraphView.
   *
   * @return the TabSet used by this ParagraphView
   */
  protected TabSet getTabSet()
  {
    return tabSet;
  }

  /**
   * Finds the next offset in the document that has one of the characters
   * specified in <code>string</code>. If there is no such character found,
   * this returns -1.
   *
   * @param string the characters to search for
   * @param start the start offset
   *
   * @return the next offset in the document that has one of the characters
   *         specified in <code>string</code>
   */
  protected int findOffsetToCharactersInString(char[] string, int start)
  {
    int offset = -1;
    Document doc = getDocument();
    Segment text = new Segment();
    try
      {
        doc.getText(start, doc.getLength() - start, text);
        int index = start;

        searchLoop:
        while (true)
          {
            char ch = text.next();
            if (ch == Segment.DONE)
              break;

            for (int j = 0; j < string.length; ++j)
              {
                if (string[j] == ch)
                  {
                    offset = index;
                    break searchLoop;
                  }
              }
            index++;
          }
      }
    catch (BadLocationException ex)
      {
        // Ignore this and return -1.
      }
    return offset;
  }

  protected int getClosestPositionTo(int pos, Position.Bias bias, Shape a,
                                     int direction, Position.Bias[] biasRet,
                                     int rowIndex, int x)
    throws BadLocationException
  {
    // FIXME: Implement this properly. However, this looks like it might
    // have been replaced by viewToModel.
    return pos;
  }

  /**
   * Returns the size that is used by this view (or it's child views) between
   * <code>startOffset</code> and <code>endOffset</code>. If the child views
   * implement the {@link TabableView} interface, then this is used to
   * determine the span, otherwise we use the preferred span of the child
   * views.
   *
   * @param startOffset the start offset
   * @param endOffset the end offset
   *
   * @return the span used by the view between <code>startOffset</code> and
   *         <code>endOffset</cod>
   */
  protected float getPartialSize(int startOffset, int endOffset)
  {
    int startIndex = getViewIndex(startOffset, Position.Bias.Backward);
    int endIndex = getViewIndex(endOffset, Position.Bias.Forward);
    float span;
    if (startIndex == endIndex)
      {
        View child = getView(startIndex);
        if (child instanceof TabableView)
          {
            TabableView tabable = (TabableView) child;
            span = tabable.getPartialSpan(startOffset, endOffset);
          }
        else
          span = child.getPreferredSpan(X_AXIS);
      }
    else if (endIndex - startIndex == 1)
      {
        View child1 = getView(startIndex);
        if (child1 instanceof TabableView)
          {
            TabableView tabable = (TabableView) child1;
            span = tabable.getPartialSpan(startOffset, child1.getEndOffset());
          }
        else
          span = child1.getPreferredSpan(X_AXIS);
        View child2 = getView(endIndex);
        if (child2 instanceof TabableView)
          {
            TabableView tabable = (TabableView) child2;
            span += tabable.getPartialSpan(child2.getStartOffset(), endOffset);
          }
        else
          span += child2.getPreferredSpan(X_AXIS);
      }
    else
      {
        // Start with the first view.
        View child1 = getView(startIndex);
        if (child1 instanceof TabableView)
          {
            TabableView tabable = (TabableView) child1;
            span = tabable.getPartialSpan(startOffset, child1.getEndOffset());
          }
        else
          span = child1.getPreferredSpan(X_AXIS);

        // Add up the view spans between the start and the end view.
        for (int i = startIndex + 1; i < endIndex; i++)
          {
            View child = getView(i);
            span += child.getPreferredSpan(X_AXIS);
          }

        // Add the span of the last view.
        View child2 = getView(endIndex);
        if (child2 instanceof TabableView)
          {
            TabableView tabable = (TabableView) child2;
            span += tabable.getPartialSpan(child2.getStartOffset(), endOffset);
          }
        else
          span += child2.getPreferredSpan(X_AXIS);
      }
    return span;
  }

  /**
   * Returns the location where the tabs are calculated from. This returns
   * <code>0.0F</code> by default.
   *
   * @return the location where the tabs are calculated from
   */
  protected float getTabBase()
  {
    return 0.0F;
  }

  /**
   * @specnote This method is specified to take a Row parameter, which is a
   *           private inner class of that class, which makes it unusable from
   *           application code. Also, this method seems to be replaced by
   *           {@link FlowStrategy#adjustRow(FlowView, int, int, int)}.
   *
   */
  protected void adjustRow(Row r, int desiredSpan, int x)
  {
  }

  /**
   * @specnote This method's signature differs from the one defined in
   *           {@link View} and is therefore never called. It is probably there
   *           for historical reasons.
   */
  public View breakView(int axis, float len, Shape a)
  {
    // This method is not used.
    return null;
  }

  /**
   * @specnote This method's signature differs from the one defined in
   *           {@link View} and is therefore never called. It is probably there
   *           for historical reasons.
   */
  public int getBreakWeight(int axis, float len)
  {
    // This method is not used.
    return 0;
  }
}
