/*******************************************************************************
 * 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.labo.gui.admin;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.security.cert.X509Certificate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.RegexFileFilter;
import lu.tudor.santec.gecamed.core.gui.widgets.FileSelectorPanel;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.PhysicianKey;
import lu.tudor.santec.gecamed.labo.ejb.session.beans.KeyChainBean;
import lu.tudor.santec.gecamed.labo.ejb.session.interfaces.KeyChainInterface;
import lu.tudor.santec.gecamed.labo.gui.LaboModule;
import lu.tudor.santec.gecamed.labo.utils.LaboException;
import lu.tudor.santec.gecamed.labo.utils.PasswordEncrypter;
import lu.tudor.santec.gecamed.labo.utils.SmimeDecoder;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class PhysicianKeyDialog extends JDialog implements PropertyChangeListener,
														   ItemListener,
														   ActionListener,
														   Relocalizable
	{
	/**
	 * 
	 */
	private JPanel					m_KeyFilePanel;
	private TitledBorder			m_KeyFileBorder;
	private RegexFileFilter			m_KeyFileFilter;
	private FileSelectorPanel		m_KeyFileChooser;
	private JCheckBox				m_DifferentCerificateLocation;
	private RegexFileFilter			m_CertificateFileFilter;
	private FileSelectorPanel		m_CertificateFileChooser;
	
	private JPanel					m_PasswordPanel;
	private TitledBorder			m_PasswordBorder;
	private JCheckBox				m_ShowTyping;
	private JLabel					m_PasswordLabel;
	private JPasswordField			m_Password;
	
	private JPanel					m_TestPanel;
	private TitledBorder			m_TestBorder;
	private JButton					m_TestButton;
	
	private JButton					m_SaveButton;
	private JButton					m_CancelButton;
	private boolean					m_Canceled;

	private PhysicianKey			m_Key;
	private PasswordEncrypter		m_PasswordEncrypter;
	private KeyChainInterface		m_KeyInterface;
	
	/** the logger Object for this class */
	private static Logger m_Logger = Logger.getLogger(PhysicianKeyDialog.class.getName());

	private static ImageIcon m_KeyTestIcon     = IconFetcher.getIcon (LaboModule.class,LaboModule.c_i32_TestKey);
	private static ImageIcon m_ValidKeyIcon    = IconFetcher.getIcon (LaboModule.class,LaboModule.c_i32_KeySuccess);
	private static ImageIcon m_InvalidKeyIcon  = IconFetcher.getIcon (LaboModule.class,LaboModule.c_i32_KeyFailure);

    private static Pattern 
    
    c_KeyPattern = Pattern.compile ("^(\\d{6}-\\d{2}[A-Z]?)\\.key$",Pattern.CASE_INSENSITIVE);
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	
	private static final long serialVersionUID 		 = 1L;

	private final static int  c_IconTextGap   		  = 10;

	private final static char c_ClearText			  = '\u0000';
	private final static char c_EchoCharacter		  = '\u2022';
	
	private final static String c_Columns			  = "3dlu,fill:max(70dlu;pref):grow," +
														"3dlu,fill:max(35dlu;pref)," +
														"3dlu,fill:max(35dlu;pref),3dlu";
		
	private final static String c_Rows				  = "3dlu,fill:pref," +
														"3dlu,fill:pref," +
														"3dlu,fill:pref," +
														"3dlu,fill:pref,3dlu";
	
	private final static String c_KeyFileColumns      = "3dlu,fill:pref:grow,3dlu";

	private final static String c_KeyFileRows 	      = "3dlu,fill:pref," +
														"3dlu,fill:pref," +
														"3dlu,fill:pref,3dlu";
	
	private final static String c_PasswordColumns     = "3dlu,fill:max(40dlu;pref)," +
														"3dlu,fill:max(100dlu;pref),3dlu";

	private final static String c_PasswordRows 	  	  = "3dlu,fill:pref," +
														"3dlu,fill:pref,3dlu";

	private final static String c_TestColumns 		  = "3dlu,fill:pref:grow,3dlu";

	private final static String c_TestRows 			  = "3dlu,fill:pref," +
	  													"3dlu,fill:pref,3dlu";

	private final static String	c_Title				  				= "PhysicianKeyDialog.Title";
	
	private final static String	c_KeyFileBorder		  				= "PhysicianKeyDialog.KeyFileBorder";
	private final static String	c_DifferentCertificateLocationLabel	= "PhysicianKeyDialog.DifferentCertificateLocationLabel";
	private final static String	c_KeyFileLabel						= "PhysicianKeyDialog.KeyFileLabel";
	private final static String c_KeyFileFilterDescription			= "PhysicianKeyDialog.KeyFileFilterDescription";
	private final static String	c_CertificateFileLabel				= "PhysicianKeyDialog.CertificateFileLabel";
	private final static String c_CertificateFileFilterDescription	= "PhysicianKeyDialog.CertificateFileFilterDescription";

	private final static String	c_PasswordBorder		  			= "PhysicianKeyDialog.PasswordBorder";
	private final static String c_ShowTypingLabel					= "PhysicianKeyDialog.ShowTypingLabel";
	private final static String c_PasswordLabel						= "PhysicianKeyDialog.PasswordLabel";

	private final static String c_TestBorder						= "PhysicianKeyDialog.TestBorder";
	private final static String c_TestButton						= "PhysicianKeyDialog.TestButton";
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public PhysicianKeyDialog (String p_MasterPassword)
	{		
	super (MainFrame.getInstance(),Translatrix.getTranslationString(c_Title),true);	

	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	
	Color			l_DefaultColor;
	
	m_PasswordEncrypter = new PasswordEncrypter ();
	m_PasswordEncrypter.setEncryptionPassword(p_MasterPassword);
	
	this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	this.getContentPane().setBackground (GECAMedColors.c_GECAMedBackground);
	
	l_Constraints  = new CellConstraints();
	
	l_DefaultColor = (Color) UIManager.getDefaults().get("TextField.inactiveBackground");   
	UIManager.getDefaults().put("TextField.inactiveBackground", Color.WHITE );

	this.buildKeyFilePanel();
	this.buildPasswordPanel();
	this.buildTestPanel();
	
	m_SaveButton    = new JButton ();
	m_SaveButton.setIcon(IconFetcher.getScaledIcon(IconFetcher.class,GECAMedIconNames.OK,16));
	m_SaveButton.addActionListener(this);
	
	m_CancelButton    = new JButton ();
	m_CancelButton.setIcon(IconFetcher.getScaledIcon(IconFetcher.class,GECAMedIconNames.CANCEL,16));
	m_CancelButton.addActionListener(this);

	this.relocalize();

	l_Layout = new FormLayout(c_Columns, c_Rows);
    this.setLayout (l_Layout);

	this.add (m_KeyFilePanel,  	l_Constraints.xywh(2, 2, 5, 1));
	this.add (m_PasswordPanel,  l_Constraints.xywh(2, 4, 5, 1));
	this.add (m_TestPanel,  	l_Constraints.xywh(2, 6, 5, 1));
	this.add (m_SaveButton,		l_Constraints.xywh(4, 8, 1, 1));
	this.add (m_CancelButton,	l_Constraints.xywh(6, 8, 1, 1));
	
	UIManager.getDefaults().put("TextField.inactiveBackground", l_DefaultColor );	
	
	this.getRootPane().setDefaultButton(m_SaveButton);
	m_Key = new PhysicianKey ();
	}
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
/**
 * The private getKeyInterface returns an instance of the PhysicianKeyBean
 * session bean. On the first call, the PhysicianKeyBean will actualy be looked up
 * via JNDI. Once it has been found, the reference to the bean will be stored
 * in a private data member. Doing so avoids JNDI lookups on later calls.
 * @return an instance of the PhysicianKeyBean session bean.
 */
