/*******************************************************************************
 * 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.Connection;
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 ConnectionPanel extends JPanel implements ActionListener,
													   Relocalizable
	{
	/**
	 * 
	 */
	private GenericListBox		m_ConnectionsListBox;
	private ConnectionListModel	m_Connections;
	private JButton				m_AddConnectionButton;
	private JButton				m_RemoveConnectionButton;

	private Physician			m_Physician;
	
	private KeyChainInterface	m_KeyChainInterface;
	
	private static Logger	m_Logger = new Logger (ConnectionPanel.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_AddConnectionButton	 = "ConnectionPanel.AddConnectionButton";
	private final static String c_AddConnectionTip	 	 = "ConnectionPanel.AddConnectionTip";
	private final static String c_RemoveConnectionButton = "ConnectionPanel.RemoveConnectionButton";
	private final static String c_RemoveConnectionTip    = "ConnectionPanel.RemoveConnectionTip";

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

public ConnectionPanel ()
	{	
	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 <Connection> getConnectionsForPhysician (Physician p_Physician)
	{
	KeyChainInterface		l_Interface   = null;
	Collection <Connection>	l_Connections = null;
	
	if ((p_Physician == null) || !p_Physician.isPersistent()) return null;
	
	l_Interface = this.getKeyChainInterface();
	if (l_Interface == null) return null;
	
	try	{
		l_Connections = l_Interface.getConnectionsByPhysicianId(p_Physician.getId());
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.FATAL, "Error while fetching connections for physician " + p_Physician.toString() + "!",p_Exception);			
		}
	
	return l_Connections;
	}

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

private Connection saveConnection (Connection p_Connection)
	{
	KeyChainInterface		l_Interface   = null;

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

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

private void deleteConnection (Connection p_Connection)
	{
	KeyChainInterface		l_Interface   = null;

	if (p_Connection == null) return;
	
	l_Interface = this.getKeyChainInterface();
	if (l_Interface == null) return;
	
	try	{
		l_Interface.deleteConnection(p_Connection);
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.FATAL, "Error while deleting connection!",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_Connections = new ConnectionListModel ();
	
	m_ConnectionsListBox = new GenericListBox (m_Connections);
	m_ConnectionsListBox.setRenderer (new ConnectionRenderer ());
	
  	l_MouseAdapter = new MouseAdapter()
    		{
    		public void mouseClicked(MouseEvent p_Event)
    			{
    			if (p_Event.getClickCount() == 2)
    				{
    				editSelectedConnection (); 
    				}
    			}
    		};

	m_ConnectionsListBox.addMouseListener(l_MouseAdapter);
	
	l_Icon = LaboModule.getButtonIcon (LaboModule.c_i32_AddConnection);
	m_AddConnectionButton = new JButton (Translatrix.getTranslationString(c_AddConnectionButton),l_Icon);
	m_AddConnectionButton.setToolTipText (Translatrix.getTranslationString(c_AddConnectionTip));
	m_AddConnectionButton.setHorizontalAlignment(SwingConstants.LEFT);
	m_AddConnectionButton.setVerticalTextPosition(AbstractButton.CENTER);
	m_AddConnectionButton.setHorizontalTextPosition(AbstractButton.TRAILING); 
	m_AddConnectionButton.addActionListener(this);
	m_AddConnectionButton.setEnabled(false);
	
	l_Icon = LaboModule.getButtonIcon (LaboModule.c_i32_RemoveConnection);
	m_RemoveConnectionButton = new JButton (Translatrix.getTranslationString(c_RemoveConnectionButton),l_Icon);
	m_RemoveConnectionButton.setToolTipText (Translatrix.getTranslationString(c_RemoveConnectionTip));
	m_RemoveConnectionButton.setHorizontalAlignment(SwingConstants.LEFT);
	m_RemoveConnectionButton.setVerticalTextPosition(AbstractButton.CENTER);
	m_RemoveConnectionButton.setHorizontalTextPosition(AbstractButton.TRAILING); 
	m_RemoveConnectionButton.addActionListener(this);
	m_RemoveConnectionButton.setEnabled(false);
	
	this.add (m_ConnectionsListBox, 	 l_Constraints.xywh (2, 2, 1, 6));
	this.add (m_AddConnectionButton, 	 l_Constraints.xywh (4, 2, 1, 1));
	this.add (m_RemoveConnectionButton,  l_Constraints.xywh (4, 4, 1, 1));
	}

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

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

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

public void setPhysician (Physician p_Physician)
	{
	if ((p_Physician == null) || (!p_Physician.isPersistent())) return;
	
	m_Physician = p_Physician;
	
	m_AddConnectionButton.setEnabled(true);
	m_RemoveConnectionButton.setEnabled(true);
	
	m_Connections.setConnections(this.getConnectionsForPhysician(p_Physician));
	this.updateListBox();
	}

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

public void addConnection ()
	{
	Connection			l_Connection;
	ConnectionDialog	l_ConnectionDialog;	String
	l_MasterPassword = LaboModule.getMasterPassword();
	
	if (l_MasterPassword == null)
		return;
	
	l_Connection = new Connection ();
	l_Connection.setPhysicianId(m_Physician.getId());
	
	l_ConnectionDialog = new ConnectionDialog (l_MasterPassword);
	l_ConnectionDialog.setConnection(l_Connection);
	l_ConnectionDialog.pack();
	MainFrame.showDialogCentered(l_ConnectionDialog);

	if (!l_ConnectionDialog.wasCanceled())
		{
		l_Connection = l_ConnectionDialog.getConnection();
		l_Connection = this.saveConnection(l_Connection);
		m_Connections.addConnection(l_Connection);
		this.updateListBox();
		}
	}

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

public void editSelectedConnection ()
	{
	int					l_SelectedRow;
	Connection			l_Connection;
	ConnectionDialog	l_ConnectionDialog;	
	String 				l_MasterPassword = LaboModule.getMasterPassword();
	
	if (l_MasterPassword == null)
		return;
	
	l_SelectedRow = m_ConnectionsListBox.getSelectedRow();
	l_Connection = m_Connections.getConnectionAt(l_SelectedRow);
	
	l_ConnectionDialog = new ConnectionDialog (l_MasterPassword);
	l_ConnectionDialog.setConnection(l_Connection);
	l_ConnectionDialog.pack();
	MainFrame.showDialogCentered(l_ConnectionDialog);
	
	if (!l_ConnectionDialog.wasCanceled())
		{
		l_Connection = l_ConnectionDialog.getConnection();
		l_Connection = this.saveConnection(l_Connection);
		m_Connections.setConnectionAt(l_Connection, l_SelectedRow);
		this.updateListBox();
		}
	}

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

public void removeSelectedConnection ()
	{
	int 			l_SelectedRow;
	Connection		l_Connection;
		
	l_SelectedRow = m_ConnectionsListBox.getSelectedRow();
	if (l_SelectedRow >= 0)
		{
		l_Connection = m_Connections.getConnectionAt(l_SelectedRow);
		this.deleteConnection(l_Connection);
		m_Connections.removeConnectionAt(l_SelectedRow);
		this.updateListBox();
		}
	}

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

public void relocalize()
	{
	if (m_AddConnectionButton != null)
		m_AddConnectionButton.setText(Translatrix.getTranslationString(c_AddConnectionButton));
	
	if (m_RemoveConnectionButton != null)
		m_RemoveConnectionButton.setText(Translatrix.getTranslationString(c_RemoveConnectionButton));
	}

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

public void actionPerformed (ActionEvent p_ActionEvent)
	{
	if (p_ActionEvent.getSource().equals(m_AddConnectionButton))
		{
		this.addConnection ();	
		}
	else if (p_ActionEvent.getSource().equals(m_RemoveConnectionButton))
		{
		this.removeSelectedConnection ();	
		}
	}

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

	}
