package lu.tudor.santec.gecamed.esante.gui.dialogs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;

import javax.net.ssl.SSLSocketFactory;
import javax.swing.AbstractAction;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.Document;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.esante.ejb.entity.beans.ESanteProperty;
import lu.tudor.santec.gecamed.esante.ejb.session.beans.ESanteConfigManagerBean;
import lu.tudor.santec.gecamed.esante.gui.IconNames;
import lu.tudor.santec.gecamed.esante.gui.data.Configuration;
import lu.tudor.santec.gecamed.esante.gui.luxtrust.UserInactivityMonitor;
import lu.tudor.santec.gecamed.esante.gui.utils.ESanteGuiUtils;
import lu.tudor.santec.gecamed.esante.gui.webservice.SSLManager;
import lu.tudor.santec.gecamed.esante.gui.webservice.Security;
import lu.tudor.santec.gecamed.esante.utils.exceptions.SendingStoppedException;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.l2fprod.common.swing.JLinkButton;

/**
 * @author jens.ferring(at)tudor.lu
 * 
 * @version <br>
 *          $Log: LoginDialog.java,v $
 *          Revision 1.29  2014-02-06 14:25:33  ferring
 *          Username-password token removed and replaced by user name
 *
 *          Revision 1.28  2014-02-04 10:08:39  ferring
 *          eSante ID management completed
 *          Only those documents will be shown, that are retrieved by the RSQ
 *
 *          Revision 1.27  2014-02-03 12:42:11  ferring
 *          Text fields enlarged
 *
 *          Revision 1.26  2014-01-27 13:13:47  donak
 *          * Properties are now saved in db in respect to the following contexts:
 *            - specific to a GECAMed user
 *            - specific to a GECAMed physician
 *            - specific to an eSanté plattform user
 *            - general (independend of GECAMed user, physician, eSanté platform user)
 *          * Improved authentication handling. A signed authentication request is now only done for user authentication. for dsp authentication requests the provided saml assertion is used. (authentication speed up). ATTENTION: This fix is currently disabled till a bug in the eSanté platform has been fixed.
 *          * Naming of message loggings had been adapted to the naming in the connection kit (e.g. DSP-10, DSP-22)
 *          * Changed behavior for handling of dsps for which physician has insufficient access permissions. If physician does not want to provide presence password, a DSP-11 is sent instead of a DSP-12 to allow the physician to at least access the documents he is author of.
 *
 *          Revision 1.25  2014-01-27 10:08:55  ferring
 *          background changed to GECAMed default
 *
 *          Revision 1.24  2014-01-23 15:01:43  ferring
 *          logout button added
 *
 *          Revision 1.23  2014-01-17 11:13:33  ferring
 *          Progress dialog added, telling that something is in going on, when checking LuxTrust stuff
 *
 *          Revision 1.22  2014-01-08 17:46:20  donak
 *          Improved card reader feedback delay when inserting smartcard
 *          Solved issue with storing UserAssertion in table DSP
 *          Added handling for closed/deleted dsps and blacklisted users
 *          Created class DspPrivileges for convenient handling of dsp access rights. The privileges are cached and renewed with each dp saml assertion request. Cached privileges should be used for displaying dsp state and mandate on screen
 *          Fixed exception that was occasionally thrown at smartcard handling in login dialog (hopefully)
 *
 *          Revision 1.21  2013-12-27 17:05:05  donak
 *          Fixed bug that prevented saml assertions from being cached
 *          (hopefully) fixed watchdog issue causing unpredictable user timeouts
 *
 *          Revision 1.20  2013-12-23 18:07:36  donak
 *          Stabilized smartcard login - using now the LuxTrust API and should thus be easily extendible to signing server usage.
 *
 *          Revision 1.19  2013-12-19 12:37:22  ferring
 *          *** empty log message ***
 *
 *          Revision 1.18  2013-12-13 16:17:08  donak
 *          LuxTrust authentication completed
 *
 *          Revision 1.17  2013-12-13 13:17:24  donak
 *          Integratoin of LuxTrust authentication - so far it is disabled
 *
 *          Revision 1.16  2013-12-13 12:31:31  ferring
 *          Exception handling changed
 *
 *          Revision 1.15  2013-12-13 11:52:57  donak
 *          Only same entered user data to db when the user does not use his luxtrust card for authentication
 *
 *          Revision 1.14  2013-12-13 11:35:48  donak
 *          Further adaptions for displaying the data that is printed on the smart card when using LuxTrust authentication
 *
 *          Revision 1.13  2013-12-12 18:10:27  donak
 *          Forgot to remove a debug entry...
 *
 *          Revision 1.12  2013-12-12 18:08:14  donak
 *          Added SmartCard functionality to login dialog. Functionality is now integrated with watchdog. Next step will the integration of the signing class and changing the saml request behavior.
 * <br>
 *          Revision 1.11 2013-12-11 16:17:14 ferring <br>
 *          Tabbed pane prepared <br>
 * <br>
 *          Revision 1.10 2013-12-11 08:11:30 ferring <br>
 *          translations added <br>
 * <br>
 *          Revision 1.9 2013-12-05 12:27:19 ferring <br>
 *          CDA columns renamed <br>
 *          Login data of user stored <br>
 *          Checking if CDA doc exists, creating a new one <br>
 * <br>
 *          Revision 1.8 2013-10-25 08:49:46 ferring <br>
 *          focus handling added <br>
 * <br>
 *          Revision 1.7 2013-10-24 15:11:56 donak <br>
 *          Added LuxTrust card watchdog. <br>
 *          Harmonized "invalid authentication data" dialogs <br>
 *          optimized upload process <br>
 * <br>
 *          Revision 1.6 2013-10-23 14:56:25 donak <br>
 *          Inactivity watchdog integration (currently timeout is set to 5 minutes). 30 seconds before automated logout takes place, a warning message will be
 *          displayed on screen. Watchdos is activated as soon as a saml assertion is cached and disabled after it purged the saml cache and reset the user
 *          password for accessing the DSP. Availability of LuxTrust card is currently not checked but will be added to the next version. <br>
 *          Added specifc error message if user logs in with invalid authentication information. <br>
 * <br>
 *          Revision 1.5 2013-10-23 07:32:32 ferring <br>
 *          icon names changed to constants <br>
 * <br>
 *          Revision 1.4 2013-10-09 13:36:35 ferring <br>
 *          eSanté icon changed and tree view initialised <br>
 * <br>
 *          Revision 1.3 2013-09-04 06:19:16 ferring <br>
 *          eSante view bugfixes <br>
 * <br>
 *          Revision 1.2 2013-07-03 13:06:24 ferring <br>
 *          eSante module handling changed <br>
 * <br>
 *          Revision 1.1 2013-06-10 08:21:53 ferring <br>
 *          eSante POC <br>
 */