//---------------------------------------------------------------------------

private KeyChainInterface getKeyInterface ()
	{
	if (m_KeyInterface != null) return m_KeyInterface;

	try {
		m_KeyInterface = (KeyChainInterface) ManagerFactory.getRemote (KeyChainBean.class);
		} 
	catch (Exception p_Exception) 
		{
		m_Logger.log(Level.ERROR, "Failed to lookup ConnectionInterface!",p_Exception);
		}

	return m_KeyInterface;
	}

//---------------------------------------------------------------------------
	
	private boolean isValidKey(PhysicianKey p_Key, String p_Password)
	{
		KeyChainInterface	l_KeyInterface;
		int					l_Errors;
		
		l_KeyInterface = this.getKeyInterface();
		
		if (l_KeyInterface == null)
			return false;
		
		try
		{
			l_Errors = l_KeyInterface.isValidKey(p_Key, p_Password);
			
			if (l_Errors != LaboException.ERROR_NONE)
			{
				m_Logger.log(Level.WARN, "Warning while trying to validate key:\n" + LaboException.getMessageForErrors(l_Errors));
			}
		}
		catch (Exception p_Exception)
		{
			l_Errors = LaboException.ERROR_UNKNOWN;
			m_Logger.log(Level.ERROR, "Error while testing validity of key " + p_Key.getLabel() + "!", p_Exception);
		}
		
		
		if (l_Errors != LaboException.ERROR_NONE)
		{
			// TODO: show dialog depending on error
			if ((l_Errors & LaboException.ERROR_PASSWORD_NOT_SET) == LaboException.ERROR_PASSWORD_NOT_SET)
			{
				GECAMedBaseDialogImpl.showMessageDialog(this, 
						Translatrix.getTranslationString("PhysicianKeyDialog.Error.unlockKeyTitle"), 
						Translatrix.getTranslationString("Please enter a password."), 
						GECAMedBaseDialogImpl.OK_BUTTON_MODE, 
						GECAMedModule.getIcon(GECAMedIconNames.ERROR));
			}
			else if ((l_Errors & (LaboException.ERROR_CERTIFICATE_NOT_SET | LaboException.ERROR_KEY_NOT_SET)) 
					!= LaboException.ERROR_NONE)
			{
				GECAMedBaseDialogImpl.showMessageDialog(this, 
						Translatrix.getTranslationString("PhysicianKeyDialog.Error.unlockKeyTitle"), 
						Translatrix.getTranslationString("Please upload your private and public key (.key and .crt file)."), 
						GECAMedBaseDialogImpl.OK_BUTTON_MODE,
						GECAMedModule.getIcon(GECAMedIconNames.ERROR));
			}
			else if ((l_Errors & LaboException.ERROR_PASSWORD_INVALID) == LaboException.ERROR_PASSWORD_INVALID)
			{
				GECAMedBaseDialogImpl.showMessageDialog(this, 
						Translatrix.getTranslationString("PhysicianKeyDialog.Error.unlockKeyTitle"), 
						Translatrix.getTranslationString("The password is invalid."), 
						GECAMedBaseDialogImpl.OK_BUTTON_MODE, 
						GECAMedModule.getIcon(GECAMedIconNames.ERROR));
			}
			else if ((l_Errors & LaboException.ERROR_ROOT_CA_INVALID) == LaboException.ERROR_ROOT_CA_INVALID)
			{
				GECAMedBaseDialogImpl.showMessageDialog(this, 
						Translatrix.getTranslationString("PhysicianKeyDialog.Error.unlockKeyTitle"), 
						Translatrix.getTranslationString("The signer that signed your certificate is not registered. Please add its signature to the Root CAs."),
						GECAMedBaseDialogImpl.OK_BUTTON_MODE, 
						GECAMedModule.getBigIcon(GECAMedIconNames.WARNING));
			}
			else
			{
				GECAMedBaseDialogImpl.showMessageDialog(this, 
						Translatrix.getTranslationString("PhysicianKeyDialog.Error.unlockKeyTitle"), 
						Translatrix.getTranslationString("An error occured. Please see the client and server log file for more details."), 
						GECAMedBaseDialogImpl.OK_BUTTON_MODE,
						GECAMedModule.getIcon(GECAMedIconNames.ERROR));
			}
		}
		
		return l_Errors == LaboException.ERROR_NONE;
	}

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

