/* JTextArea.java --
   Copyright (C) 2004, 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;

import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Rectangle;

import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleStateSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
import javax.swing.text.View;

/**
 * The <code>JTextArea</code> component provides a multi-line area for displaying
 * and editing plain text.  The component is designed to act as a lightweight
 * replacement for the heavyweight <code>java.awt.TextArea</code> component,
 * which provides similar functionality using native widgets.
 * <p>
 *
 * This component has additional functionality to the AWT class.  It follows
 * the same design pattern as seen in other text components, such as
 * <code>JTextField</code>, <code>JTextPane</code> and <code>JEditorPane</code>,
 * and embodied in <code>JTextComponent</code>.  These classes separate the text
 * (the model) from its appearance within the onscreen component (the view).  The
 * text is held within a <code>javax.swing.text.Document</code> object, which can
 * also maintain relevant style information where necessary.  As a result, it is the
 * document that should be monitored for textual changes, via
 * <code>DocumentEvent</code>s delivered to registered
 * <code>DocumentListener</code>s, rather than this component.
 * <p>
 *
 * Unlike <code>java.awt.TextArea</code>, <code>JTextArea</code> does not
 * handle scrolling.  Instead, this functionality is delegated to a
 * <code>JScrollPane</code>, which can contain the text area and handle
 * scrolling when required.  Likewise, the word wrapping functionality
 * of the AWT component is converted to a property of this component
 * and the <code>rows</code> and <code>columns</code> properties
 * are used in calculating the preferred size of the scroll pane's
 * view port.
 *
 * @author Michael Koch  (konqueror@gmx.de)
 * @author Andrew John Hughes  (gnu_andrew@member.fsf.org)
 * @see java.awt.TextArea
 * @see javax.swing.text.JTextComponent
 * @see javax.swing.JTextField
 * @see javax.swing.JTextPane
 * @see javax.swing.JEditorPane
 * @see javax.swing.text.Document
 * @see javax.swing.event.DocumentEvent
 * @see javax.swing.event.DocumentListener
 */

public class JTextArea extends JTextComponent
{
  /**
   * Provides accessibility support for <code>JTextArea</code>.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class AccessibleJTextArea extends AccessibleJTextComponent
  {

    /**
     * Creates a new <code>AccessibleJTextArea</code> object.
     */
    protected AccessibleJTextArea()
    {
      super();
    }

    /**
     * Returns the accessible state of this <code>AccessibleJTextArea</code>.
     *
     * @return  the accessible state of this <code>AccessibleJTextArea</code>
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleStateSet state = super.getAccessibleStateSet();
      // TODO: Figure out what state must be added here to the super's state.
      return state;
    }
  }

  /**
   * Compatible with Sun's JDK
   */
  private static final long serialVersionUID = -6141680179310439825L;

  /**
   * The number of rows used by the component.
   */
  private int rows;

  /**
   * The number of columns used by the component.
   */
  private int columns;

  /**
   * Whether line wrapping is enabled or not.
   */
  private boolean lineWrap;

  /**
   * The number of characters equal to a tab within the text.
   */
  private int tabSize = 8;

  private boolean wrapStyleWord;

  /**
   * Creates a new <code>JTextArea</code> object.
   */
  public JTextArea()
  {
    this(null, null, 0, 0);
  }

  /**
   * Creates a new <code>JTextArea</code> object.
   *
   * @param text the initial text
   */
  public JTextArea(String text)
  {
    this(null, text, 0, 0);
  }

  /**
   * Creates a new <code>JTextArea</code> object.
   *
   * @param rows the number of rows
   * @param columns the number of cols
   *
   * @exception IllegalArgumentException if rows or columns are negative
   */
  public JTextArea(int rows, int columns)
  {
    this(null, null, rows, columns);
  }

  /**
   * Creates a new <code>JTextArea</code> object.
   *
   * @param text the initial text
   * @param rows the number of rows
   * @param columns the number of cols
   *
   * @exception IllegalArgumentException if rows or columns are negative
   */
  public JTextArea(String text, int rows, int columns)
  {
    this(null, text, rows, columns);
  }

  /**
   * Creates a new <code>JTextArea</code> object.
   *
   * @param doc the document model to use
   */
  public JTextArea(Document doc)
  {
    this(doc, null, 0, 0);
  }

  /**
   * Creates a new <code>JTextArea</code> object.
   *
   * @param doc the document model to use
   * @param text the initial text
   * @param rows the number of rows
   * @param columns the number of cols
   *
   * @exception IllegalArgumentException if rows or columns are negative
   */
  public JTextArea(Document doc, String text, int rows, int columns)
  {
    setDocument(doc == null ? createDefaultModel() : doc);
    // Only explicitly setText() when there is actual text since
    // setText() might be overridden and not expected to be called
    // from the constructor (as in JEdit).
    if (text != null)
      setText(text);
    setRows(rows);
    setColumns(columns);
  }

