import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

/**
 * An encapsulation of a simple TextEditor that supports
 * copy, cut, and paste operations.
 * 
 * @author Prof. David Bernstein, James Madison University
 */
public class TextEditor extends JPanel
{
  private static final long serialVersionUID = 1L;
  
  private Caret              caret;
  private JTextArea          ta;
  private String             clipboard;
  
  /**
   * Default Constructor.
   */
  public TextEditor()
  {
    super();
    ta = new JTextArea();
    caret = ta.getCaret();
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    
    performLayout();
  }
  
  /**
   * Add a CaretListener.
   * 
   * @param cl  The CaretListener to add.
   */
  public void addCaretListener(CaretListener cl)
  {
    ta.addCaretListener(cl);
  }
  
  /**
   * Add a MouseListener.
   * 
   * @param ml  The MouseListener to add.
   */
  public void addMouseListener(MouseListener ml)
  {
    ta.addMouseListener(ml);
  }

  /**
   * Copy text to the "clipboard".
   */
  public void copy()
  {
      int  dot, mark;
      
      dot  = caret.getDot();        
      mark = caret.getMark();
      clipboard = ta.getSelectedText();
      ta.select(-1, -1);
      caret.setDot(mark); // Causes a CaretEvent to be fired
      caret.setDot(dot);  // Positions the Caret at the right position
      ta.requestFocus();
  }

  /**
   * Cut text to the "clipboard".
   */
  public void cut()
  {
      int dot;        

      dot = caret.getDot();        
      clipboard = ta.getSelectedText();
      ta.replaceSelection(null);
      ta.select(-1, -1);
      caret.setDot(dot);
      ta.requestFocus();
  }
  
  /**
   * Get the "clipboard" for this TextEditor.
   * 
   * @return The "clipboard"
   */
  public String getClipboard()
  {
    return clipboard;
  }
  
  /**
   * Get the currently selected text for this TextEditor.
   * 
   * @return The text
   */
  public String getSelectedText()
  {
    return ta.getSelectedText();
  }

  /**
   * Paste text from the "clipboard".
   */
  public void paste()
  {
      int dot, offset;        

      dot = caret.getDot();
      offset = clipboard.length();
      
      ta.replaceSelection(clipboard);
      clipboard = null;

      caret.setDot(dot + offset);
      ta.requestFocus();
  }
  
  /**
   * Layout this component.
   */
  private void performLayout()
  {
    setLayout(new BorderLayout());
    
    JScrollPane scrollPane = new JScrollPane(ta);
    scrollPane.setHorizontalScrollBarPolicy(
              JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
              );
    scrollPane.setVerticalScrollBarPolicy(
              JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
              );

    add(scrollPane, BorderLayout.CENTER);
  }
}