public class LoginDialog extends GECAMedBaseDialogImpl implements CaretListener, ChangeListener {
	/* ======================================== */
	// CONSTANTS
	/* ======================================== */

	private static final long serialVersionUID = 5603949255110390597L;
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(LoginDialog.class.getName());

	/* ======================================== */
	// MEMBERS
	/* ======================================== */

	private static Configuration loginConfig;
	private static boolean displayExpirationMessage = false;

	// token field for username/password login
//	private JTextField loginFieldUp;
	// token field for sigining server login
//	private JTextField loginFieldSs;
	// token field for username/password login
//	private JTextField idFieldUp;
	// token field for sigining server login
//	private JTextField idFieldSs;
	// password field for signing server login
//	private JTextField passwordFieldSs;
	// password field for username/password login
//	private JTextField passwordFieldUp;
	// password field for smartcard login
	private JTextField passwordFieldSc;
	// the document containing the user login
	private Document loginDoc = null;
	// the document containing the user id (or nonce)
//	private Document idDoc = null;
	// the document containing the user password
//	private Document password_Doc = null;
	// pane that contains the tabs with the different login methods
	private JTabbedPane tabbedPane;
	// login via signing server
//	private JPanel signingServerLoginPanel;
	// informs the user that his session has expired
	private JLabel sessionExpired;
	// login via smartcard
	private JPanel smartCardLoginPanel;
	// shown if the LuxTrust middleware is not installed
	private JPanel ltmwDownloadPanel;
	// temporary way for user login with username/password (low security)
//	private JPanel userPassLoginPanel;
	// has to be dynamically set to the name of the owner of the currently inserted smartcard
	private JLabel smartCardOwner = new JLabel();
	// has to be dynamically set to the serial number of the currently inserted smartcard
	private JLabel smartCardId = new JLabel();
	// requests the user to insert a smart card
	private JLabel messageLabelSc;
	// provides access to the smartcard
	private static UserInactivityMonitor watchdog;
	// indicates if there is a smartcard driver installed and thus this way for identification has to be offered to the user
//	private static Boolean isSmartcardInstalled;