private JPanel buildKeyFilePanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	

	l_Layout = new FormLayout(c_KeyFileColumns, c_KeyFileRows);
	l_Constraints = new CellConstraints();
	
	m_KeyFileBorder = new TitledBorder ("");
	
	m_KeyFilePanel = new JPanel ();
	m_KeyFilePanel.setBorder(m_KeyFileBorder);
	m_KeyFilePanel.setLayout(l_Layout);
	m_KeyFilePanel.setOpaque (false);
	
	m_KeyFileFilter = new RegexFileFilter ();
	m_KeyFileFilter.setFilePattern("^\\d{6}-\\d{2}[A-Z]?\\.key$", false);
	
	m_KeyFileChooser = new FileSelectorPanel (MainFrame.getInstance(),c_KeyFileLabel,FileSelectorPanel.c_ForLoading);
	m_KeyFileChooser.setFileFilter(m_KeyFileFilter);
	m_KeyFileChooser.setOpaque (false);
	m_KeyFileChooser.addPropertyChangeListener(this);
	
	m_DifferentCerificateLocation = new JCheckBox ();
	m_DifferentCerificateLocation.setSelected(false);
	m_DifferentCerificateLocation.setBackground(GECAMedColors.c_GECAMedBackground);
	m_DifferentCerificateLocation.addItemListener(this);
	
	m_CertificateFileFilter = new RegexFileFilter ();
	m_CertificateFileFilter.setFilePattern("^\\d{6}-\\d{2}[A-Z]?\\.crt$", false);

	m_CertificateFileChooser = new FileSelectorPanel (MainFrame.getInstance(),c_CertificateFileLabel,FileSelectorPanel.c_ForLoading);
	m_CertificateFileChooser.setFileFilter(m_CertificateFileFilter);
	m_CertificateFileChooser.setOpaque (false);
	m_CertificateFileChooser.addPropertyChangeListener(this);
	m_CertificateFileChooser.setEnabled(false);
	
	m_KeyFilePanel.add (m_KeyFileChooser,  				l_Constraints.xywh(2, 2, 1, 1));
	m_KeyFilePanel.add (m_DifferentCerificateLocation,  l_Constraints.xywh(2, 4, 1, 1));
	m_KeyFilePanel.add (m_CertificateFileChooser,  		l_Constraints.xywh(2, 6, 1, 1));
	
	return m_KeyFilePanel;
	}
	
