/*****************************************************************************
 *                                                                           *
 *  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.patient.gui.medLogin;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.ExternalPasswordStore;
import lu.tudor.santec.gecamed.core.ejb.session.beans.ExternalPasswordStoreBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.ExternalPasswordStoreInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser;
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;

/**
 * Panel to enter the settings (physician and the token) for MedLogin.
 *  
 * @author Thorsten Roth thorsten.roth(at)tudor.lu
 *
 * @version
 * <br>$Log: MedLoginInitPanel.java,v $
 * <br>Revision 1.14  2013-12-27 18:09:26  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.13  2013-07-15 06:18:37  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.12  2013-02-19 12:07:34  ferring
 * <br>GECAMedLists changed. Will now automatically load list of all beans
 * <br>
 * <br>Revision 1.11  2012-08-07 14:00:18  troth
 * <br>Add function to allow users to delete the login informations in the new table external password store.
 * <br>
 * <br>Revision 1.10  2012-08-06 14:52:27  troth
 * <br>change logger.
 * <br>
 * <br>Revision 1.9  2012-08-06 14:09:57  troth
 * <br>Now the MedLogin service stores the tokens of the users in the new table external password store.
 * <br>
 * <br>Revision 1.8  2012-08-06 14:04:04  troth
 * <br>Now the MedLogin service stores the tokens of the users in the new table external password store.
 * <br>
 * <br>Revision 1.7  2012-08-02 16:14:15  troth
 * <br>Add new table to database for external password store (for MedLogin and other Services).
 * <br>
 * <br>Revision 1.6  2012-08-01 15:38:02  troth
 * <br>Remove token and password saving in the database for MedLogin and CyberLab. Now the token and password is only save for one GECAMed session.
 * <br>
 * <br>Revision 1.5  2012-03-06 16:21:14  troth
 * <br>Finish the new function of the MedLogin Button.
 * <br>
 * <br>Revision 1.4  2012-03-05 16:44:25  troth
 * <br>First version of the MedLogin Button.
 * <br>
 * <br>Revision 1.3  2012-03-05 10:35:57  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.2  2012-03-05 09:55:06  troth
 * <br>Test: Open browser over java desktop API.
 * <br>
 * <br>Revision 1.1  2012-02-23 17:06:45  troth
 * <br>Add new dialog to edit the MedLogin physician settings.
 * <br>
 */
public class MedLoginInitPanel extends JPanel{

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

	/**
	 * Need GUI Components
	 */
	// Logo & Icon
	private JLabel logoLabel;
	
	private Icon icon;
	
	// Token
	private JLabel tokenLabel;

	private JPasswordField tokenField;

	// Physician
	private JLabel physicianLabel;

	private JComboBox physicianBox;
	
	private Boolean enableComboboxActionListener = true;
		
	// Ordernumber
	private JLabel numberLabel;

	private JTextField numberField;

	// Save password in database
	private JCheckBox savePasswordCheckBox;
	
	private Boolean savePassword = false;
	
	private ExternalPasswordStore currentPassword;
	
	private static String passwordType = "MedLogin";
	
	private static String passwordKey = "Token";
	
	/**
	 * Needed Objects 
	 */
	private Physician currentPhysician;
	
	private Patient currentPatient;

	private GecamedUser currentUser;

	/**
	 * Needed beans
	 */

	private static ExternalPasswordStoreInterface passwordManager;
	
	/**
	 * Initialize all needed beans
	 */
	static
	{
		try{
			passwordManager = (ExternalPasswordStoreInterface) ManagerFactory.getRemote(ExternalPasswordStoreBean.class);
		} catch (Exception e) {
			logger.log(Level.WARN, "Couldn't get connection with ExternalPasswordStoreBean.", e);
		}
	}
	