	/* ======================================== */
	// CONSTRUCTORS
	/* ======================================== */

	private LoginDialog() {
		super(MainFrame.getInstance(), Translatrix.getTranslationString("esante.loginDialog"), OK_CANCEL_BUTTON_MODE);

		setResizingOptions(RESIZING_NONE);
		mainPanel.setLayout(new BorderLayout());

		// create panel and tabs
		tabbedPane = new JTabbedPane();
		tabbedPane.setOpaque(false);
//		userPassLoginPanel	= createUserPassLoginTab();
		smartCardLoginPanel	= createSmartCardLoginTab();
		ltmwDownloadPanel	= createLTMWDownloadTab();
		
		// and stack them
//		tabbedPane.addTab(Translatrix.getTranslationString("esante.loginDialog.titleUserPassword"), userPassLoginPanel);
		// smartcard login tab only makes sense if the driver has been installed
		tabbedPane.addTab(Translatrix.getTranslationString("esante.loginDialog.titleSmartCard"), 
				getWatchDog().isLuxTrustDriverInstalled() ? smartCardLoginPanel : ltmwDownloadPanel);
		// TODO add signing server token tab
		mainPanel.add(tabbedPane, BorderLayout.CENTER);
		tabbedPane.addChangeListener(this);
	}

	/**
	 * Creates a tab that allows the user to login via a luxtrust smartcard
	 * 
	 * @return The smartcard login tab
	 */
	private JPanel createSmartCardLoginTab() {
		JPanel			smartCardLoginPanel	= new JPanel();
		CellConstraints	cc					= new CellConstraints();
		
		
		// define layout
		smartCardLoginPanel.setLayout(new FormLayout(
		// column definition
				"15px, f:p, 15px, f:p, 10px, f:80dlu:g, 15px",
				// row definition
				"15px,f:p," + // session expired message
				"15px,f:p," + // smart card owner name (label and value)
				" 5px,f:p," + // smart card id (label and value)
				" 5px,f:p," + // private key password
				" 5px,f:p," + // insert card message
				"15px:g"));
		smartCardLoginPanel.setOpaque(false);

		// create icon for the smartcard authentication
		JLabel iconLabelSc = new JLabel(ESanteGuiUtils.getIcon(IconNames.ESANTE_LOGO_SQUARE, ESanteGuiUtils.LARGEPIX));
		iconLabelSc.setOpaque(false);

		// create the label that tags the name of the owner of the inserted smartcard
		JLabel smartCardOwnerLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.smartCardOwner"));
		smartCardOwnerLabel.setOpaque(false);

		// create the label that tags the id of the inserted smartcard
		JLabel smartCardIdLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.smartCardId"));
		smartCardIdLabel.setOpaque(false);

		// create the label and input field for the private key password
		JLabel passLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.password"));
		passLabel.setOpaque(false);
		passwordFieldSc = new JPasswordField();
		passwordFieldSc.addCaretListener(this);

		// create the label and input field for the private key password
		messageLabelSc = new JLabel(Translatrix.getTranslationString("esante.loginDialog.initializingSmartCard"));
		messageLabelSc.setOpaque(false);
		
		sessionExpired = new JLabel(Translatrix.getTranslationString("esante.loginDialog.sessionExpired"));
		sessionExpired.setOpaque(false);
		
		// build the tab content
		smartCardLoginPanel.add(iconLabelSc, cc.xywh(2, 2, 1, 3, CellConstraints.CENTER, CellConstraints.CENTER));
		smartCardLoginPanel.add(sessionExpired, cc.xywh(4, 2, 3, 1, CellConstraints.CENTER, CellConstraints.CENTER));		
		smartCardLoginPanel.add(smartCardOwnerLabel, cc.xy(4, 4));
		smartCardLoginPanel.add(this.smartCardOwner, cc.xy(6, 4));
		smartCardLoginPanel.add(smartCardIdLabel, cc.xy(4, 6));
		smartCardLoginPanel.add(this.smartCardId, cc.xy(6, 6));
		smartCardLoginPanel.add(passLabel, cc.xy(4, 8));
		smartCardLoginPanel.add(passwordFieldSc, cc.xy(6, 8));
		smartCardLoginPanel.add(messageLabelSc, cc.xywh(4, 10, 3, 1, CellConstraints.CENTER, CellConstraints.CENTER));
		return smartCardLoginPanel;
	}
	
	
	private JPanel createLTMWDownloadTab ()
	{
		CellConstraints	cc	= new CellConstraints();
		JPanel			panel;
		JLabel			descriptionLabel;
		JLinkButton		downloadButton;
		
		
		descriptionLabel= new JLabel(Translatrix.getTranslationString("<html>"
				+ "Download and install the LuxTrust Middleware and restart<br>"
				+ "your Computer.<br>"
				+ "Afterwards you shall be able to use your LuxTrust card.<br>"
				+ "</html>"));
		
		downloadButton	= new JLinkButton(new AbstractAction(Translatrix.getTranslationString("Download LuxTrust Middleware"))
		{
			private static final long	serialVersionUID	= 1L;

			public void actionPerformed (ActionEvent e)
			{
				ESanteGuiUtils.openLuxtrustMiddlewareDownloadPage();
			}
		});
		downloadButton.setForeground(Color.BLUE);
		
		panel		= new JPanel(new FormLayout(
				// columns
				" 5px, f:p:g, 5px",
				// rows
				" 5px,f:p:g, " + 
				"15px,f:p," +
				" 5px"));
		
		panel.add(descriptionLabel,	cc.xy(2, 2));
		panel.add(downloadButton,	cc.xy(2, 4));
		
		panel.setOpaque(false);
		
		return panel;
	}
	
	
	public void showRequestSmartcardMessage(boolean showMessage){
		if(showMessage){
			messageLabelSc.setText(Translatrix.getTranslationString("esante.loginDialog.insertSmartCard"));
		} else {
			messageLabelSc.setText("");
		}
	}
	
