package usinggui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;


/**
 * A simple editor that uses a pop-up menu
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Editor extends    JPanel
                    implements ActionListener, MouseListener
{
    Caret              caret;    
    JMenuItem          copyItem, cutItem, pasteItem;
    JPopupMenu         popup;
    JTextArea          ta;
    String             clipboard;


    /**
     * Constructor
     */
    public Editor()
    {
       super();

       setLayout(new BorderLayout());
       setSize(400,400);

       ta = new JTextArea();
       caret = ta.getCaret();
       ta.setLineWrap(true);
       ta.setWrapStyleWord(true);
       caret = ta.getCaret();

       constructControls();
       performLayout();       
       ta.addMouseListener(this); // To show the popup menu

       clipboard = null;
    }

//[0a
    /**
     * Handle actionPerformed events
     *
     * @param evt   The event
     */
    public void actionPerformed(ActionEvent evt)
    {
       String     command;

       command = evt.getActionCommand();

       if (command.equals("Copy"))       copy();
       else if (command.equals("Cut"))   cut();
       else if (command.equals("Paste")) paste();
    }

    /**
     * Construct the JPopupMenu, JMenu, and JToolBar and
     * add an array of Action objects to them.
     */
    private void constructControls()
    {
       popup = new JPopupMenu();

       copyItem = new JMenuItem("Copy");
       copyItem.addActionListener(this);
       popup.add(copyItem);

       cutItem = new JMenuItem("Cut");
       cutItem.addActionListener(this);
       popup.add(cutItem);

       pasteItem = new JMenuItem("Paste");
       pasteItem.addActionListener(this);
       popup.add(pasteItem);
    }
//]0a
    /**
     * 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();
    }

    /**
     * Is there any text on the "clipboard"?
     *
     * @return true if yes; false otherwise
     */
    public boolean isClipping()
    {
        return (clipboard != null);
    }

    /**
     * Is there any text selected?
     *
     * @return true if yes; false otherwise
     */
    public boolean isSelection()
    {
        return (ta.getSelectedText() != null);
    }

    /**
     * Handle mouseClicked events (required by MouseListener)
     *
     * @param evt   The event
     */
    public void mouseClicked(MouseEvent evt)
    {
    }

    /**
     * Handle mouseEntered events (required by MouseListener)
     *
     * @param evt   The event
     */
    public void mouseEntered(MouseEvent evt)
    {
    }

    /**
     * Handle mouseExited events (required by MouseListener)
     *
     * @param evt   The event
     */
    public void mouseExited(MouseEvent evt)
    {
    }

    /**
     * Handle mousePressed events (required by MouseListener)
     *
     * @param evt   The event
     */
    public void mousePressed(MouseEvent evt)
    {
    }
//[0b
    /**
     * Handle mouseReleased events (required by MouseListener)
     *
     * @param evt   The event
     */
    public void mouseReleased(MouseEvent evt)
    {
       if (evt.isPopupTrigger()) showPopup(evt.getPoint());
    }
//]0b
    /**
     * Layout this Editor.
     */
    private void performLayout()
    {
	JScrollPane      scrollPane;

	setLayout(new BorderLayout());
	setSize(400,400);

	scrollPane = new JScrollPane(ta);
	scrollPane.setHorizontalScrollBarPolicy(
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
            );
	scrollPane.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
            );
	add(scrollPane, BorderLayout.CENTER);
    }

    /**
     * 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();
    }
//[0c
    /**
     * Show the pop-up menu
     *
     * @param point   The location of the pop-up menu
     */
    private void showPopup(Point point)
    {
       copyItem.setEnabled(false);
       cutItem.setEnabled(false);
       pasteItem.setEnabled(false);

       if (isSelection())
       { 
          copyItem.setEnabled(true);
          cutItem.setEnabled(true);
       }

       if (isClipping()) pasteItem.setEnabled(true);

       popup.show(this, point.x, point.y);
    }
//]0c
}
