/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed 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 (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.core.gui;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;

import lu.tudor.santec.gecamed.core.gui.listener.GlobalHotkeyRegister;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

/**
 * extension of the Java AbstractAction class with aditional features for GECAMed
 * use this class to add Actions to you module. The action will automatically be added
 * to the buttonbar on top and/or the menubar. The hotkey of the action will be registered
 * in GECAMed for the specified module. 
 *
 * @Version
 * <br>$Log: GECAMedAction.java,v $
 * <br>Revision 1.32  2013-12-27 18:09:26  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.31  2013-08-05 08:22:00  ferring
 * <br>Physician keys not stored by translated name anymore
 * <br>
 * <br>Revision 1.30  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.29  2012-10-03 09:57:37  troth
 * <br>Bug fix: Menu items not longer displayed a HotKey or empty "()" if it is not set.
 * <br>
 * <br>Revision 1.28  2012-01-24 13:20:34  troth
 * <br>Bugfix: Hotkey are now only show in the tooltip text if it is set.
 * <br>
 * <br>Revision 1.27  2012-01-20 17:02:12  troth
 * <br>Add functions to set the icon of TopButton and BottomButton (for example: toggel the buttons image).
 * <br>
 * <br>Revision 1.26  2011-03-10 06:53:33  ferring
 * <br>bug fixed, where all global GECAMedAction had been shown in the patient module top bar, independent of they were specified to be a top button action or not.
 * <br>Now they are only shown, if they ought to be a top button action.
 * <br>
 * <br>Revision 1.25  2011-03-04 09:53:11  ferring
 * <br>Hotkeys for physicians added.
 * <br>It is now possible to make a hotkey consisting of key + modifiers.
 * <br>
 * <br>Revision 1.24  2010-12-20 15:42:05  troth
 * <br>GUI redesign of Waitingroom and the Waitingroom get his own usersettingpanel
 * <br>
 * <br>Revision 1.23  2009-07-02 11:50:43  hermen
 * <br>fixed address/zipcode bug
 * <br>
 * <br>Revision 1.22  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.21  2008-04-29 14:17:38  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.20  2008-03-10 14:14:05  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.19  2008-01-15 09:29:38  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 * <br>Revision 1.18  2007-12-03 10:59:02  hermen
 * <br>updated Javadoc
 * <br>
 *
 */
public class GECAMedAction extends AbstractAction implements Relocalizable
    {
	private static final long serialVersionUID = 1L;
	private static Logger m_Logger = Logger.getLogger ("gecam.client.gui.main.GECAMedAction");
	
	public static String PHYSICIAN_TRANSLATION	= "Hotkeys.selectPhysician";
	public static String NOT_EDITABLE	= "NOT_EDITABLE";
	

	private String			m_Name;
	private ImageIcon		m_Icon;

	protected GECAMedModule	m_Parent;
    protected JButton		m_TopButton;
    protected JButton		m_BottomButton;
	protected JMenuItem		m_MenuItem;
    protected boolean    	m_IsMenuAction;
	protected boolean    	m_IsTopBarAction;
    protected boolean    	m_IsBottomBarAction;
    protected String		m_HotKey = "";
	private int 			m_Shortcut;
	private String			m_Translation			= null;
	private String[]		m_TranslationParameter	= null;

//***************************************************************************
//* Constructor                                                             *
//***************************************************************************

//  ---------------------------------------------------------------------------
/** Constructor.
 * @param p_Parent specifies the parent GECAMedModule this action was created for.
 * @param p_Name specifies the name for the Action to be created
 * @param p_Icon specifies the icon representing the Action
 * @param p_Shortcut specifies the shortcut key (EventKey code) to be assigned to the action.
 * @param p_IsMenuAction
 * @param p_IsTopBarAction specifies whether Action should appear as button in top button bar.
 * @param p_IsBottomBarAction specifies whether Action should appear as button in bottom button bar.
 * @param p_HotKey specifies the global, system-wide hotkey for this action
 */
//    ---------------------------------------------------------------------------
public GECAMedAction (GECAMedModule p_Parent,
			            String		p_Name,
			            ImageIcon   p_Icon,
			            Integer     p_Shortcut,
			            boolean		p_IsMenuAction,
			            boolean     p_IsTopBarAction,
			            boolean	   	p_IsBottomBarAction,
			            int 		p_HotKey)
	{
	this(p_Parent, p_Name, p_Icon, p_Shortcut, p_IsMenuAction, p_IsTopBarAction, p_IsBottomBarAction, p_HotKey, 0);
	this.m_HotKey = GlobalHotkeyRegister.getKeyString(p_HotKey, 0);
	}


public GECAMedAction (GECAMedModule p_Parent,
			            String		p_Name,
			            ImageIcon   p_Icon,
			            Integer     p_Shortcut,
			            boolean		p_IsMenuAction,
			            boolean     p_IsTopBarAction,
			            boolean	   	p_IsBottomBarAction,
			            int 		p_HotKey,
			            int 		p_Modifiers)
	{
	this(p_Parent, p_Name, p_Icon, p_Shortcut, p_IsMenuAction, p_IsTopBarAction, p_IsBottomBarAction);
	this.m_HotKey = GlobalHotkeyRegister.getKeyString(p_HotKey, p_Modifiers);
	}


//---------------------------------------------------------------------------
/** Constructor.
 * @param p_Parent specifies the parent GECAMedModule this action was created for.
 * @param p_Name specifies the name for the Action to be created
 * @param p_Icon specifies the icon representing the Action
 * @param p_Shortcut specifies the shortcut key (EventKey code) to be assigned to the action.
 * @param p_IsTopBarAction specifies whether Action should appear as button in top button bar.
 * @param p_IsBottomBarAction specifies whether Action should appear as button in bottom button bar.
 */
//---------------------------------------------------------------------------

public GECAMedAction (GECAMedModule p_Parent,
                      String      	p_Name,
                      ImageIcon   	p_Icon,
                      Integer       p_Shortcut,
                      boolean		p_IsMenuAction,
                      boolean     	p_IsTopBarAction,
                      boolean	   	p_IsBottomBarAction)
    {
	super(Translatrix.getTranslationString(p_Name), p_Icon);
	
	m_Name  = p_Name;
	m_Icon  = p_Icon;

    if (p_Shortcut != null) {
    	m_Shortcut = p_Shortcut;
    	putValue(MNEMONIC_KEY, Integer.valueOf (p_Shortcut));
    } else {
    	m_Shortcut = KeyEvent.VK_UNDEFINED;
    }

    m_Parent          	= p_Parent;
    m_IsMenuAction  	= p_IsMenuAction;
    m_IsTopBarAction  	= p_IsTopBarAction;
    m_IsBottomBarAction = p_IsBottomBarAction;

    if (m_IsMenuAction)
		{
    		m_MenuItem    = new JMenuItem (this);
    		setMenuIcon(m_Icon, m_MenuItem);
//    			l_SmallIcon = new ImageIcon (m_Icon.getImage().getScaledInstance(16,16,Image.SCALE_SMOOTH));
//    			m_MenuItem.setIcon(l_SmallIcon);
//    		}
    	
		m_MenuItem.setText(Translatrix.getTranslationString(m_Name)
				+ (getHotKey() != null && getHotKey().length() > 0 ? (" ("+ getHotKeyName()+")") : ""));
		}

    if (m_IsTopBarAction)
		{
		m_TopButton    = new JButton (this);
		m_TopButton.setText("");
		}

	if (m_IsBottomBarAction)
		{
		m_BottomButton = new JButton (this);
		m_BottomButton.setText ("");
		}
	}

//***************************************************************************
//* Class Body                                                              *
//***************************************************************************

public boolean isMenuAction ()
	{
	return m_IsMenuAction;
	}

//---------------------------------------------------------------------------

public void setMenuAction (boolean p_IsMenuAction)
	{
	m_IsMenuAction = p_IsMenuAction;
	}

//---------------------------------------------------------------------------

public boolean isTopBarAction ()
	{
	return m_IsTopBarAction;
	}

//---------------------------------------------------------------------------

public void setTopBarAction (boolean p_IsTopBarAction)
	{
	m_IsTopBarAction = p_IsTopBarAction;
	}

//---------------------------------------------------------------------------

public boolean isBottomBarAction ()
	{
	return m_IsBottomBarAction;
	}

//---------------------------------------------------------------------------

public void setBottomBarAction (boolean p_IsBottomBarAction)
	{
	m_IsBottomBarAction = p_IsBottomBarAction;
	}

//---------------------------------------------------------------------------

public String getHotKey()
{
	return m_HotKey;
}

//---------------------------------------------------------------------------

public void setHotKey (int p_HotKey)
{
	setHotKey (GlobalHotkeyRegister.getKeyString(p_HotKey, 0));
}

public void setHotKey(String p_HotKey)
{
	if (m_Parent != null ) {
		try {
			m_Parent.unregisterHotKey(m_HotKey);
		} catch (Exception e) {
		}
		this.m_HotKey = p_HotKey;

		if (p_HotKey != null)
			m_Parent.registerHotKey(m_HotKey, this);
	} else { // global hotkey
		try {
			GlobalHotkeyRegister.unregisterHotKey(m_HotKey);
		} catch (Exception e) {
		}
		this.m_HotKey = p_HotKey;

		if (p_HotKey != null)
			GlobalHotkeyRegister.registerHotKey(m_HotKey, this);
	}
	
	relocalize();
}

//---------------------------------------------------------------------------

public String getHotKeyName()
{
	if (m_HotKey == null)
		return "";
	return m_HotKey;
}

//---------------------------------------------------------------------------

/**
 * @return Returns the Shortcut.
 */
public int getShortcut() {
	return m_Shortcut;
}

/**
 * @return sets the Shortcut.
 */
public void setShortcut(int p_Shortcut) {
	this.m_Shortcut = p_Shortcut;
	putValue(MNEMONIC_KEY, Integer.valueOf (p_Shortcut));
}

/**
 * @return Returns the ShortcutName.
 */
public String getShortcutName() {
	if (m_Shortcut == 0)
		return "";
	return "Alt+" +KeyEvent.getKeyText(m_Shortcut);
}

//---------------------------------------------------------------------------

public void setTranslation (String p_Name, String ... p_TranslationParameter)
{
	m_Translation			= p_Name;
	m_TranslationParameter	= p_TranslationParameter;
}

//---------------------------------------------------------------------------

public void setName (String p_Name)
{
	m_Name	= p_Name;
}

//---------------------------------------------------------------------------

public String getName()
{
	return m_Name;
}

//---------------------------------------------------------------------------

public String getTranslatedName()
{
	return Translatrix.getTranslationString(m_Translation != null ? m_Translation : m_Name, m_TranslationParameter); 
}




//---------------------------------------------------------------------------
/** Adds this action to parent GECAMed Module. Adding action means that
 *  action will be added to module menu (if desired) and that
 *  action buttons are added to modules' top and/or bottom bar respectively.
 */
//---------------------------------------------------------------------------

public void add () {
	add(false);
}

public void add (boolean addSeparator)
	{

	if (m_Parent == null)
		{
		if (m_Name != null) m_Logger.warn (m_Name + " Action can't be added because parent module is not set");
		               else m_Logger.warn ("Unknown Action can't be added because parent module is not set");
		return;
		}

	m_Logger.info ("Adding Action " + m_Name);

	if ((m_IsMenuAction) && (m_MenuItem == null))
		{
		m_MenuItem = new JMenuItem (this);
		setMenuIcon(m_Icon, m_MenuItem);
//		l_SmallIcon = new Image Icon (m_Icon.getImage().getScaledInstance(16,16,Image.SCALE_SMOOTH));
//		m_MenuItem.setIcon(l_SmallIcon);
		m_MenuItem.setText(Translatrix.getTranslationString(m_Name + "Menu"));
		}

	if ((m_IsTopBarAction) && (m_TopButton == null))
		{
		m_TopButton = new JButton (this);
		m_TopButton.setFocusable(true);
		m_TopButton.setText("");
		}

	if ((m_IsBottomBarAction) && (m_BottomButton == null))
		{
		m_BottomButton = new JButton (this);
		m_BottomButton.setText("");
		}

	this.relocalize ();

	if (m_IsMenuAction) {
		m_Parent.addMenuItem (m_MenuItem);
		if (addSeparator)
			m_Parent.addMenuSeparator(new JSeparator());
	}
	if (m_IsTopBarAction)		m_Parent.addTopButton(m_TopButton);
	if (m_IsBottomBarAction)	m_Parent.addTopButton(m_BottomButton);

	if (m_HotKey != null) {
		m_Parent.registerHotKey(m_HotKey, this);
	}

	m_Parent.addGECAMedAction (this);
	}

//---------------------------------------------------------------------------
/** Invoked when an action occurs.
 * @param The Action causing the method to be called.
 */
//---------------------------------------------------------------------------

public void actionPerformed (ActionEvent p_Event)
    {
	m_Logger.info (m_Name + " Action performed!");
    }

//---------------------------------------------------------------------------
/**
 * Method is part of the Relocalizable interface. The method does everything
 * required to reflect changes of active Locale
 */
//---------------------------------------------------------------------------

public void relocalize()
	{
		String l_ToolTipText;
		String l_MenuText;
		
		// if name and tooltip have to be different. Create in Translation the actionname and the tooltip extra
		// and give the tooltip the name: 'actionname + Tip'
		l_ToolTipText = Translatrix.getTranslationString(m_Name + "Tip");
		if (l_ToolTipText.equals(m_Name + "Tip")) 
			l_ToolTipText = Translatrix.getTranslationString(m_Name);
	
		l_ToolTipText = "<html><b>" + l_ToolTipText + "</b>";
		
		if(this.m_HotKey != null)
			if (!this.m_HotKey.equals(""))
				l_ToolTipText += " ("+ this.m_HotKey +")";
		
		
		l_MenuText = Translatrix.getTranslationString(m_Name + "Menu");
		if (l_MenuText.equals(m_Name + "Menu")) 
			l_MenuText = Translatrix.getTranslationString(m_Name);
		
		this.putValue("NAME",Translatrix.getTranslationString(m_Name));
		this.putValue(SHORT_DESCRIPTION, l_ToolTipText);
	
		if (m_MenuItem != null) 	m_MenuItem.setText(l_MenuText + (getHotKey() != null && getHotKey().length() > 0 ? (" ("+ getHotKeyName()+")") : ""));
		if (m_TopButton != null)    m_TopButton.setToolTipText(l_ToolTipText);
		if (m_BottomButton != null) m_BottomButton.setToolTipText(l_ToolTipText);
	}


/**
 * Set the icon to the JMenuItem if icon is not null
 * 
 * @param icon
 * @param mItem
 */
private void setMenuIcon(ImageIcon icon, JMenuItem mItem) {
	/* ================================================== */
	if (icon != null) {
		ImageIcon smallIcon = new ImageIcon (icon.getImage().getScaledInstance(16,16,Image.SCALE_SMOOTH));
		mItem.setIcon(smallIcon);
	}
	/* ================================================== */
}

public void setIcon(ImageIcon icon)
{
	setMenuIcon(icon, m_MenuItem);
}

/**
 * Set the icon to the TopButton if icon is not null
 * 
 * @param icon
 */
public void setTopButtonIcon(ImageIcon icon)
{
	if (icon != null) {
		ImageIcon normalIcon = new ImageIcon (icon.getImage().getScaledInstance(32,32,Image.SCALE_SMOOTH));
		m_TopButton.setIcon(normalIcon);
	}
}

/**
 * Set the icon to the BottomButton if icon is not null
 * 
 * @param icon
 */
public void setBottomButtonIcon(ImageIcon icon)
{
	if (icon != null) {
		ImageIcon normalIcon = new ImageIcon (icon.getImage().getScaledInstance(32,32,Image.SCALE_SMOOTH));
		m_BottomButton.setIcon(normalIcon);
	}
}

/**
 * Set the the ToolTipText of the MenuItem, TopButton or BottomButton
 */
public void setToolTipText(String name)
{
	m_Name = name;
	relocalize();
}


public static String getHotKeyName (Physician physician)
{
	return PHYSICIAN_TRANSLATION + "_" + physician.getId();
}



//***************************************************************************
//* End of Class				                            					*
//***************************************************************************
}