	public void showInitializeSmartcardMessage(boolean showMessage){
		if(showMessage){
			messageLabelSc.setText(Translatrix.getTranslationString("esante.loginDialog.initializingSmartCard"));
		} else {
			messageLabelSc.setText("");
		}
	}
	public void showSmartcardNotReadableMessage(boolean showMessage){
		if(showMessage){
			messageLabelSc.setText(Translatrix.getTranslationString("esante.loginDialog.SmartCardNotReadable"));
		} else {
			messageLabelSc.setText("");
		}
	}
	
	/**
	 * Creates a tab that allows the user to login via a username and password
	 * 
	 * @return The username/password login tab
	 
	private JPanel createUserPassLoginTab() {
		JPanel userPassLoginPanel = new JPanel();
		CellConstraints cc = new CellConstraints();
		userPassLoginPanel.setLayout(new FormLayout(
		// column definition
				"15px, f:p, 15px, f:p, 10px, f:d:g, 15px",
				// row definition
				"15px,f:p," + // physician login
//				" 5px,f:p," + // physician id
				" 5px,f:p," + // physician password
				"15px:g"));
		userPassLoginPanel.setOpaque(false);

		// create icon for the username/password authentication
		JLabel iconLabel = new JLabel(ESanteGuiUtils.getIcon(IconNames.ESANTE_LOGO_SQUARE, ESanteGuiUtils.LARGEPIX));
		iconLabel.setOpaque(false);

		// create the label and input field for the login name
		JLabel loginLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.login"));
		loginLabel.setOpaque(false);
//		loginFieldUp = new JTextField();
//		loginFieldUp.addCaretListener(this);
//		if (loginDoc == null) {
//			loginDoc = loginFieldUp.getDocument();
//		} else {
//			loginFieldUp.setDocument(loginDoc);
//		}
		// create the label and input field for the user token
//		JLabel idLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.id"));
//		idLabel.setOpaque(false);
//		idFieldUp = new JTextField();
//		idFieldUp.addCaretListener(this);
//		if (idDoc == null) {
//			idDoc = idFieldUp.getDocument();
//		} else {
//			idFieldUp.setDocument(idDoc);
//		}
		// create the label and input field for the private key password
		JLabel passLabel = new JLabel(Translatrix.getTranslationString("esante.loginDialog.password"));
		passLabel.setOpaque(false);
		passwordFieldUp = new JPasswordField();
		passwordFieldUp.addCaretListener(this);

		// build the tab content
		userPassLoginPanel.add(iconLabel, cc.xywh(2, 2, 1, 3, CellConstraints.CENTER, CellConstraints.CENTER));
		userPassLoginPanel.add(loginLabel, cc.xy(4, 2));
		userPassLoginPanel.add(loginFieldUp, cc.xy(6, 2));
//		userPassLoginPanel.add(idLabel, cc.xy(4, 4));
//		userPassLoginPanel.add(idFieldUp, cc.xy(6, 4));
		userPassLoginPanel.add(passLabel, cc.xy(4, 4));
		userPassLoginPanel.add(passwordFieldUp, cc.xy(6, 4));

		return userPassLoginPanel;
	}
*/

