/*******************************************************************************
 * 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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.widgets.GenericListBox;
import lu.tudor.santec.gecamed.core.utils.Logger;
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.office.ejb.entity.beans.Physician;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Level;

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

public class PhysicianKeyPanel extends JPanel implements ActionListener,
													   Relocalizable
	{
	/**
	 * 
	 */
	private GenericListBox			m_KeyListBox;
	private PhysicianKeyListModel	m_Keys;
	private JButton					m_AddKeyButton;
	private JButton					m_RemoveKeyButton;

	private Physician				m_Physician;
	
	private KeyChainInterface		m_KeyChainInterface;
	
	private static Logger	m_Logger = new Logger (PhysicianKeyPanel.class);
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	
	private static final long serialVersionUID = 1L;

	private final static String c_Columns	= "3dlu,fill:max(150dlu;pref),3dlu,fill:max(50dlu;pref)";
		
	private final static String c_Rows		= "3dlu,fill:pref,3dlu," +
										 	  "fill:max(10dlu;pref),3dlu," +
										 	  "fill:max(10dlu;pref),fill:pref:grow,3dlu";
	
	private final static String c_AddKeyButton	   = "PhysicianKeyPanel.AddKeyButton";
	private final static String c_AddKeyTip	 	   = "PhysicianKeyPanel.AddKeyTip";
	private final static String c_RemoveKeyButton  = "PhysicianKeyPanel.RemoveKeyButton";
	private final static String c_RemoveKeyTip     = "PhysicianKeyPanel.RemoveKeyTip";

//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public PhysicianKeyPanel ()
	{	
	this.buildPanel();
	}
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
/**
 * The private getKeyChainInterface returns an instance of the KeyChainBean
 * session bean. On the first call, the KeyChainBean 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 KeyChainBean session bean.
 */
//---------------------------------------------------------------------------

private KeyChainInterface getKeyChainInterface ()
	{
	if (m_KeyChainInterface != null) return m_KeyChainInterface;

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

	return m_KeyChainInterface;
	}

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

private Collection <PhysicianKey> getKeysForPhysician (Physician p_Physician)
	{
	KeyChainInterface			l_Interface   = null;
	Collection <PhysicianKey>	l_Keys = null;
	
	if ((p_Physician == null) || !p_Physician.isPersistent()) return null;
	
	l_Interface = this.getKeyChainInterface();
	if (l_Interface == null) return null;
	
	try	{
		l_Keys = l_Interface.getKeysByPhysicianId(p_Physician.getId());
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.FATAL, "Error while fetching keys for physician " + p_Physician.toString() + "!",p_Exception);			
		}
	
	return l_Keys;
	}

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

private PhysicianKey saveKey (PhysicianKey p_Key)
	{
	KeyChainInterface		l_Interface   = null;

	if (p_Key == null) return null;
	
	l_Interface = this.getKeyChainInterface();
	if (l_Interface == null) return null;
	
	try	{
		p_Key = l_Interface.saveKey (p_Key);
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.FATAL, "Error while saving key!",p_Exception);			
		}
	
	return p_Key;	
	}

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

private void deleteKey (PhysicianKey p_Key)
	{
	KeyChainInterface		l_Interface   = null;

	if (p_Key == null) return;
	
	l_Interface = this.getKeyChainInterface();
	if (l_Interface == null) return;
	
	try	{
		l_Interface.deleteKey(p_Key);
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.FATAL, "Failed to delete key!",p_Exception);			
		}
	}

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

private void buildPanel ()
	{
	CellConstraints		l_Constraints;
	FormLayout			l_Layout;
	MouseAdapter		l_MouseAdapter;
	ImageIcon			l_Icon;
	
	l_Constraints  	= new CellConstraints();
	l_Layout		= new FormLayout(c_Columns, c_Rows);

	this.setLayout(l_Layout);	
	this.setOpaque(false);
	
	m_Keys = new PhysicianKeyListModel ();
	
	m_KeyListBox = new GenericListBox (m_Keys);
	m_KeyListBox.setRenderer (new PhysicianKeyRenderer ());
	
  	l_MouseAdapter = new MouseAdapter()
    		{
    		public void mouseClicked(MouseEvent p_Event)
    			{
    			if (p_Event.getClickCount() == 2)
    				{
    				editSelectedKey (); 
    				}
    			}
    		};

	m_KeyListBox.addMouseListener(l_MouseAdapter);
	
	l_Icon = LaboModule.getButtonIcon (LaboModule.c_i32_AddKey);
	m_AddKeyButton = new JButton (Translatrix.getTranslationString(c_AddKeyButton),l_Icon);
	m_AddKeyButton.setToolTipText (Translatrix.getTranslationString(c_AddKeyTip));
	m_AddKeyButton.setHorizontalAlignment(SwingConstants.LEFT);
	m_AddKeyButton.setVerticalTextPosition(AbstractButton.CENTER);
	m_AddKeyButton.setHorizontalTextPosition(AbstractButton.TRAILING); 
	m_AddKeyButton.addActionListener(this);
	m_AddKeyButton.setEnabled(false);
	
	l_Icon = LaboModule.getButtonIcon (LaboModule.c_i32_RemoveKey);
	m_RemoveKeyButton = new JButton (Translatrix.getTranslationString(c_RemoveKeyButton),l_Icon);
	m_RemoveKeyButton.setToolTipText (Translatrix.getTranslationString(c_RemoveKeyTip));
	m_RemoveKeyButton.setHorizontalAlignment(SwingConstants.LEFT);
	m_RemoveKeyButton.setVerticalTextPosition(AbstractButton.CENTER);
	m_RemoveKeyButton.setHorizontalTextPosition(AbstractButton.TRAILING); 
	m_RemoveKeyButton.addActionListener(this);
	m_RemoveKeyButton.setEnabled(false);
	
	this.add (m_KeyListBox, 	 l_Constraints.xywh (2, 2, 1, 6));
	this.add (m_AddKeyButton, 	 l_Constraints.xywh (4, 2, 1, 1));
	this.add (m_RemoveKeyButton, l_Constraints.xywh (4, 4, 1, 1));
	}

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