//---------------------------------------------------------------------------

private void buildPasswordPanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	

	l_Layout = new FormLayout(c_PasswordColumns, c_PasswordRows);
	l_Constraints = new CellConstraints();
	
	m_PasswordBorder = new TitledBorder ("");
	
	m_PasswordPanel = new JPanel ();
	m_PasswordPanel.setBorder(m_PasswordBorder);
	m_PasswordPanel.setLayout(l_Layout);
	m_PasswordPanel.setOpaque (false);
	
	m_PasswordLabel = new JLabel ();
	m_PasswordLabel.setForeground(GECAMedColors.c_LabelColor);
	
	m_ShowTyping    = new JCheckBox ();
	m_ShowTyping.setSelected(false);
	m_ShowTyping.setBackground(GECAMedColors.c_GECAMedBackground);
	m_ShowTyping.addItemListener(this);
	
	m_Password		= new JPasswordField ();
	m_Password.setEchoChar(c_EchoCharacter);
	
	m_PasswordPanel.add (m_ShowTyping,  	l_Constraints.xywh(4, 2, 1, 1));
	m_PasswordPanel.add (m_PasswordLabel,  	l_Constraints.xywh(2, 4, 1, 1));
	m_PasswordPanel.add (m_Password,  	 	l_Constraints.xywh(4, 4, 1, 1));
	}

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