	/**
	 * Indicates which login method has been chosen by the user
	 * 
	 * @return The chosen login method (either {@link #LOGIN_SMARTCARD}, {@link #LOGIN_USERNAME_PASSWORD}, or {@link #LOGIN_SIGNING_SERVER})
	 */
	public int getLoginMethod() {
		if (tabbedPane.getSelectedComponent() == smartCardLoginPanel) {
			return Configuration.LOGIN_SMARTCARD;
		}
//		if (tabbedPane.getSelectedComponent() == userPassLoginPanel) {
//			return Configuration.LOGIN_USERNAME_PASSWORD;
//		}
		return Configuration.LOGIN_SIGNING_SERVER;
	}

	/**
	 * Brings the tab that correspond to the provided login method to front
	 * 
	 * @param loginMethod
	 *            The desired login method (either {@link #LOGIN_SMARTCARD}, {@link #LOGIN_USERNAME_PASSWORD}, or {@link #LOGIN_SIGNING_SERVER})
	 */
	public void activateTab(int loginMethod) {
		if (loginMethod == Configuration.LOGIN_SMARTCARD) {
			tabbedPane.setSelectedComponent(smartCardLoginPanel);
		} else if (loginMethod == Configuration.LOGIN_USERNAME_PASSWORD) {
//			tabbedPane.setSelectedComponent(userPassLoginPanel);
		} else if (loginMethod == Configuration.LOGIN_SIGNING_SERVER) {
			// not yet implemented
			// tabbedPane.setSelectedComponent(signingServerLoginPanel);
		}
	}
	

