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

import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.TextAttribute;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.GECAMedTab;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.DefaultComboBoxRenderer;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.core.gui.widgets.ErrorDialog;
import lu.tudor.santec.gecamed.core.utils.GECAMedUtils;
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.ejb.session.interfaces.ESanteConfigManager;
import lu.tudor.santec.gecamed.esante.gui.dialogs.EHealthIdEditDialog;
import lu.tudor.santec.gecamed.esante.gui.webservice.SOAPUtilities;
import lu.tudor.santec.gecamed.esante.gui.webservice.WebserviceConstants;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

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

/**
 * @author Thorsten Roth thorsten.roth(at)tudor.lu
 *
 * @version
 * <br>$Log: ESanteManagementPanel.java,v $
 * <br>Revision 1.11  2014-02-04 10:08:44  ferring
 * <br>eSante ID management completed
 * <br>Only those documents will be shown, that are retrieved by the RSQ
 * <br>
 * <br>Revision 1.10  2014-01-30 12:54:12  ferring
 * <br>URLs only editable with double click
 * <br>
 * <br>Revision 1.9  2014-01-29 16:57:51  donak
 * <br>Renamed references to HPD to eHealth in respect to the request of the eHealth Agency
 * <br>Removed template DSP-11-12 as it is not needed and was created only for internal testing purposes
 * <br>
 * <br>Revision 1.8  2014-01-28 16:02:44  ferring
 * <br>eHealth ID management implemented
 * <br>
 * <br>Revision 1.7  2014-01-22 14:40:40  ferring
 * <br>inactivity timeout is now represented as JSlider
 * <br>
 * <br>Revision 1.6  2014-01-21 14:32:05  ferring
 * <br>myDSP configuration can be changed and reloaded.
 * <br>The clean CDA files on server function was added
 * <br>
 * <br>Revision 1.5  2014-01-10 08:24:39  ferring
 * <br>text fields deactivated
 * <br>
 * <br>Revision 1.4  2014-01-06 13:14:05  ferring
 * <br>Option added to select the download site
 * <br>
 * <br>Revision 1.3  2013-12-27 18:09:27  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.2  2013-12-11 13:21:58  troth
 * <br>Admin tab for eSante.
 * <br>
 * <br>Revision 1.1  2013-12-10 16:40:15  troth
 * <br>Admin tab for eSante.
 * <br>
 */