	/**
	 * The Constructor init all GUI Components. There are two layouts one for the user with permission for MedLogin and one for the user without this permission.
	 */
	public MedLoginInitPanel()
	{
		if(
				PatientManagerModule.getCurrentUser().getPhysicians().size() > 0
				|| GECAMedModule.userHasPermission("Core.changePhysician")
//				|| GECAMedModule.userHasRole("PatientModule", "physician")
		)
		{
			// -------------------------------------------------------
			// The panel layout (FormLayout) (User with permissions)
			// -------------------------------------------------------
			CellConstraints cc = new CellConstraints();
			this.setLayout(new FormLayout(
					// cols
					"10dlu," +			// 1
					"fill:pref," + 		// 2 left
					"3dlu," +			// 3
					"fill:pref," + 		// 4 right
					"10dlu",			// 5
					// rows
					"10dlu," +			// 1
					"fill:pref," +		// 2 logo
					"6dlu," +			// 3
					"fill:pref," +		// 4 physician
					"6dlu," +			// 5
					"fill:pref," +		// 6 token
					"6dlu," +			// 7
					"fill:pref," +		// 8 number
					"10dlu," +			// 9
					"fill:pref," +		// 10 checkbox savepassword 
					"10dlu"				// 11
					));
			this.setOpaque(false);
			
			// -------------------------------------------------------
			// logo
			// -------------------------------------------------------
			icon = new ImageIcon(IconFetcher.getIcon(PatientManagerModule.class, PatientManagerModule.MEDLOGIN).getImage());
			this.logoLabel = new JLabel(icon);
	
			// -------------------------------------------------------
			// physician
			// -------------------------------------------------------
			this.physicianLabel = new JLabel(Translatrix.getTranslationString("medLogin.physicianLabel") + " :");
			this.physicianLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
			this.physicianBox = new JComboBox();
			
			// init physician select box
			refreshPhysicianBox();
			
			// add listener to physician select box
			this.physicianBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (enableComboboxActionListener) 
					{
						currentUser = PatientManagerModule.getCurrentUser();
						currentPhysician = ((Physician) physicianBox.getSelectedItem());
						try {
							currentPassword = passwordManager.getPassword(currentPhysician.getId(), passwordType, passwordKey);
							if(currentPassword != null)
							{
								tokenField.setText(currentPassword.getValue());
								savePassword = true;
							}else{
								tokenField.setText("");
								savePassword = false;
								currentPassword = new ExternalPasswordStore();
								currentPassword.setUserId(currentUser.getId());
								currentPassword.setPhysicianId(currentPhysician.getId());
								currentPassword.setType(passwordType);
								currentPassword.setKey(passwordKey);
							}
							savePasswordCheckBox.setSelected(savePassword);
							
						} catch (Exception e1) {
							logger.log(Level.WARN, "Couldn't load password from database table core.external_password_store.", e1);
							e1.printStackTrace();
						}
						if(PatientManagerModule.getCurrentUser().getPhysicians().contains(currentPhysician))
						{
							tokenField.setEnabled(true);
							savePasswordCheckBox.setEnabled(true);
						}else{
							tokenField.setEnabled(false);
							savePasswordCheckBox.setEnabled(false);
						}
					}
				}
			});
			
			// -------------------------------------------------------
			// token
			// -------------------------------------------------------
			this.tokenLabel = new JLabel(Translatrix.getTranslationString("medLogin.tokenLabel") + " :");
			this.tokenLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
			this.tokenField = new JPasswordField(40);
			this.tokenField.setToolTipText(Translatrix.getTranslationString("medLogin.tokenTooltip"));
			
			// -------------------------------------------------------
			// order number
			// -------------------------------------------------------
			this.numberLabel = new JLabel(Translatrix.getTranslationString("medLogin.orderNumberLabel") + " :");
			this.numberLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
			this.numberField = new JTextField(40);
			this.numberField.setToolTipText(Translatrix.getTranslationString("medLogin.orderNumberTooltip"));
			
			// -------------------------------------------------------
			// save password check box
			// -------------------------------------------------------
			this.savePasswordCheckBox = new JCheckBox(Translatrix.getTranslationString("medLogin.savePasswordLabel"));
			this.savePasswordCheckBox.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent e)
				{
					if(savePassword) savePassword = false;
					else savePassword = true;
				}
			});
			
			// -------------------------------------------------------
			// add components to panel
			// -------------------------------------------------------
			this.add(this.logoLabel, cc.xyw		(2, 2, 3));
			this.add(this.physicianLabel, cc.xy	(2, 4));
			this.add(this.physicianBox, cc.xy	(4, 4));
			this.add(this.tokenLabel, cc.xy		(2, 6));
			this.add(this.tokenField, cc.xy		(4, 6));
			this.add(this.numberLabel, cc.xy	(2, 8));
			this.add(this.numberField, cc.xy	(4, 8));
			this.add(this.savePasswordCheckBox, cc.xyw(2, 10, 3));
			
			// get current user 
			currentUser = PatientManagerModule.getCurrentUser();
			// get current physician
			currentPhysician = PatientManagerModule.getCurrentPhysician();
			this.enableComboboxActionListener = false;
			this.physicianBox.setSelectedItem(currentPhysician);
			this.enableComboboxActionListener = true;
			// set token
			try {
				currentPassword = passwordManager.getPassword(currentPhysician.getId() ,passwordType ,passwordKey);
				if(currentPassword != null)
				{
					this.tokenField.setText(currentPassword.getValue());
					savePassword = true;
				}else{
					this.tokenField.setText("");
					savePassword = false;
					currentPassword = new ExternalPasswordStore();
					currentPassword.setUserId(currentUser.getId());
					currentPassword.setPhysicianId(currentPhysician.getId());
					currentPassword.setType(passwordType);
					currentPassword.setKey(passwordKey);
				}
				
			} catch (Exception e1) {
				logger.log(Level.WARN, "Couldn't load password from database table core.external_password_store.", e1);
				e1.printStackTrace();
			}
			if(PatientManagerModule.getCurrentUser().getPhysicians().contains(currentPhysician))
			{
				tokenField.setEnabled(true);
				savePasswordCheckBox.setEnabled(true);
			}else{
				tokenField.setEnabled(false);
				savePasswordCheckBox.setEnabled(false);
			}
			
			// set current patient
			currentPatient = PatientManagerModule.getCurrentPatient();
			
			// set save password check box
			this.savePasswordCheckBox.setSelected(savePassword);
		}else{
			// -------------------------------------------------------
			// laylout if user have no permissions
			// -------------------------------------------------------
			CellConstraints cc = new CellConstraints();
			this.setLayout(new FormLayout(
					// cols
					"10dlu," +			// 1
					"fill:pref," + 		// 2 center
					"10dlu",			// 5
					// rows
					"10dlu," +			// 1
					"fill:pref," +		// 2 logo
					"6dlu," +			// 3
					"fill:pref," +		// 4 message
					"10dlu"				// 9
					));
			this.setOpaque(false);
			
			// -------------------------------------------------------
			// logo
			// -------------------------------------------------------
			icon = new ImageIcon(IconFetcher.getIcon(PatientManagerModule.class, PatientManagerModule.MEDLOGIN).getImage());
			this.logoLabel = new JLabel(icon);
			
			// -------------------------------------------------------
			// message label
			// -------------------------------------------------------
			this.numberLabel = new JLabel(Translatrix.getTranslationString("medLogin.accessDenied"));
			this.numberLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
						
			// -------------------------------------------------------
			// add components to panel
			// -------------------------------------------------------
			this.add(this.logoLabel, cc.xy		(2, 2));
			this.add(this.numberLabel, cc.xy	(2, 4));
		}
			
	}

	public JTextField getTokenField()
	{
		return tokenField;
	}

	public void setTokenField(JPasswordField tokenField)
	{
		this.tokenField = tokenField;
	}
	
	/**
	 * Save the token of the selected physician or delete it if savePassword is false (flag from the checkbox).
	 */
	public void updateToken()
	{
		if(savePassword)
		{
			currentPassword.setValue(new String(this.tokenField.getPassword()));
			try {
				currentPassword = passwordManager.savePassword(currentPassword);
			} catch (Exception e) {
				logger.log(Level.WARN, "Couldn't save password in database table core.external_password_store.", e);
			}
		}else{
			try {
				passwordManager.deletePassword(currentPassword);
				currentPassword = null;
			} catch (Exception e) {
				logger.log(Level.WARN, "Couldn't delete password in database table core.external_password_store.", e);
			}
		}
//		PatientPanel.setMedLoginToken(password.getPassword());
//		try {
//			officeManager.savePhysician(currentPhysician);
//		} catch (Exception e) {
//			logger.log(Level.WARN, "Couldn't save Physician.", e);
//			e.printStackTrace();
//		}
	}

	/**
	 * Create and returns a string url to the Medlogin website with all parameters given from the dialog.
	 * @return a string url to the Medlogin website
	 */
	public String getURL()
	{
		// create MedLogin-URL
		String medLoginURL = "https://medlogin.labo.lu/include/myresults/historie.php?prog=gecamed-4-me"; // host + progcode
		// set docid | &docid=555555
		medLoginURL = medLoginURL + "&docid=" + currentPhysician.getUcmCode().substring(0, 6);
		// set patient matricule | &ma=19631224000
		if(currentPatient != null)
			if(!currentPatient.getSocialSecurityNumber().equals("00000000000"))
			{
				medLoginURL = medLoginURL + "&ma=" + currentPatient.getSocialSecurityNumber();
			}
		
		// set order number | &oid=1112140001
		if(!this.numberField.getText().equals(""))
		{
			medLoginURL = medLoginURL + "&oid=" + numberField.getText().trim();
		}
			
		// set token | &token=rc4rAa65zN2NJVYszfLL6oeLR7mZRtKZodfFXCjvq3gYnWoC@R
		if(!new String(this.tokenField.getPassword()).equals(""))
		{
			medLoginURL = medLoginURL + "&token=" + new String(this.tokenField.getPassword()).trim();
		}
		return medLoginURL;
	}
	
	/**
	 * Refresh the physician combobox.
	 */
	private void refreshPhysicianBox() {
		// get physician from GECAMedLists
		List<Physician> physicianList = GECAMedLists.getListReference(Physician.class);
		
		this.enableComboboxActionListener = false;
		this.physicianBox.removeAllItems();

		if (physicianList.size() > 0)
			for (Physician physician : physicianList)
			{
				// if user hat the permission to change physician add all physician
				if(GECAMedModule.userHasPermission("Core.changePhysician"))
					this.physicianBox.addItem(physician);
				// else add only the physician which are related to the user
				else
					if(PatientManagerModule.getCurrentUser().getPhysicians().contains(physician))
						this.physicianBox.addItem(physician);
			}
		this.enableComboboxActionListener = true;
	}
}