	/* ======================================== */
	// GETTER & SETTER
	/* ======================================== */

	/**
	 * Provides a reference to the smartcard panel
	 * @return the smartcard panel
	 */
	public JPanel getSmartCardTab(){
		return smartCardLoginPanel;
	}

	/**
	 * sets the name of the owner of the smartcard in the login tab
	 * @param ownerName The name of the owner of the smartcard
	 */
	public void setOwnerName(String ownerName){
		smartCardOwner.setText(ownerName);
	}
	
	/**
	 * sets the serial number of the smartcard in the login tab
	 * @param serialNumber The serial number of the smartcard
	 */
	public void setSerialNumber(String serialNumber){
		smartCardId.setText(serialNumber);
	}
	
	/**
	 * Provides the login name that has been entered by the user
	 * 
	 * @return The login name or null if the login method is {@link #LOGIN_SMARTCARD}
	 */
	public String getLogin() {
//		if (getLoginMethod() != Configuration.LOGIN_SMARTCARD) {
//			// there is no login name for smartcards
//			return loginFieldUp.getText();
//		} else {
			return smartCardOwner.getText();
//		}
	}

//	public void setLogin(String login) {
//		this.loginFieldUp.setText(login);
//	}

//	/**
//	 * Provides the nonce (or id - which is actually the same) that has been entered by the user
//	 * 
//	 * @return The nonce or null if the login method is {@link #LOGIN_SMARTCARD}
//	 */
//	public String getId() {
//		String content = null;
//		// there is no id/nonce for smartcards
//		if (getLoginMethod() != Configuration.LOGIN_SMARTCARD) {
//			try {
//				content = idDoc.getText(0, idDoc.getLength());
//			} catch (BadLocationException e) {
//				;
//			}
//		} else{
//			content = smartCardId.getText();
//		}
//
//		return content;
//	}
	
	
	/**
	 * @return The smart card ID of the LuxTrust card or <code>null</code> 
	 * if smart card is not chosen as login method.
	 */
	public String getSmartCardId ()
	{
		if (getLoginMethod() == Configuration.LOGIN_SMARTCARD)
			return smartCardId.getText();
		else
			return null;
	}
	
	@Override
	public void setVisible(boolean b)
	{
		if(b){
			// coordination of the info message for the user in case of an expired session
			sessionExpired.setVisible(LoginDialog.displayExpirationMessage);
		}
		
		super.setVisible(b);
	}
	
	/**
	 * @return The reference to get the corresponding eHealth ID.
	 */
	public String getEHealthIdReference ()
	{
		switch (getLoginMethod())
		{
			case Configuration.LOGIN_SMARTCARD:
				
				return smartCardId.getText();
			
			case Configuration.LOGIN_USERNAME_PASSWORD:
				
//				return loginFieldUp.getText();
				
			default:
				logger.warn("login method not found. Couldn't return the correct eHealth ID reference.");
				return null;
		}
	}
	

//	public void setId(String id) {
//		this.idFieldUp.setText(id);
//	}

	/**
	 * Provides the password that has been entered by the user
	 * 
	 * @return The user password
	 */
	public String getPassword() {

//		if (getLoginMethod() == Configuration.LOGIN_SMARTCARD) {
			return passwordFieldSc.getText();
//		} else {
//			return passwordFieldUp.getText();
//		}
	}

//	public void setPassword(String password) {
//		this.passwordFieldUp.setText(password);
//	}

	/* ======================================== */
	// CLASS BODY
	/* ======================================== */