public class ESanteManagementPanel extends GECAMedTab implements Relocalizable, DocumentListener, 
		PropertyChangeListener, ChangeListener, MouseListener, FocusListener, KeyListener, ItemListener
{
	/* ======================================== */
	// CONSTANTS
	/* ======================================== */
	
	private static final long serialVersionUID = 1L;
	
	private static final String CONNECTION_LABEL_TRANSLATRIX_PREFIX	= "esante.managementPanel.connection.";
	
	private static final String	PROPERTY_SEARCH_NAME				= "WSDL_%";
	
	
	
	/* ======================================== */
	// MEMBERS
	/* ======================================== */
	
	private JPanel					connectionPanel;
	private JPanel					objectIdPanel;
	private JPanel					preferencesPanel;
	
	private TitledBorder			connectionBorder;
	private TitledBorder			objectIdBorder;
	private TitledBorder			preferencesBorder;
	
	private JButton					saveButton;
	private JButton					reloadButton;
	private JButton					clearTemplateCacheButton;
	
//	private JButton					downloadSiteButton;
	
	// the text fields to save and update
	private Map<String, JTextField>	connectionFieldMap;
	
	private JTextField				gecamedAppIdField;
	private	JButton					eHealthIdsButton;
	
	private JSlider					inactivityTimeoutSlider;
	private JLabel					inactivityTimeoutLabel;
	private JLabel					epsosUrlLabel;
	private JTextField				epsosUrlField;
	private JCheckBox				showEpsosButtonBox;
	
	private String					editStartValue;
	private JComboBox<MessageLogLevel> messageLoglevelCB;

	private TitledBorder ooBorder;

	private JPanel ooPanel;

	private JButton installOOButton;

	private JLabel ooPathLabel;
	
	
	/* ======================================== */
	// CONSTRUCTORS
	/* ======================================== */
	
	public ESanteManagementPanel ()
	{
		CellConstraints	cc = new CellConstraints();;
		FormLayout		layout;
		
		this.setOpaque(false);
		
		// Tap title and icon
		this.setTitle(Translatrix.getTranslationString("esante.managementPanel.title"));
		this.setIcon(IconFetcher.getIcon(ESanteManagementPanel.class, "my_dsp_logo.png"));
		
		
		// Connection panel
		initConnectionPanel();
		
		// ObjectID panel
		initObjectIdPanel();
		
		// Preferences panel
		initPreferencesPanel();
		
		// OpenOffice Panel
		initOOPanel();
		
		saveButton		= new JButton(new AbstractAction("", GECAMedModule.getScaledIcon(GECAMedIconNames.SAVE, 32))
		{
			private static final long	serialVersionUID	= 1L;

			public void actionPerformed (ActionEvent e)
			{
				saveData();
			}
		});
		saveButton.setEnabled(false);
		
		reloadButton	= new JButton(new AbstractAction("", GECAMedModule.getScaledIcon(GECAMedIconNames.RELOAD, 32))
		{
			private static final long	serialVersionUID	= 1L;

			public void actionPerformed (ActionEvent e)
			{
				reload();
			}
		});
		
		clearTemplateCacheButton = new JButton(new AbstractAction(
				"", GECAMedModule.getScaledIcon(GECAMedIconNames.MESSAGE_DELETE, 32)) 
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) 
			{
				SOAPUtilities.clearTemplatesCache();
			}
		});
		clearTemplateCacheButton.setToolTipText("Clear template cache");
		
		JPanel	ioButtonPanel	= new JPanel(new FormLayout("f:40px", 
				"f:40px, 3dlu, f:40px, 10dlu, f:40px"));
		ioButtonPanel.setOpaque(false);
		ioButtonPanel.add(saveButton,				cc.xy(1, 1));
		ioButtonPanel.add(reloadButton,				cc.xy(1, 3));
		ioButtonPanel.add(clearTemplateCacheButton,	cc.xy(1, 5));
		
		layout = new FormLayout(
				"3dlu,f:50px:g, 20dlu, f:50px:g,3dlu, f:p,3dlu", 
				"3dlu,t:p, 20dlu, t:p, 3dlu, t:p, 3dlu");
		this.setLayout(layout);
		
		this.add(this.connectionPanel, 	cc.xyw (2, 2, 3));
		this.add(this.objectIdPanel, 	cc.xy  (2, 4));
		this.add(this.ooPanel, 			cc.xy  (2, 6));
		this.add(this.preferencesPanel,	cc.xywh  (4, 4, 1, 3));
		this.add(ioButtonPanel,			cc.xywh(6, 2, 1, 3));
		
		
		

		//Disable buttons if demo mode
		if (GECAMedUtils.isDemo() && !MainFrame.isAdmin()) {
		   	// disables all tabs
			saveButton.setEnabled(false);
			reloadButton.setEnabled(false);
			clearTemplateCacheButton.setEnabled(false);
			
		} else {
			// notify yourself, if something was modified
			addPropertyChangeListener(DATA_CHANGED, this);
			saveButton.setEnabled(true);
			reloadButton.setEnabled(true);
			clearTemplateCacheButton.setEnabled(true);
			
		}
	}
	
	
	
	/* ======================================== */
	// CLASS BODY
	/* ======================================== */
	
	@Override
	public void saveData ()
	{
		HashMap<String, String>	eSanteProperties	= new HashMap<String, String>();
		
		
		// save the generic connection URLs
		for (String key : connectionFieldMap.keySet())
			eSanteProperties.put(key, connectionFieldMap.get(key).getText().trim());
		
		// save the Object IDs
//		eSanteProperties.put(ESanteProperty.PROP_GECAMED_APPLICATION_ID,	gecamedAppIdField.getText().trim());
		
		// save the preferences
		eSanteProperties.put(ESanteProperty.PROP_INACTIVITY_TIMEOUT,		String.valueOf(inactivityTimeoutSlider.getValue()));
		eSanteProperties.put(ESanteProperty.PROP_EPSOS_URL,					epsosUrlField.getText().trim());
		eSanteProperties.put(ESanteProperty.PROP_SHOW_EPSOS_BUTTON,			String.valueOf(showEpsosButtonBox.isSelected()));
		
		ESanteConfigManagerBean.getInstance().setESanteProperties(eSanteProperties);
		setModified(false);
	}
	
	
	@Override
	public void reload ()
	{
		ESanteConfigManager	manager				= ESanteConfigManagerBean.getInstance();
		Map<String, String>	eSanteProperties	= manager.getESanteProperties(PROPERTY_SEARCH_NAME);
		String				value;
		
		
		// save the generic connection URLs
		for (String key : connectionFieldMap.keySet())
		{
			value	= eSanteProperties.get(key);
			if (value != null)
				connectionFieldMap.get(key).setText(value);
		}
		
		// save the Object IDs
//		gecamedAppIdField.setText(manager.getESanteProperty(ESanteProperty.PROP_GECAMED_APPLICATION_ID));
		
		// save the preferences
		try
		{
			inactivityTimeoutSlider.setValue(Integer.parseInt(manager.getESantePropertyValue(ESanteProperty.PROP_INACTIVITY_TIMEOUT)));
		}
		catch (NumberFormatException e)
		{
			inactivityTimeoutSlider.setValue(inactivityTimeoutSlider.getMinimum());
		}
		epsosUrlField.setText(manager.getESantePropertyValue(ESanteProperty.PROP_EPSOS_URL));
		
		value	= manager.getESantePropertyValue(ESanteProperty.PROP_SHOW_EPSOS_BUTTON);
		showEpsosButtonBox.setSelected(GECAMedUtils.isTrue(value, true));
		
		setModified(false);
	}
	
	
	public void relocalize ()
	{
		// not used, as it the connection parameter panel is build generically
	}
	
	
	/* ---------------------------------------- */
	// DOCUMENT LISTENER METHODS
	/* ---------------------------------------- */
	
	public void insertUpdate (DocumentEvent e)
	{
		setModified(true);
	}
	
	
	public void removeUpdate (DocumentEvent e)
	{
		setModified(true);
	}
	
	
	public void changedUpdate (DocumentEvent e) {}
	
	
	/* ---------------------------------------- */
	// PROPERTY CHANGED LISTENER METHOD
	/* ---------------------------------------- */
	
	public void propertyChange (PropertyChangeEvent evt)
	{
		saveButton.setEnabled(isModified());
	}
	
	
	/* ---------------------------------------- */
	// CHANGE LISTENER METHOD
	/* ---------------------------------------- */
	
	public void stateChanged (ChangeEvent e)
	{
		if (!GECAMedUtils.isDemo() && MainFrame.isAdmin()) {
			setModified(true);
		}
		
		inactivityTimeoutLabel.setText(String.valueOf(inactivityTimeoutSlider.getValue()));
	}
	
	
	/* ---------------------------------------- */
	// MOUSE LISTENER METHODS
	/* ---------------------------------------- */
	
	public void mouseClicked (MouseEvent e)
	{
		if (e.getClickCount() >= 2
				&& e.getSource() instanceof JTextComponent)
		{
			JTextComponent c = (JTextComponent) e.getSource();
			c.setEditable(true);
			c.setCaretPosition(c.getText().length());
			c.getCaret().setVisible(true);
			editStartValue	= c.getText();
		}
	}
	
	
	public void mousePressed (MouseEvent e) {}
	public void mouseReleased (MouseEvent e) {}
	public void mouseEntered (MouseEvent e) {}
	public void mouseExited (MouseEvent e) {}
	
	
	/* ---------------------------------------- */
	// FOCUS LISTENER
	/* ---------------------------------------- */
	
	public void focusGained (FocusEvent e) {}
	
	
	public void focusLost (FocusEvent e)
	{
		editingStopped((JTextComponent) e.getSource());
	}
	
	
	/* ---------------------------------------- */
	// KEY LISTENER METHODS
	/* ---------------------------------------- */
	
	public void keyTyped (KeyEvent e) {}
	public void keyPressed (KeyEvent e) {}
	
	
	public void keyReleased (KeyEvent e) 
	{
		if (e.getSource() instanceof JTextComponent)
		{
			switch (e.getKeyCode())
			{
				case KeyEvent.VK_ESCAPE:
					
					((JTextComponent)e.getSource()).setText(editStartValue);
					
				case KeyEvent.VK_ENTER:
				case KeyEvent.VK_TAB:
					
					editingStopped((JTextComponent) e.getSource());
					break;
			}
		}
	}
	
	
	/* ---------------------------------------- */
	// ITEM LISTENER METHOD
	/* ---------------------------------------- */
	
	public void itemStateChanged(ItemEvent e) {
		if ((e.getStateChange() == ItemEvent.SELECTED) && ((e.getSource() == this.messageLoglevelCB))) {
			try {
				int level = ((MessageLogLevel) this.messageLoglevelCB.getSelectedItem()).getLogLevel();
				// and store it in the database for subsequent usage
				ESanteConfigManagerBean.getInstance().setESanteProperty(ESanteProperty.PROP_MESSAGE_LOGLEVEL,
						String.valueOf(level));
				// change the message log level immediately. That way, the user does not have to restart Gecamed for bringing it into affect
				SOAPUtilities.setMessageLogLevel(level);
			} catch (Exception ex1) {
			}
		} else {

			boolean b = showEpsosButtonBox.isSelected();

			epsosUrlLabel.setEnabled(b);
			epsosUrlField.setEditable(b);
			epsosUrlField.setEnabled(b);
		}
		if (!GECAMedUtils.isDemo() && MainFrame.isAdmin()) {
			setModified(true);
		}
	}
	
	
	
	/* ======================================== */
	// HELP METHODS
	/* ======================================== */
	
	/**
	 * Init the connection parameters panel.
	 */
	private void initConnectionPanel()
	{
		Map<String, String>	properties;
		JTextField		connectionUrlField;
		JLabel			label;
		FormLayout		formlayout		= new FormLayout("5px,f:p,10px,f:d:g,5px");
		RowSpec			emptyRow		= new RowSpec(Sizes.pixel(3));
		RowSpec			connectionRow	= new RowSpec(RowSpec.FILL, Sizes.PREFERRED, RowSpec.NO_GROW);
		CellConstraints	cc				= new CellConstraints();
		
		
		this.connectionBorder	= new TitledBorder (Translatrix.getTranslationString(
				"esante.managementPanel.connection.borderTitle"));
		this.connectionPanel	= new JPanel ();
		this.connectionPanel.setOpaque(false);
		this.connectionPanel.setBorder(connectionBorder);
		this.connectionPanel.setLayout(formlayout);
		
		
		properties	= ESanteConfigManagerBean.getInstance().getESanteProperties(PROPERTY_SEARCH_NAME);
		label		= new JLabel(Translatrix.getTranslationString("esante.managementPanel.connection.headline"));

    	formlayout.appendRow(emptyRow);
		formlayout.appendRow(connectionRow);
		connectionPanel.add(label, cc.xyw(2, formlayout.getRowCount(), 3));
		connectionFieldMap	= new HashMap<String, JTextField>();
		
		for (String key : new TreeSet<String>(properties.keySet()))
			// use the TreeSet to order it alphabetically
		{
	    	// a WSDL connection URL was found 
	    	connectionUrlField	= new JTextField(properties.get(key));
//	    	connectionUrlField.getDocument().addDocumentListener(this);
	    	connectionUrlField.setEditable(false);
	    	connectionUrlField.addMouseListener(this);
	    	connectionUrlField.addFocusListener(this);
	    	connectionUrlField.addKeyListener(this);
//	    	label				= new JLabel(Translatrix.getTranslationString(CONNECTION_LABEL_TRANSLATRIX_PREFIX + key));
	    	label				= new JLabel(key);
	    	label.setOpaque(false);
	    	
	    	formlayout.appendRow(emptyRow);
	    	formlayout.appendRow(connectionRow);
	    	connectionPanel.add(label,				cc.xy(2, formlayout.getRowCount()));
	    	connectionPanel.add(connectionUrlField,	cc.xy(4, formlayout.getRowCount()));
	    	connectionFieldMap.put(key, connectionUrlField);
		}
    	formlayout.appendRow(emptyRow);
	}
	
	/**
	 * Init the object id panel.
	 */
	private void initObjectIdPanel()
	{
		String			property;
		JLabel			label;
		int				row		= 0;
		CellConstraints	cc		= new CellConstraints();
		FormLayout		layout	= new FormLayout(
				// columns
				"5px,f:p, 10px, f:d:g,5px", 
				// rows
				" 5px,f:p," +	// GECAMed code
				" 5px,f:p," +	// eHealth ID management
				" 5px");
		
		
		this.objectIdBorder	= new TitledBorder (Translatrix.getTranslationString("esante.managementPanel.objectId.BorderTitle"));
		this.objectIdPanel	= new JPanel ();
		this.objectIdPanel.setOpaque(false);
		this.objectIdPanel.setLayout(layout);
		this.objectIdPanel.setBorder(objectIdBorder);
		
		// GECAMed code
		label				= new JLabel(Translatrix.getTranslationString("esante.managementPanel.objectId.oidGecamedApplicationCode"));
		property			= ESanteConfigManagerBean.getInstance().getESantePropertyValue(ESanteProperty.PROP_GECAMED_APPLICATION_ID);
		gecamedAppIdField	= new JTextField(property != null ? property : "");
//		gecamedAppIdField.getDocument().addDocumentListener(this);
		gecamedAppIdField.setEditable(false);
		
		this.objectIdPanel.add(label, 				cc.xy(2, row+=2));
		this.objectIdPanel.add(gecamedAppIdField,	cc.xy(4, row));
		
		// eHealth ID management
		eHealthIdsButton	= new JButton(new AbstractAction(
				Translatrix.getTranslationString("esante.managementPanel.objectId.manageEHealthIds"))
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed (ActionEvent e)
			{
				editEHealthIds();
			}
		});
		
		this.objectIdPanel.add(eHealthIdsButton,		cc.xyw(2, row+=2, 3));
	}
	
	
	/**
	 * Init the object id panel.
	 */
	private void initOOPanel()
	{
		int				row		= 0;
		CellConstraints	cc		= new CellConstraints();
		FormLayout		layout	= new FormLayout(
				// columns
				"5px,f:p, 10px, f:d:g,5px", 
				// rows
				" 5px,f:p," +
				" 5px,f:p," +
				" 5px,f:p," +
				" 5px");
		
		
		this.ooBorder	= new TitledBorder (Translatrix.getTranslationString("esante.managementPanel.oo.OOBorderTitle"));
		this.ooPanel	= new JPanel ();
		this.ooPanel.setOpaque(false);
		this.ooPanel.setLayout(layout);
		this.ooPanel.setBorder(ooBorder);
		
		
		JLabel pathLabel = new JLabel(Translatrix.getTranslationString("esante.managementPanel.oo.ooPath"));
		this.ooPanel.add(pathLabel, 				cc.xy(2, row+=2));
		
		String path = ESanteConfigManagerBean.getInstance().checkOpenOffice();
		if (path == null) path = Translatrix.getTranslationString("esante.managementPanel.oo.notInstalled");
		ooPathLabel = new JLabel(path);
	
		this.ooPanel.add(ooPathLabel, 				cc.xy(2, row+=2));

		
		// eHealth ID management
		installOOButton	= new JButton(new AbstractAction(
				Translatrix.getTranslationString("esante.managementPanel.oo.installOO"))
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed (ActionEvent e)
			{
				new Thread() {
					public void run() {
						try {
							MainFrame.getInstance().setWaitCursor(true);
							installOOButton.setEnabled(false);
							if (ESanteConfigManagerBean.getInstance().checkOpenOffice() != null) {
								if (JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(
										MainFrame.getInstance(),
										Translatrix.getTranslationString("esante.managementPanel.oo.ooExistsQuestion"),
									    Translatrix.getTranslationString("esante.managementPanel.oo.ooExists"),
									    JOptionPane.YES_NO_OPTION)) {
									return;
								}
							}
							
							ESanteConfigManagerBean.getInstance().installOpenOffice(true);		
							
							String path = ESanteConfigManagerBean.getInstance().checkOpenOffice();
							if (path == null) path = Translatrix.getTranslationString("esante.managementPanel.oo.notInstalled");
							ooPathLabel.setText(path);
							
						} catch (Exception e2) {
							ErrorDialog.showErrorDialog(MainFrame.getInstance(), 
									Translatrix.getTranslationString("esante.managementPanel.oo.errorOO"), 
									Translatrix.getTranslationString("esante.managementPanel.oo.errorOO") + " " + e2.getMessage(),
									e2);
						} finally {
							MainFrame.getInstance().setWaitCursor(false);
							installOOButton.setEnabled(true);
						}
					}
				}.start();
			}
		});
		
		if (GECAMedUtils.isDemo() && !MainFrame.isAdmin()) {
			installOOButton.setEnabled(false);
		}
		
		this.ooPanel.add(installOOButton, cc.xyw(2, row+=2, 3));
	}
	
	
	/**
	 * Init preference Panel
	 */
	private void initPreferencesPanel()
	{
		JLabel				label;
		String				property;
		FormLayout			layout	= new FormLayout(
				// columns
				"5px,f:p, 10px, f:d:g,5px", 
				// rows
				" 5px,f:p," +	// inactivity timeout
//				" 5px,f:p," +	// download site
				" 5px,f:p," +	// show epSOS button
				" 5px,f:p," +	// epSOS URL
				" 5px,f:p," +	// message loglevel
				" 5px");
		CellConstraints		cc		= new CellConstraints();
		ESanteConfigManager	manager	= ESanteConfigManagerBean.getInstance();
		JPanel				inactivityTimeoutPanel;
		
		
		preferencesBorder	= new TitledBorder (Translatrix.getTranslationString(
				"esante.managementPanel.preferencesPanel.borderTitle"));
		preferencesPanel	= new JPanel ();
		preferencesPanel.setOpaque(false);
		preferencesPanel.setLayout(layout);
		preferencesPanel.setBorder(this.preferencesBorder);
		
		// inactivity timeout
		label					= new JLabel(Translatrix.getTranslationString(
				"esante.managementPanel.preferencesPanel.inactivityTimeout"));
		property				= manager.getESantePropertyValue(ESanteProperty.PROP_INACTIVITY_TIMEOUT);
		inactivityTimeoutSlider	= new JSlider(ESanteProperty.MIN_INACTIVITY_TIMEOUT, ESanteProperty.MAX_INACTIVITY_TIMEOUT);
		inactivityTimeoutSlider.setOpaque(false);
		try
		{
			inactivityTimeoutSlider.setValue(Integer.parseInt(property));
		}
		catch (Exception e)
		{
			inactivityTimeoutSlider.setValue(inactivityTimeoutSlider.getMinimum());
		}
		inactivityTimeoutSlider.addChangeListener(this);
		inactivityTimeoutSlider.setMajorTickSpacing(5);
		inactivityTimeoutSlider.setMinorTickSpacing(1);
		inactivityTimeoutSlider.setPaintLabels(true);
		inactivityTimeoutSlider.setPaintTicks(true);
		inactivityTimeoutSlider.setPaintTrack(true);
		
		inactivityTimeoutLabel	= new JLabel(String.valueOf(inactivityTimeoutSlider.getValue()));
		inactivityTimeoutLabel.setOpaque(false);
		GECAMedGuiUtils.changeFont(inactivityTimeoutLabel, TextAttribute.SIZE, 16);
		
		inactivityTimeoutPanel	= new JPanel(new FormLayout("f:d:g,10px,f:p", "f:p"));
		inactivityTimeoutPanel.setOpaque(false);
		inactivityTimeoutPanel.add(inactivityTimeoutSlider,	cc.xy(1, 1));
		inactivityTimeoutPanel.add(inactivityTimeoutLabel,	cc.xy(3, 1));
		
		preferencesPanel.add(label,						cc.xy(2, 2));
		preferencesPanel.add(inactivityTimeoutPanel,	cc.xy(4, 2));
		
		// Download site 
		// not visible, because shouldn't be used anymore
//		label	= new JLabel(Translatrix.getTranslationString(
//				"esante.managementPanel.preferencesPanel.cdaDownloadSite"));
//		downloadSiteButton	= new JButton(new AbstractAction()
//		{
//			private static final long	serialVersionUID	= 1L;
//			
//			public void actionPerformed (ActionEvent e)
//			{
//				chooseDownloadSite();
//			}
//		});
//		setCdaDownloadSiteCaption();
//		
//		this.preferencesPanel.add(label,				cc.xy(2, 4));
//		this.preferencesPanel.add(downloadSiteButton, 	cc.xy(4, 4));
		
		// show EPSOS button
		label			= new JLabel(Translatrix._("esante.managementPanel.preferencesPanel.showEpSOSButton"));
		property		= manager.getESantePropertyValue(ESanteProperty.PROP_SHOW_EPSOS_BUTTON);
		
		showEpsosButtonBox	= new JCheckBox("");
		showEpsosButtonBox.setOpaque(false);
		showEpsosButtonBox.setSelected(GECAMedUtils.isTrue(property, true));
		showEpsosButtonBox.addItemListener(this);
		
		preferencesPanel.add(label,					cc.xy(2, 4));
		preferencesPanel.add(showEpsosButtonBox,	cc.xy(4, 4));
		
		// EPSOS URL
		epsosUrlLabel	= new JLabel(Translatrix.getTranslationString(
				"esante.managementPanel.preferencesPanel.epSOS_URL"));
		property		= manager.getESantePropertyValue(ESanteProperty.PROP_EPSOS_URL);
		epsosUrlField	= new JTextField(property != null ? property : "");
		epsosUrlField.getDocument().addDocumentListener(this);
		
		if (!showEpsosButtonBox.isSelected())
		{
			epsosUrlField.setEnabled(false);
			epsosUrlField.setEditable(false);
			epsosUrlLabel.setEnabled(false);
		}
		
		preferencesPanel.add(epsosUrlLabel, cc.xy(2, 6));
		preferencesPanel.add(epsosUrlField,	cc.xy(4, 6));
		
		JLabel messageLoglevelLabel	= new JLabel(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.messageLoglevel"));
		messageLoglevelCB = new JComboBox<MessageLogLevel>();
		messageLoglevelCB.setFont(messageLoglevelCB.getFont().deriveFont(Font.BOLD, 12));
		messageLoglevelCB.setRenderer(new MessageLoglevelCbRenderer());
		messageLoglevelCB.setPreferredSize(new Dimension(200, 20));
		MessageLogLevel noneLevel = new MessageLogLevel(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.messageLoglevel.none"), WebserviceConstants.MESSAGE_LOGLEVEL_NONE);
		MessageLogLevel atnaLevel = new MessageLogLevel(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.messageLoglevel.atna"), WebserviceConstants.MESSAGE_LOGLEVEL_ATNA);
		MessageLogLevel messageLevel = new MessageLogLevel(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.messageLoglevel.message"), WebserviceConstants.MESSAGE_LOGLEVEL_MESSAGE);
		MessageLogLevel fullLevel = new MessageLogLevel(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.messageLoglevel.full"), WebserviceConstants.MESSAGE_LOGLEVEL_FULL);
		messageLoglevelCB.addItem(noneLevel);
		messageLoglevelCB.addItem(atnaLevel);
		messageLoglevelCB.addItem(messageLevel);
		messageLoglevelCB.addItem(fullLevel);
		
		// load last setting from db
		int currentLevel = WebserviceConstants.MESSAGE_LOGLEVEL_NONE;
		try {
			currentLevel = Integer.parseInt(manager.getESantePropertyValue(ESanteProperty.PROP_MESSAGE_LOGLEVEL));
		} catch (NumberFormatException e) {
		}

		// and set the corresponding value active in the combobox
		switch (currentLevel) {
		case WebserviceConstants.MESSAGE_LOGLEVEL_ATNA:
			messageLoglevelCB.setSelectedItem(atnaLevel);
			break;
		case WebserviceConstants.MESSAGE_LOGLEVEL_MESSAGE:
			messageLoglevelCB.setSelectedItem(messageLevel);
			break;
		case WebserviceConstants.MESSAGE_LOGLEVEL_FULL:
			messageLoglevelCB.setSelectedItem(fullLevel);
			break;
		default:
			messageLoglevelCB.setSelectedItem(noneLevel);
			break;
		}
		messageLoglevelCB.addItemListener(this);
		
		preferencesPanel.add(messageLoglevelLabel, cc.xy(2, 8));
		preferencesPanel.add(messageLoglevelCB,	cc.xy(4, 8));
	}
	
	
	public class MessageLoglevelCbRenderer extends DefaultComboBoxRenderer {

	    private static final long serialVersionUID = 879234767762341L;

	    public MessageLoglevelCbRenderer() {
	    }

	    /*
	     * (non-Javadoc)
	     * 
	     * @see lu.tudor.santec.gecamed.core.gui.utils.DefaultComboBoxRenderer#getRenderString(java.lang.Object)
	     */
	    protected String getRenderString(Object p_Object) {
	        String Rendered = "";

	        if (p_Object instanceof MessageLogLevel) {
	           Rendered = ((MessageLogLevel) p_Object).getDisplayName();
	        } else
	            Rendered = "";

	        return Rendered;
	    }
	}

	public class MessageLogLevel {

	    private static final long serialVersionUID = 769234767762341L;

		String displayName=null;
		int logLevel = WebserviceConstants.MESSAGE_LOGLEVEL_NOT_SET;
		

		
		public MessageLogLevel(String displayName, int level){
			this.displayName = displayName;
			this.logLevel= level;
		}
		public String getDisplayName() {
			return displayName;
		}
		
		public int getLogLevel() {
			return logLevel;
		}
	}
	
	
//	private void chooseDownloadSite ()
//	{
//		CdaDownloadSiteDialog.getInstance().chooseCdaDownloadSite();
//		setCdaDownloadSiteCaption();
//	}
	
	
//	private void setCdaDownloadSiteCaption ()
//	{
//		if (ESanteUtils.getCdaDownloadSite() == ESanteUtils.CDA_DOWNLOAD_SITE_CLIENT)
//			downloadSiteButton.setText(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.client"));
//		else
//			downloadSiteButton.setText(Translatrix.getTranslationString("esante.managementPanel.preferencesPanel.server"));
//	}
	
	
	private void editEHealthIds ()
	{
		EHealthIdEditDialog.showDialog();
	}
	
	
	private void editingStopped (JTextComponent c)
	{
		c.setEditable(false);
		c.getCaret().setVisible(false);
		if (!c.getText().equals(editStartValue))
		{
			if (!GECAMedUtils.isDemo() && MainFrame.isAdmin()) {
				setModified(true);
			}
		}
	}
}