private void buildTestPanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	

	l_Layout = new FormLayout(c_TestColumns, c_TestRows);
	l_Constraints = new CellConstraints();
	
	m_TestBorder = new TitledBorder ("");
	
	m_TestPanel = new JPanel ();
	m_TestPanel.setBorder(m_TestBorder);
	m_TestPanel.setLayout(l_Layout);
	m_TestPanel.setOpaque (false);

	m_TestButton = new JButton ();
	m_TestButton.setIcon(m_KeyTestIcon);
	m_TestButton.setText(Translatrix.getTranslationString(c_TestButton));
	m_TestButton.setIconTextGap(c_IconTextGap);
	m_TestButton.addActionListener(this);
	
	m_TestPanel.add (m_TestButton,  	 l_Constraints.xywh(2, 2, 1, 1));
	}

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

private File setKeyFromFile (PhysicianKey p_Key, File p_KeyFile)
	{
	File	l_CertificateFile = null;
	Matcher	l_KeyMatcher;
	
	if ((p_KeyFile != null) && p_KeyFile.canRead())
		{
		l_KeyMatcher = c_KeyPattern.matcher(p_KeyFile.getName());
		if (l_KeyMatcher.matches())
			{
			p_Key.setPemPrivate(SmimeDecoder.getPEMFromFile(p_KeyFile));
			p_Key.setLabel(l_KeyMatcher.group(1));
			
			l_CertificateFile = new File (p_KeyFile.getParent() + File.separator + 
										  l_KeyMatcher.group(1) + ".crt");

			if ((l_CertificateFile != null) && l_CertificateFile.canRead ())
				{
				p_Key.setPemPublic(SmimeDecoder.getPEMFromFile(l_CertificateFile));
				}
			}
		}
	
	return l_CertificateFile;
	}

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

private void updateDialogFromKey (PhysicianKey p_Key) throws LaboException
	{
	File	l_File;
	
	if (p_Key == null) return;
	
	if (p_Key.getLabel() != null)
		{
		l_File = new File (p_Key.getLabel() + ".key");	
		m_KeyFileChooser.setFile (l_File);
		l_File = new File (p_Key.getLabel() + ".crt");	
		m_CertificateFileChooser.setFile(l_File);
		}
		
	m_Password.setEchoChar(c_EchoCharacter);
	
	if (p_Key.getPassword() != null)
		m_Password.setText(m_PasswordEncrypter.decryptPassword(p_Key.getPassword ()));
	}

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

private void updateKeyFromDialog (PhysicianKey p_Key)
	{
	String 			l_EncryptedPassword;
	X509Certificate	l_Certificate;
	
	if (p_Key == null) return;
			
	l_EncryptedPassword = m_PasswordEncrypter.encryptPassword(String.valueOf(m_Password.getPassword()));
	p_Key.setPassword(l_EncryptedPassword);
	}

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

public PhysicianKey getKey ()
	{
	this.updateKeyFromDialog (m_Key);
	return m_Key;
	}

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

	public void setKey(PhysicianKey p_Key)
	{
		m_Key = p_Key;
		
		try
		{
			this.updateDialogFromKey(m_Key);
		}
		catch (LaboException e)
		{
			m_Logger.log(Level.ERROR, "Error setting key. SmimeDecoder error code = "+e.getErrorCode(), e);
		}
	}

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

public boolean wasCanceled ()
	{
	return m_Canceled;	
	}

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