	public static Configuration getConfiguration() throws SendingStoppedException, Exception {
		
		if (loginConfig == null) {
			
			// put it in a thread and show the connecting dialog, while it is operating
			Configuration		config		= Configuration.getFilledConfiguration();
			ConnectingDialog	conDialog	= new ConnectingDialog("esante.loginDialog.waitTitle", "esante.loginDialog.waitMessage");
			ConfigurationLoader	loader		= new ConfigurationLoader(conDialog);
			LoginDialog			dialog;
			
			
			// start collecting information and show the wait dialog
			loader.start();
			int option = conDialog.showCenteredDialog();
			
			if (option != ConnectingDialog.OK_OPTION)
			{
				loader.cancel();
				try
				{
					loader.join(5000);
					if (loader.isAlive())
						loader.interrupt();
				}
				catch (InterruptedException e)
				{
					// it may happen, that the thread already died. No need to panic.
				}
			}
			
			if (loader.getException() != null)
				throw loader.getException();
			
			if (loader.wasCanceled())
				throw new SendingStoppedException(true);
			
			// show the dialog
			dialog	= loader.loginDialog;
			dialog.pack();
			dialog.centerWindowOnOwner();
			dialog.setVisible(true);

			// watchdog must be stopped
			getWatchDog().stopLoginMonitor();
			
			if (dialog.getButtonOption() != OK_OPTION) {
				LoginDialog.displayExpirationMessage(false);
				throw new SendingStoppedException(true);
			}
			
			loginConfig = config;
			loginConfig.setLoginMethod(dialog.getLoginMethod());
			loginConfig.setLogin(dialog.getLogin());
			loginConfig.setAuthorId(dialog.getEHealthIdReference());
			loginConfig.setClearPassword(dialog.getPassword());

			// never ever save the luxtrust card password to db
			if (loginConfig.getLoginMethod() != Configuration.LOGIN_SMARTCARD) {
				
				ESanteConfigManagerBean.getInstance().setUserProperty(
						ESanteProperty.PROP_PHYSICIAN_LOGIN_DATA,
						new StringBuilder().append(loginConfig.getLogin()).append("\n").append(loginConfig.getAuthorId()).toString(), GECAMedModule.getCurrentUser().getId());
//							new StringBuilder().append(loginConfig.getLogin()).append("\n").append(loginConfig.getAuthorId()).append("\n")
//							.append("").toString(), GECAMedModule.getCurrentUser().getId());
			}
			
			// initialize the ssl manager with the keystore and disarm the truststore (accept all kind of server certificates)
			SSLManager.reset();
		//	loginConfig.setSocketFactory(SSLManager.initSSL(dialog.getKeystorePath(), dialog.getPassword()));
			// for the time being it is ok using the default socket factory. If local certificates should be supported in the future, this has to be changed to the code line above
			loginConfig.setSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
		}

		return loginConfig;
	}

	/**
	 * Sends the login configuration object to the garbage collector. The next time, the configuration object is requested, the user has to fill the login
	 * dialog again.
	 */
	public static void resetConfiguration() {
		loginConfig = null;
	}
	
	/**
	 * Shows an information popup to inform the user about invalid user login information and resets the configuration data
	 */
	public static void incorrectLoginData() {
		UserInactivityMonitor.logout();
//		LoginDialog.resetConfiguration();
		ESanteDialog.showMessageDialog(MainFrame.getInstance(), 
				Translatrix.getTranslationString("esante.loginDialog.incorrectLoginTitle"),
				Translatrix.getTranslationString("esante.loginDialog.incorrectLoginMessage"), 
				GECAMedBaseDialogImpl.OK_BUTTON_MODE,
				GECAMedModule.getBigIcon(GECAMedIconNames.WARNING));
	}

	@Override
	public void prepareToShowUp() {
		evaluate();
		setFocus();
		super.prepareToShowUp();
	}

	public void caretUpdate(CaretEvent e) {
		evaluate();
	}

	/**
	 * Is called when another tab has been activated. It checks which input field should get focus and if the ok button should be enabled
	 */
	public void stateChanged(ChangeEvent e) {
		setFocus();
		evaluate();
	}