  /**
   * Appends the supplied text to the current contents
   * of the document model.
   *
   * @param toAppend the text to append
   */
  public void append(String toAppend)
  {
      try
          {
              getDocument().insertString(getText().length(), toAppend, null);
          }
      catch (BadLocationException exception)
          {
              /* This shouldn't happen in theory -- but, if it does...  */
              throw new RuntimeException("Unexpected exception occurred.", exception);
          }
      if (toAppend != null && toAppend.length() > 0)
        revalidate();
  }

  /**
   * Creates the default document model.
   *
   * @return a new default model
   */
  protected Document createDefaultModel()
  {
    return new PlainDocument();
  }

  /**
   * Returns true if the width of this component should be forced
   * to match the width of a surrounding view port.  When line wrapping
   * is turned on, this method returns true.
   *
   * @return true if lines are wrapped.
   */
  public boolean getScrollableTracksViewportWidth()
  {
    return lineWrap ? true : super.getScrollableTracksViewportWidth();
  }

  /**
   * Returns the increment that is needed to expose exactly one new line
   * of text. This is implemented here to return the values of
   * {@link #getRowHeight} and {@link #getColumnWidth}, depending on
   * the value of the argument <code>direction</code>.
   *
   * @param visibleRect the view area that is visible in the viewport
   * @param orientation either {@link SwingConstants#VERTICAL} or
   *     {@link SwingConstants#HORIZONTAL}
   * @param direction less than zero for up/left scrolling, greater
   *     than zero for down/right scrolling
   *
   * @return the increment that is needed to expose exactly one new row
   *     or column of text
   *
   * @throws IllegalArgumentException if <code>orientation</code> is invalid
   */
  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                        int direction)
  {
    if (orientation == SwingConstants.VERTICAL)
      return getRowHeight();
    else if (orientation == SwingConstants.HORIZONTAL)
      return getColumnWidth();
    else
      throw new IllegalArgumentException("orientation must be either "
                                     + "javax.swing.SwingConstants.VERTICAL "
                                     + "or "
                                     + "javax.swing.SwingConstants.HORIZONTAL"
                                     );
  }

  /**
   * Returns the preferred size of that text component in the case
   * it is embedded within a JScrollPane. This uses the column and
   * row settings if they are explicitly set, or fall back to
   * the superclass's behaviour.
   *
   * @return the preferred size of that text component in the case
   *     it is embedded within a JScrollPane
   */
  public Dimension getPreferredScrollableViewportSize()
  {
    if ((rows > 0) && (columns > 0))
      return new Dimension(columns * getColumnWidth(), rows * getRowHeight());
    else
      return super.getPreferredScrollableViewportSize();
  }

  /**
   * Returns the UI class ID string.
   *
   * @return the string "TextAreaUI"
   */
  public String getUIClassID()
  {
    return "TextAreaUI";
  }

  /**
   * Returns the current number of columns.
   *
   * @return number of columns
   */
  public int getColumns()
  {
    return columns;
  }

  /**
   * Sets the number of rows.
   *
   * @param columns number of columns
   *
   * @exception IllegalArgumentException if columns is negative
   */
  public void setColumns(int columns)
  {
    if (columns < 0)
      throw new IllegalArgumentException();

    if (columns != this.columns)
      {
        this.columns = columns;
        revalidate();
      }
  }

  /**
   * Returns the current number of rows.
   *
   * @return number of rows
   */
  public int getRows()
  {
    return rows;
  }

  /**
   * Sets the number of rows.
   *
   * @param rows number of rows
   *
   * @exception IllegalArgumentException if rows is negative
   */
  public void setRows(int rows)
  {
    if (rows < 0)
      throw new IllegalArgumentException();

    if (rows != this.rows)
      {
        this.rows = rows;
        revalidate();
      }
  }

  /**
   * Checks whether line wrapping is enabled.
   *
   * @return <code>true</code> if line wrapping is enabled,
   * <code>false</code> otherwise
   */
  public boolean getLineWrap()
  {
    return lineWrap;
  }

  /**
   * Enables/disables line wrapping.
   *
   * @param flag <code>true</code> to enable line wrapping,
   * <code>false</code> otherwise
   */
  public void setLineWrap(boolean flag)
  {
    if (lineWrap == flag)
      return;

    boolean oldValue = lineWrap;
    lineWrap = flag;
    firePropertyChange("lineWrap", oldValue, lineWrap);
  }

  /**
   * Checks whether word style wrapping is enabled.
   *
   * @return <code>true</code> if word style wrapping is enabled,
   * <code>false</code> otherwise
   */
  public boolean getWrapStyleWord()
  {
    return wrapStyleWord;
  }

  /**
   * Enables/Disables word style wrapping.
   *
   * @param flag <code>true</code> to enable word style wrapping,
   * <code>false</code> otherwise
   */
  public void setWrapStyleWord(boolean flag)
  {
    if (wrapStyleWord == flag)
      return;

    boolean oldValue = wrapStyleWord;
    wrapStyleWord = flag;
    firePropertyChange("wrapStyleWord", oldValue, wrapStyleWord);
  }

  /**
   * Returns the number of characters used for a tab.
   * This defaults to 8.
   *
   * @return the current number of spaces used for a tab.
   */
  public int getTabSize()
  {
    return tabSize;
  }

  /**
   * Sets the number of characters used for a tab to the
   * supplied value.  If a change to the tab size property
   * occurs (i.e. newSize != tabSize), a property change event
   * is fired.
   *
   * @param newSize The new number of characters to use for a tab.
   */
  public void setTabSize(int newSize)
  {
    if (tabSize == newSize)
      return;

    int oldValue = tabSize;
    tabSize = newSize;
    firePropertyChange("tabSize", oldValue, tabSize);
  }

  protected int getColumnWidth()
  {
    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
    return metrics.charWidth('m');
  }

  public int getLineCount()
  {
    return getDocument().getDefaultRootElement().getElementCount();
  }

  public int getLineStartOffset(int line)
     throws BadLocationException
  {
    int lineCount = getLineCount();

    if (line < 0 || line > lineCount)
      throw new BadLocationException("Non-existing line number", line);

    Element lineElem = getDocument().getDefaultRootElement().getElement(line);
    return lineElem.getStartOffset();
  }

  public int getLineEndOffset(int line)
     throws BadLocationException
  {
    int lineCount = getLineCount();

    if (line < 0 || line > lineCount)
      throw new BadLocationException("Non-existing line number", line);

    Element lineElem = getDocument().getDefaultRootElement().getElement(line);
    return lineElem.getEndOffset();
  }

  public int getLineOfOffset(int offset)
    throws BadLocationException
  {
    Document doc = getDocument();

    if (offset < doc.getStartPosition().getOffset()
        || offset >= doc.getEndPosition().getOffset())
      throw new BadLocationException("offset outside of document", offset);

    return doc.getDefaultRootElement().getElementIndex(offset);
  }

  protected int getRowHeight()
  {
    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
    return metrics.getHeight();
  }

  /**
   * Inserts the supplied text at the specified position.  Nothing
   * happens in the case that the model or the supplied string is null
   * or of zero length.
   *
   * @param string The string of text to insert.
   * @param position The position at which to insert the supplied text.
   * @throws IllegalArgumentException if the position is &lt; 0 or greater
   * than the length of the current text.
   */
  public void insert(String string, int position)
  {
    // Retrieve the document model.
    Document doc = getDocument();

    // Check the model and string for validity.
    if (doc == null
        || string == null
        || string.length() == 0)
      return;

    // Insert the text into the model.
    try
      {
        doc.insertString(position, string, null);
      }
    catch (BadLocationException e)
      {
        throw new IllegalArgumentException("The supplied position, "
                                           + position + ", was invalid.");
      }
  }

  public void replaceRange(String text, int start, int end)
  {
    Document doc = getDocument();

    if (start > end
        || start < doc.getStartPosition().getOffset()
        || end >= doc.getEndPosition().getOffset())
      throw new IllegalArgumentException();

    try
      {
        doc.remove(start, end - start);
        doc.insertString(start, text, null);
      }
    catch (BadLocationException e)
      {
        // This cannot happen as we check offset above.
      }
  }

  /**
   * Returns the preferred size for the JTextArea. This is the maximum of
   * the size that is needed to display the content and the requested size
   * as per {@link #getColumns} and {@link #getRows}.
   *
   * @return the preferred size of the JTextArea
   */
  public Dimension getPreferredSize()
  {
    int reqWidth = getColumns() * getColumnWidth();
    int reqHeight = getRows() * getRowHeight();
    View view = getUI().getRootView(this);
    int neededWidth = (int) view.getPreferredSpan(View.HORIZONTAL);
    int neededHeight = (int) view.getPreferredSpan(View.VERTICAL);
    return new Dimension(Math.max(reqWidth, neededWidth),
                          Math.max(reqHeight, neededHeight));
  }

  /**
   * Returns the accessible context associated with the <code>JTextArea</code>.
   *
   * @return the accessible context associated with the <code>JTextArea</code>
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJTextArea();
    return accessibleContext;
  }
}
