/*****************************************************************************
 *                                                                           *
 *  Copyright (c) 2010 by SANTEC/TUDOR www.santec.tudor.lu                   *
 *                                                                           *
 *                                                                           *
 *  This library is free software; you can redistribute it and/or modify it  *
 *  under the terms of the GNU Lesser General Public License as published    *
 *  by the Free Software Foundation; either version 2 of the License, or     *
 *  (at your option) any later version.                                      *
 *                                                                           *
 *  This software 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        *
 *  Lesser General Public License for more details.                          *
 *                                                                           *
 *  You should have received a copy of the GNU Lesser General Public         *
 *  License along with this library; if not, write to the Free Software      *
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  *
 *                                                                           *
 *****************************************************************************/
package lu.tudor.santec.gecamed.core.gui.utils;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.i18n.Translatrix;

/**
 * 
 * An extension of the JTextField component.
 * Has undo features
 * 
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: UndoTextField.java,v $
 * <br>Revision 1.5  2010-10-11 08:45:21  troth
 * <br>add undo and redo function
 * <br>
 * <br>Revision 1.4  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.3  2007/03/02 08:28:39  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1  2006/12/01 14:32:22  heinemann
 * <br>undo textfield
 * <br>undo textarea
 * <br>
 */
public class UndoTextField extends JTextField {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JPopupMenu popup;
	private static JTextComponent currentTextField;
	
	private static MouseAdapter mouseAdapter;
	
	
	/**
	 * 
	 */
	private UndoManager undoManager;
	
	/* *************************************************************
	 *  Static block
	 */
	{
		// init the popup menu
		popup = new JPopupMenu();
		
		popup.add(new AbstractAction(
				Translatrix.getTranslationString("core.undo") + " - Ctrl+Z",
				GECAMedModule.getSmallIcon (GECAMedIconNames.UNDO))
		{
			/* ------------------------------------------------------ */
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ============================================= */
				 if (undoManager.canUndo()) {
                     undoManager.undo();
                 }
				/* ============================================= */
			}
			/* ------------------------------------------------------ */
		});
		
		popup.add(new AbstractAction(
				Translatrix.getTranslationString("core.redo") + " - Ctrl+Y",
				GECAMedModule.getSmallIcon (GECAMedIconNames.DO))
		{
			/* ------------------------------------------------------ */
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ============================================= */
				if (undoManager.canRedo()) {
					undoManager.redo();
                }
				/* ============================================= */
			}
			/* ------------------------------------------------------ */
		});
		
		popup.add(new JSeparator());
		
		popup.add(new AbstractAction(
				Translatrix.getTranslationString("core.copy") + " - Ctrl+C",
				GECAMedModule.getMiniIcon(GECAMedIconNames.COPY))
		{
			/* ------------------------------------------------------ */
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ============================================= */
				// copy selection to clipboard
				currentTextField.copy();
				/* ============================================= */
			}
			/* ------------------------------------------------------ */
		});
		
		popup.add(new AbstractAction(
				Translatrix.getTranslationString("core.paste") + " - Ctrl+V",
				GECAMedModule.getMiniIcon(GECAMedIconNames.PASTE))
		{
			/* ------------------------------------------------------ */
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ============================================= */
				// copy selection to clipboard
				currentTextField.paste();
				/* ============================================= */
			}
			/* ------------------------------------------------------ */
		});
		
		popup.add(new AbstractAction(
				Translatrix.getTranslationString("core.cut") + " - Ctrl+X",
				GECAMedModule.getMiniIcon(GECAMedIconNames.CUT))
		{
			/* ------------------------------------------------------ */
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ============================================= */
				// copy selection to clipboard
				currentTextField.cut();
				/* ============================================= */
			}
			/* ------------------------------------------------------ */
		});
		/* ------------------------------------------------------ */
		/* ------------------------------------------------------ */
		// mouse listener
		mouseAdapter = new MouseAdapter() {

			@Override
			public void mouseReleased(MouseEvent e) {
				/* ============================================= */
				clicked(e);
				/* ============================================= */
			}
			@Override
			public void mousePressed(MouseEvent e) {
				/* ============================================= */
				clicked(e);
				/* ============================================= */
			}
			
			private void clicked(MouseEvent e) {
				/* ====================================================== */
				if (e.isPopupTrigger()) {
					currentTextField = (JTextComponent) e.getSource();
					popup.show(currentTextField, e.getX(), e.getY());
				}
				/* ====================================================== */
			}
		};
	}
	
	
	/* *************************************************************
	 *  Body
	 */
	
	public UndoTextField(UndoManager undoManager) {
		/* ====================================================== */
		this(null, null, 0, undoManager);
		/* ====================================================== */
	}
	
	public UndoTextField(String text, UndoManager undoManager) {
		/* ====================================================== */
		this(null, text, 0, undoManager);
		/* ====================================================== */
	}
	
	public UndoTextField(int columns, UndoManager undoManager) {
		/* ====================================================== */
		this(null, null, columns, undoManager);
		/* ====================================================== */
	}
	
	public UndoTextField(String text, int columns, UndoManager undoManager) {
		/* ====================================================== */
		this(null, text, columns, undoManager);
		/* ====================================================== */
	}
	
	public UndoTextField(Document doc, String text, int columns, UndoManager undoManager) {
		/* ====================================================== */
		super(doc, text, columns);
		this.undoManager = undoManager;
		initListener();
		/* ====================================================== */
	}
	
	
	/**
	 * Add a keylistener and the undomanager
	 */
	private void initListener() {
		/* ====================================================== */
		this.getDocument().addUndoableEditListener(undoManager);
		/* ------------------------------------------------------ */
		// add key listener for Str+Z as undo key
		this.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				/* ============================================= */
				// undo function Crrl+Z
				if (e.isControlDown() && e.getKeyCode() == 90) { // Z
					if (undoManager.canUndo()) {
						undoManager.undo();
						((Component)e.getSource()).requestFocus();
					}
				}
				// redo function Crtl+Y
				if (e.isControlDown() && e.getKeyCode() == 89) { // Y
					if (undoManager.canRedo()) {
						undoManager.redo();
						((Component)e.getSource()).requestFocus();
					}
				}
				/* ============================================= */
			}
		});
		/* ------------------------------------------------------ */
		/* ------------------------------------------------------ */
		// mouslistener for right click context menu
		this.addMouseListener(mouseAdapter);
		/* ====================================================== */
	}
}