	private void setFocus() {
		if (getLoginMethod() == Configuration.LOGIN_SMARTCARD) {
			passwordFieldSc.requestFocus();
		} 
//		else {
//			if (loginFieldUp.getText().trim().length() == 0) {
//				loginFieldUp.requestFocus();
////			} else if (idFieldUp.getText().trim().length() == 0) {
////				idFieldUp.requestFocus();
//			} else {
//				passwordFieldUp.requestFocus();
//			}
//		}
	}
	
	public static UserInactivityMonitor getWatchDog ()
	{
		if (watchdog == null)
			watchdog	= Security.getInactivityMonitor();
		
		return watchdog;
	}

	public void evaluate() {

		if (getLoginMethod() == Configuration.LOGIN_SMARTCARD) {
			okButton.setEnabled((getLoginMethod() == Configuration.LOGIN_SMARTCARD) && (smartCardId.getText().length() > 0)
					&& (getPassword().trim().length() > 0));
		} else {
			okButton.setEnabled((getLogin().trim().length() > 0) && (getPassword().trim().length() > 0));
		}
	}
	
	/**
	 * Determines if an info message should be shown that informs the user that his session has expired
	 * 
	 * @param displayMessage
	 *            flag that indicates if the message should be shown
	 */
	public static void displayExpirationMessage(boolean displayMessage) {
		LoginDialog.displayExpirationMessage = displayMessage;
	}
	
	private static class ConfigurationLoader extends Thread
	{
		/* ======================================== */
		// MEMBERS
		/* ======================================== */
		
		private boolean				keepRunning	= true;
		
		private ConnectingDialog	connectingDialog;
		
		private LoginDialog			loginDialog;
		
		private Exception			exception;
		
		
		
		/* ======================================== */
		// CONSTRUCTOR
		/* ======================================== */
		
		public ConfigurationLoader (ConnectingDialog connectingDialog)
		{
			this.connectingDialog	= connectingDialog;
		}
		
		
		
		/* ======================================== */
		// CLASS BODY
		/* ======================================== */
		
		@Override
		public void run ()
		{
			try
			{
//				String loginProperties = ESanteConfigManagerBean.getInstance().getUserProperty(
//						ESanteProperty.PROP_PHYSICIAN_LOGIN_DATA, GECAMedModule.getCurrentUser().getId());
				
				if (loginDialog == null)
					loginDialog	= new LoginDialog();
				
				if (!keepRunning)
					return;
				
//				if (loginProperties != null)
//				{
////					String[] loginInfo = loginProperties.split("\n");
//					
//					// set the login information as far as known
//					if (loginInfo.length > 0)
//						loginDialog.setLogin(loginInfo[0]);
//					if (loginInfo.length > 1)
//						loginDialog.setId(loginInfo[1]);
	//				if (loginInfo.length > 2)
	//					LoginDialog.this.setPassword(loginInfo[2]);
					
//				}
				
				String[] loginInfo = Security.getInactivityMonitor().getOwnerIdentification();
					if (loginInfo != null)
					{
						loginDialog.setOwnerName(loginInfo[0]);
						loginDialog.setSerialNumber(loginInfo[1]);
					}

				
				if (!keepRunning)
					return;
				
				// for the time being the username password tab will activated by default
//				loginDialog.activateTab(Configuration.LOGIN_USERNAME_PASSWORD);
				// start watchdog to monitor smartcard availability
				if (getWatchDog().isLuxTrustDriverInstalled())
				{
					getWatchDog().startLoginMonitor(loginDialog);
				}
				
				if (!keepRunning)
					return;
			}
			catch (Exception e)
			{
				this.exception	= e;
			}
			finally
			{
				// wait for the dialog to be open
				while (keepRunning && !connectingDialog.isVisible())
				{
					try
					{
						Thread.sleep(100);
					}
					catch (Exception e) {}
				}
				connectingDialog.okActionCalled();
			}
		}
		
		
		public boolean wasCanceled ()
		{
			return !keepRunning;
		}
		
		
		public void cancel ()
		{
			keepRunning = false;
		}
		
		
		public Exception getException ()
		{
			return exception;
		}
		
	}
}
