/* 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;
  }
}