private void updateListBox ()
	{
	m_KeyListBox.packRows();
	m_KeyListBox.packColumns();
	m_KeyListBox.validate();		
	}

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

public void setPhysician (Physician p_Physician)
	{
	if ((p_Physician == null) || (!p_Physician.isPersistent())) return;
	
	m_Physician = p_Physician;
	
	m_AddKeyButton.setEnabled(true);
	m_RemoveKeyButton.setEnabled(true);
	
	m_Keys.setKeys(this.getKeysForPhysician(p_Physician));
	
	this.updateListBox();
	}

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

public void addKey ()
	{
	PhysicianKey		l_Key;
	PhysicianKeyDialog  l_KeyDialog;
	String				l_MasterPassword = LaboModule.getMasterPassword();
	
	if (l_MasterPassword == null)
		return;
	
	
	l_Key 		  = new PhysicianKey ();
	l_Key.setPhysicianId(m_Physician.getId());
	
	l_KeyDialog = new PhysicianKeyDialog (l_MasterPassword);
	l_KeyDialog.setKey(l_Key);
	l_KeyDialog.pack();
	MainFrame.showDialogCentered(l_KeyDialog);	
	
	if (!l_KeyDialog.wasCanceled())
		{
		l_Key = l_KeyDialog.getKey();
		l_Key = this.saveKey(l_Key);
		m_Keys.addKey(l_Key);
		this.updateListBox();
		}
	}

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

public void removeSelectedKey ()
	{
	int 			l_SelectedRow;
	PhysicianKey	l_Key;
		
	l_SelectedRow = m_KeyListBox.getSelectedRow();
	if (l_SelectedRow >= 0)
		{
		l_Key = m_Keys.getKeyAt(l_SelectedRow);
		this.deleteKey(l_Key);
		m_Keys.removeKeyAt(l_SelectedRow);
		this.updateListBox();
		}
	}

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

public void editSelectedKey ()
	{
	int					l_SelectedRow;
	PhysicianKey		l_Key;
	PhysicianKeyDialog 	l_KeyDialog;
	String				l_MasterPassword = LaboModule.getMasterPassword();
	
	if (l_MasterPassword == null)
		return;
	
	l_SelectedRow = m_KeyListBox.getSelectedRow();
	l_Key 		  = m_Keys.getKeyAt(l_SelectedRow);
		
	l_KeyDialog = new PhysicianKeyDialog (l_MasterPassword);
	l_KeyDialog.setKey(l_Key);
	l_KeyDialog.pack();
	MainFrame.showDialogCentered(l_KeyDialog);	
	
	if (!l_KeyDialog.wasCanceled())
		{
		l_Key = l_KeyDialog.getKey();
		l_Key = this.saveKey(l_Key);
		m_Keys.setKeyAt(l_Key, l_SelectedRow);
		this.updateListBox();
		}
	}

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

public void relocalize()
	{
	if (m_AddKeyButton != null)
		m_AddKeyButton.setText(Translatrix.getTranslationString(c_AddKeyButton));
	
	if (m_RemoveKeyButton != null)
		m_RemoveKeyButton.setText(Translatrix.getTranslationString(c_RemoveKeyButton));
	}

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

public void actionPerformed (ActionEvent p_ActionEvent)
	{
	if (p_ActionEvent.getSource().equals(m_AddKeyButton))
		{
		this.addKey ();	
		}
	else if (p_ActionEvent.getSource().equals(m_RemoveKeyButton))
		{
		this.removeSelectedKey ();	
		}
	}

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

	}