public void relocalize()
	{
	this.setTitle(Translatrix.getTranslationString(c_Title));
		
	if (m_KeyFileBorder != null) 
		m_KeyFileBorder.setTitle(Translatrix.getTranslationString(c_KeyFileBorder));
	
	if (m_KeyFileFilter != null)
		m_KeyFileFilter.setDescription(Translatrix.getTranslationString(c_KeyFileFilterDescription));

	if (m_KeyFileChooser != null)
		m_KeyFileChooser.relocalize();
	
	if (m_DifferentCerificateLocation != null)
		m_DifferentCerificateLocation.setText(Translatrix.getTranslationString(c_DifferentCertificateLocationLabel));
	
	if (m_CertificateFileFilter != null)
		m_CertificateFileFilter.setDescription(Translatrix.getTranslationString(c_CertificateFileFilterDescription));

	if (m_CertificateFileChooser != null)
		m_CertificateFileChooser.relocalize();

	if (m_PasswordBorder != null)
		m_PasswordBorder.setTitle(Translatrix.getTranslationString (c_PasswordBorder));

	if (m_ShowTyping != null)
		m_ShowTyping.setText(Translatrix.getTranslationString (c_ShowTypingLabel));
	
	if (m_PasswordLabel != null)
		m_PasswordLabel.setText (Translatrix.getTranslationString (c_PasswordLabel));
	
	if (m_TestBorder != null)
		m_TestBorder.setTitle(Translatrix.getTranslationString (c_TestBorder));
	
	if (m_SaveButton != null)
		m_SaveButton.setText (Translatrix.getTranslationString("core.save"));
	
	if (m_CancelButton != null)
		m_CancelButton.setText(Translatrix.getTranslationString("core.cancel"));
	}

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

public void propertyChange (PropertyChangeEvent p_ChangeEvent)
	{
	File 					l_File;
	
	if (m_Key == null) return;
	
	if (p_ChangeEvent.getSource().equals(m_KeyFileChooser))
		{
		if (p_ChangeEvent.getPropertyName().equals(FileSelectorPanel.c_FileSelectionChanged))
			{
			l_File = (File) p_ChangeEvent.getNewValue();
				
			l_File = this.setKeyFromFile(m_Key, l_File);
			if (l_File != null) 
				{
				m_CertificateFileChooser.setFile (l_File);
				}
			}				
		}
	else if (p_ChangeEvent.getSource().equals(m_CertificateFileChooser))
		{
		if (p_ChangeEvent.getPropertyName().equals(FileSelectorPanel.c_FileSelectionChanged))
			{
			l_File = (File) p_ChangeEvent.getNewValue();
			m_Key.setPemPublic(SmimeDecoder.getPEMFromFile(l_File));
			}				
		}
	}

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

public void itemStateChanged (ItemEvent p_Event)
	{
	if (p_Event.getSource().equals(m_DifferentCerificateLocation))
		{
		m_CertificateFileChooser.setEnabled(m_DifferentCerificateLocation.isSelected());	
		}
	else if (p_Event.getSource().equals(m_ShowTyping))
		{
		if (m_ShowTyping.isSelected())
			 m_Password.setEchoChar(c_ClearText);
		else m_Password.setEchoChar(c_EchoCharacter);
		}
	}

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

public void actionPerformed(ActionEvent p_ActionEvent)
	{
	if (p_ActionEvent.getSource().equals(m_TestButton))
		{
		if (this.isValidKey(m_Key, String.valueOf(m_Password.getPassword())))
			 m_TestButton.setIcon(m_ValidKeyIcon);
		else m_TestButton.setIcon(m_InvalidKeyIcon);
		}
		
	else if (p_ActionEvent.getSource().equals(m_CancelButton))
		{
		this.setVisible (false);
		m_Canceled = true;
		}
	else if (p_ActionEvent.getSource().equals(m_SaveButton))
		{				
		m_Canceled = false;
		this.setVisible (false);
		}
	}

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