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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.widgets.HeaderedPanel;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.ejb.session.beans.PatientAdminBean;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.PatientAdminInterface;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.patientlist.PatientSearchDialog;
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 display and edit the patients family contacts, such as 
 * childs, spouse and parents
 * 
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @version
 * <br>$Log: PatientFamilyPanel.java,v $
 * <br>Revision 1.29  2013-12-27 18:07:55  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.28  2013-07-15 06:18:34  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.27  2010-04-21 08:11:13  hermen
 * <br>fixed family relation adding/opening
 * <br>
 * <br>Revision 1.26  2010-03-12 14:13:17  hermen
 * <br>icon cleanup
 * <br>
 * <br>Revision 1.25  2009-05-29 13:51:21  hermen
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.24  2008-09-25 09:43:06  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.23  2008-07-22 09:09:28  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.22  2008-06-17 10:08:45  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.21  2008-04-16 14:24:28  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.20  2008-01-21 14:03:27  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 *
 */
public class PatientFamilyPanel extends HeaderedPanel implements IPatientDataPanel
{
    //~ Static fields/initializers =============================================

	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(PatientFamilyPanel.class.getName());

    private static final long serialVersionUID = 1L;
    private static final String COLUMNSPACE = "2dlu";

    //~ Instance fields ========================================================

	private PatientAdminInterface patientManager;
	private RelationPanel spouse;
	private RelationPanel parent1;
	private RelationPanel child1;
	private Set<Patient> parents;
	private Set<Patient> children;
	private PatientAdminPanel patientEditPanel;

    //~ Constructors ===========================================================
    /**
     * builds a new PhoneInfo to show/edit Phone-Data
     *
     * @param mainFrame a reference to the mainFrame of the Program to obtain all child-objects from
     */
    public PatientFamilyPanel(PatientAdminPanel patientEditPanel)
    {
    	this.setOpaque(false);
    	this.patientEditPanel = patientEditPanel;
        this.buildPanel();
    }

    //~ Methods ================================================================

    /* (non-Javadoc)
     * @see lu.tudor.santec.gecamed.patient.gui.administrative.IPatientDataPanel#getPatient(lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient)
     */
    public void getPatient(Patient patient)
    {
    	try {
    		List<Patient> pl = this.spouse.getData();
    		// ===================================================
    		// we consider only the first entry. In normal europe
    		// a person can have only one spouse at a time
    		// ===================================================
    		if (pl != null && pl.size() > 0) {
    			/* ------------------------------------------------------- */
    			Patient sp = pl.get(0);
    			if (sp.isPersistent()) {
    				// delete the name string
    				patient.setSpouseName("");
    				// set the relation to the patient object
    				patient.setSpouseId(sp.getId());
    				// set the relation to the spouse
    				sp.setSpouseId(patient.getId());
    				// save the spouse
    				patientManager.savePatient(sp);
    			} else {
    				// set the name string
    				patient.setSpouseName(sp.getSurName());
    				// remove the possible spouse relation
    				if (patient.getSpouseId() != null) {
    					// get the old spouse object
    					Patient spOld = patientManager.getPatient(patient.getSpouseId());
    					// remove the relation
    					spOld.setSpouseId(null);
    					// save old spouse, bye bye
    					patientManager.savePatient(spOld);
    					// remove spouseId
    					patient.setSpouseId(null);
    					// divorce complete. costs: 10.000.000 €
    				}
    			}
    			/* ------------------------------------------------------- */
    		} else {
    			/* ------------------------------------------------------- */
    			// =========================================================
    			// when we are here, the spouse might have been deleted
    			// =========================================================
    			patient.setSpouseName("");
    			if (patient.getSpouseId() != null) {
    				// get the old spouse object
					Patient spOld = patientManager.getPatient(patient.getSpouseId());
					// remove the relation
					spOld.setSpouseId(null);
					// save old spouse, bye bye
					patientManager.savePatient(spOld);
					// remove spouseId
					patient.setSpouseId(null);
					// divorce complete. costs: 10.000.000 €
				}
    			/* ------------------------------------------------------- */
    		}
		} catch (Exception e) {
			logger.log(Level.WARN, "error saving Spouse", e);
		}

		// ================================================================
		// Parents
		// ================================================================
		if (parent1.getData() != null && parent1.getData().size() > 0) {
			/* ------------------------------------------------------- */
			List<Patient> par = parent1.getData();
			parents = new HashSet<Patient>();
			patient.setParentName("");
			for (Patient p :  par) {
				/* ------------------------------------------------------- */
				if (p.isPersistent())
					parents.add(p);
				else
					patient.setParentName(patient.getParentName() + p.getSurName()+"\n");
				/* ------------------------------------------------------- */
			}
			patient.setParents(parents);
			/* ------------------------------------------------------- */
		} else {
			// ==============================================================
			// remove all parents
			// ==============================================================
			patient.setParentName("");
			patient.setParents(null);
		}


		// ================================================================
		// Children
		// ================================================================
		if (child1.getData() != null && child1.getData().size() > 0) {
			/* ------------------------------------------------------- */
			List<Patient> ch = child1.getData();
			children = new HashSet<Patient>();
//			patient.setParentName("");
			patient.setChildrenName("");
			for (Patient c :  ch) {
				/* ------------------------------------------------------- */
				if (c.isPersistent())
					children.add(c);
				else {
					/* ------------------------------------------------------- */
					StringBuffer buff = new StringBuffer();
					buff.append((patient.getChildrenName() != null ? patient.getChildrenName() : ""));
					buff.append((c.getSurName() != null ? c.getSurName()+"\n" : ""));
					
//					patient.setChildrenName(patient.getChildrenName() + c.getSurName()+"\\n");
					patient.setChildrenName(buff.toString());
					/* ------------------------------------------------------- */
				}
				/* ------------------------------------------------------- */
			}
			patient.setChildren(children);
			/* ------------------------------------------------------- */
		} else {
			// ==============================================================
			// remove all parents
			// ==============================================================
			patient.setChildrenName("");
			patient.setChildren(null);
		}
    }

    /* (non-Javadoc)
     * @see lu.tudor.santec.gecamed.patient.gui.administrative.IPatientDataPanel#setPatient(lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient, boolean)
     */
    public void setPatient(Patient patient, boolean editable) {
    	/* ================================================== */
    	this.spouse.reset();
    	this.parent1.reset();
    	this.child1.reset();
    	/* ------------------------------------------------------- */
    	try {
			this.spouse.setData(patientManager.getPatient(patient.getSpouseId()));
		} catch (Exception e1) {
		    	if (patient.getSpouseName() != null) {
		    	    Patient p = new Patient();
		    	    p.setSurName(patient.getSpouseName());
		    	    this.spouse.setData(p);		    	    
		    	}
		}

		this.parents = patient.getParents();
		if (this.parents != null) {
			this.parent1.setData(new ArrayList<Patient>(this.parents));
		}

		if (patient.getParentName() != null && !patient.getParentName().equals("")) {
			StringTokenizer t = new StringTokenizer(patient.getParentName(), "\n");
			List<Patient> pl = new ArrayList<Patient>();
			while (t.hasMoreTokens()) {
				/* ------------------------------------------------------- */
				Patient pNew = new Patient();
				pNew.setSurName(t.nextToken().replaceAll("\n", ""));
				pl.add(pNew);
				/* ------------------------------------------------------- */
			}
			this.parent1.getData().addAll(pl);
		}
		/* ------------------------------------------------------- */
    	this.children = patient.getChildren();
		if (this.children != null) {
			/* ------------------------------------------------------- */
			this.child1.setData(new ArrayList<Patient>(this.children));
			/* ------------------------------------------------------- */
		}
		if (patient.getChildrenName() != null && !patient.getChildrenName().equals("")) {
			StringTokenizer t = new StringTokenizer(patient.getChildrenName(), "\n");
			List<Patient> cl = new ArrayList<Patient>();
			while (t.hasMoreTokens()) {
				Patient pNew = new Patient();
				pNew.setSurName(t.nextToken().replaceAll("\n", ""));
				cl.add(pNew);
			}
			this.child1.getData().addAll(cl);
		}
		/* ================================================== */
    }

	/**
     * adds the components to the panel
     */
    private void buildPanel()
    {	
    	
    	this.setHeader(Translatrix.getTranslationString("pm.familyInfo")+":");
//    	this.setHeaderIcon(PatientManagerModule.getMediumIcon(PatientManagerModule.PATIENT));
    	this.enableAlpha(true);
    	
    	
        // initialize components
        initComponents();

        // build Layout
        String line = "";
        for (int i = 1; i <= 3; i++) {
            line = line + "85dlu:grow, " + COLUMNSPACE + ", ";
        }
        FormLayout layout = new FormLayout(line, "pref, pref, " + COLUMNSPACE + ", pref, " + COLUMNSPACE + "");
        this.setLayout(layout);
        CellConstraints cc = new CellConstraints();

        this.add(spouse, cc.xyw(1, 2, 1));

        this.add(parent1, cc.xyw(3, 2, 1));

        this.add(child1, cc.xyw(5, 2, 1));

    }

    /**
     * initializes the Components
     */
    private void initComponents()
    {
		 // Get the manager
	    patientManager = (PatientAdminInterface) ManagerFactory.getRemote(PatientAdminBean.class);

	    this.spouse = new RelationPanel(true, Translatrix.getTranslationString("pm.spouse"), 1);
	    this.parent1 = new RelationPanel(true, Translatrix.getTranslationString("pm.parents"), 2);
	    this.child1 = new RelationPanel(true, Translatrix.getTranslationString("pm.childs"), -1);
    }


    	/**
    	 * @author martin.heinemann@tudor.lu
    	 * 28.03.2007
    	 * 15:09:36
    	 *
    	 *
    	 * @version
    	 * <br>$Log: PatientFamilyPanel.java,v $
    	 * <br>Revision 1.29  2013-12-27 18:07:55  donak
    	 * <br>Cleanup of imports
    	 * <br>
    	 * <br>Revision 1.28  2013-07-15 06:18:34  ferring
    	 * <br>logging changed
    	 * <br>
    	 * <br>Revision 1.27  2010-04-21 08:11:13  hermen
    	 * <br>fixed family relation adding/opening
    	 * <br>
    	 * <br>Revision 1.26  2010-03-12 14:13:17  hermen
    	 * <br>icon cleanup
    	 * <br>
    	 * <br>Revision 1.25  2009-05-29 13:51:21  hermen
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.24  2008-09-25 09:43:06  heinemann
    	 * <br>fixed copyrights
    	 * <br>
    	 * <br>Revision 1.23  2008-07-22 09:09:28  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.22  2008-06-17 10:08:45  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.21  2008-04-16 14:24:28  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.20  2008-01-21 14:03:27  hermen
    	 * <br>updated Javadoc and refactured code
    	 * <br>
    	 * <br>Revision 1.19  2007-11-20 08:58:54  hermen
    	 * <br>moved Managerfactory to core.utils and refactured code to use ManagerFactory instead of context.lookup
    	 * <br>
    	 * <br>Revision 1.18  2007-10-24 09:30:17  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.17  2007-10-16 08:23:26  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.16  2007/07/03 12:35:29  heinemann
    	 * <br>system.out removed
    	 * <br>
    	 * <br>Revision 1.15  2007/06/19 11:28:04  hermen
    	 * <br>added logging
    	 * <br>
    	 * <br>Revision 1.14  2007/06/06 11:23:20  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.13  2007/04/11 07:38:47  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.12  2007/04/06 13:46:03  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 * <br>Revision 1.11  2007/03/30 12:18:00  heinemann
    	 * <br>*** empty log message ***
    	 * <br>
    	 *
    	 */
    	class RelationPanel extends JPanel implements MouseListener, ActionListener, KeyListener {

			private static final long serialVersionUID = 1L;
			private JTable table;
			private JScrollPane scroll;
			private JButton expandButton;
			private RelationTableModel relationTableModel;
			private int currentRow;
			private int maxCount;
			private JPanel headerPanel;

			/**
			 * @param expandable should the "add" button be visible?
			 * @param topic Topic for the panel
			 * @param maxCount maximum amount of items, use -1 for undefined
			 */
			public RelationPanel(boolean expandable, String topic, int maxCount){
				/* ================================================== */
				this.maxCount = maxCount;
				if (this.maxCount == -1)
					this.maxCount = 1000;

				this.setLayout(new BorderLayout());

				this.relationTableModel = new RelationTableModel();
				this.table = new JTable(relationTableModel);

				table.addMouseListener(this);
				table.addKeyListener(this);
				this.scroll = new JScrollPane(table);
				table.setTableHeader(null);
				table.getColumnModel().getColumn(1).setMaxWidth(20);

				table.getColumnModel().getColumn(1).setCellRenderer(new RelationTableCellRenderer());

				table.setShowGrid(false);

				scroll.getViewport().setBackground(Color.WHITE);
				scroll.setAutoscrolls(true);
				this.add(scroll, BorderLayout.CENTER);


				/* ------------------------------------------------------- */
				// topic panel
				this.expandButton = new JButton(GECAMedModule.getSmallIcon(GECAMedIconNames.ADD_LINE));
				expandButton.addActionListener(this);
				expandButton.setPreferredSize(new Dimension(20,20));
				expandButton.setContentAreaFilled(false);
//				expandButton.setBorderPainted(false);
				expandButton.setToolTipText(Translatrix.getTranslationString("pm.add"));

				this.headerPanel = new JPanel(new BorderLayout());
				headerPanel.setOpaque(false);
				// add if this is the desire of the developer.
				if (expandable) {
					headerPanel.add(expandButton, BorderLayout.EAST);
				}
				JLabel topicLabel = new JLabel(topic);
				headerPanel.add(topicLabel, BorderLayout.WEST);

				this.add(headerPanel, BorderLayout.NORTH);
				this.setOpaque(false);

				adjustSize();


				/* ================================================== */
			}

			private void adjustSize() {
				/* ================================================== */
				this.setPreferredSize(new Dimension(this.getPreferredSize().width,
						70));
				/* ================================================== */
			}
			
			public void setData(Patient data) {
				/* ================================================== */
				List<Patient> l = new ArrayList<Patient>();
				l.add(data);
				this.setData(l);
				/* ================================================== */
			}

			public void setData(List<Patient> data) {
				/* ================================================== */
				relationTableModel.setData(data);
				relationTableModel.fireTableDataChanged();
				adjustSize();
				/* ================================================== */
			}

			public List<Patient> getData() {
				/* ================================================== */
				return relationTableModel.getData();
				/* ================================================== */
			}

			public void reset() {
				/* ================================================== */
				this.relationTableModel.reset();
				/* ================================================== */
			}
			
			
//			 **************************************************************************
			// **************************************************************************
			// ActionListener of the expandButton
			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				if (e.getSource().equals(expandButton)){
					if (relationTableModel.getRowCount() < maxCount) {
						// add a new line to the table model
						relationTableModel.addData(new Patient());
						relationTableModel.fireTableDataChanged();

						this.currentRow = relationTableModel.getRowCount()-1;
						table.requestFocus();

						// start editing
						table.editCellAt(currentRow, 0);
						table.setRowSelectionInterval(currentRow, currentRow);
						table.getCellEditor().getTableCellEditorComponent(
								table, " ", true, currentRow, 0).requestFocus();
						table.scrollRectToVisible(table.getCellRect(table.getSelectedRow(), 0, true));
//						adjustSize();
					}
				}
				/* ====================================================== */
			}

			// **************************************************************************
			// mouse listener
			public void mouseClicked(MouseEvent e) {
				/* ====================================================== */
				if (SwingUtilities.isLeftMouseButton(e)) {
					if (table.getSelectedColumn() == 0) {
//						table.getCellEditor(row, 0)
					} else
					{
						/* ------------------------------------------------------- */
						int row = table.getSelectedRow();
						if (row > -1) {
							Patient p = PatientSearchDialog.searchPatient("");
							if (p != null) {
								relationTableModel.setDataAtRow(row, p);
							}
						}
						/* ------------------------------------------------------- */
					}
				}

				/* ====================================================== */
			}
			public void mouseEntered(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {
				if (e.isPopupTrigger()) {
					int row = table.getSelectedRow();
					if (row > -1) {
						PatientManagerModule.getInstance().addPatient(
								relationTableModel.getPatientAtRow(row),true);
					}
				}
			}
			public void mouseReleased(MouseEvent e) {
				if (e.isPopupTrigger()) {
					int row = table.getSelectedRow();
					if (row > -1) {
						PatientManagerModule.getInstance().addPatient(
								relationTableModel.getPatientAtRow(row),true);
					}
				}
			}
			public void mouseExited(MouseEvent e) {}

			// **************************************************************************
			// **************************************************************************
			// key Listener

			public void keyPressed(KeyEvent e) {
				/* ====================================================== */
				if (e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
					// remove the current line from the list
					int row = table.getSelectedRow();
					relationTableModel.removeData(row);
					e.consume();
				}
				/* ====================================================== */
			}
			public void keyReleased(KeyEvent e) {
			}
			public void keyTyped(KeyEvent e) {
			}


			// ******************************************************************************
			// ******************************************************************************
			//
			// Table Model for the relation table
			// ******************************************************************************

			/**
			 * @author martin.heinemann@tudor.lu
			 * 28.03.2007
			 * 16:02:05
			 *
			 *
			 * @version
			 * <br>$Log: PatientFamilyPanel.java,v $
			 * <br>Revision 1.29  2013-12-27 18:07:55  donak
			 * <br>Cleanup of imports
			 * <br>
			 * <br>Revision 1.28  2013-07-15 06:18:34  ferring
			 * <br>logging changed
			 * <br>
			 * <br>Revision 1.27  2010-04-21 08:11:13  hermen
			 * <br>fixed family relation adding/opening
			 * <br>
			 * <br>Revision 1.26  2010-03-12 14:13:17  hermen
			 * <br>icon cleanup
			 * <br>
			 * <br>Revision 1.25  2009-05-29 13:51:21  hermen
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.24  2008-09-25 09:43:06  heinemann
			 * <br>fixed copyrights
			 * <br>
			 * <br>Revision 1.23  2008-07-22 09:09:28  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.22  2008-06-17 10:08:45  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.21  2008-04-16 14:24:28  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.20  2008-01-21 14:03:27  hermen
			 * <br>updated Javadoc and refactured code
			 * <br>
			 * <br>Revision 1.19  2007-11-20 08:58:54  hermen
			 * <br>moved Managerfactory to core.utils and refactured code to use ManagerFactory instead of context.lookup
			 * <br>
			 * <br>Revision 1.18  2007-10-24 09:30:17  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.17  2007-10-16 08:23:26  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.16  2007/07/03 12:35:29  heinemann
			 * <br>system.out removed
			 * <br>
			 * <br>Revision 1.15  2007/06/19 11:28:04  hermen
			 * <br>added logging
			 * <br>
			 * <br>Revision 1.14  2007/06/06 11:23:20  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.13  2007/04/11 07:38:47  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.12  2007/04/06 13:46:03  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 * <br>Revision 1.11  2007/03/30 12:18:00  heinemann
			 * <br>*** empty log message ***
			 * <br>
			 *
			 */
			class RelationTableModel extends AbstractTableModel {

				private static final long serialVersionUID = 1L;
				private List<Patient> relations = new ArrayList<Patient>();
				private int activeRow;

				public RelationTableModel() {
					/* ================================================== */

					/* ================================================== */
				}
				
				public void reset() {
					/* ================================================== */
					relations.clear();
					fireTableDataChanged();
					/* ================================================== */
				}
				
				public void setDataAtRow(int row, Patient p) {
					/* ====================================================== */
					relations.set(row, p);
					fireTableDataChanged();
					PatientFamilyPanel.this.patientEditPanel.setModified(true);
					/* ====================================================== */
				}

				public void setData(List<Patient> data) {
					/* ================================================== */
					this.relations = data;
					/* ================================================== */
				}

				public void addData(Patient patient) {
					/* ================================================== */
					this.relations.add(patient);
					/* ================================================== */
				}

				public void removeData(int row) {
					/* ================================================== */
					try {
						relations.remove(row);
						fireTableDataChanged();
						PatientFamilyPanel.this.patientEditPanel.setModified(true);
					} catch (Exception e) {
						logger.log(Level.WARN, "deleting relations failed", e);
					}
					/* ================================================== */
				}


				public Patient getPatientAtRow(int row) {
					/* ================================================== */
					if (row > -1 && row < relations.size())
						return relations.get(row);
					return null;
					/* ================================================== */
				}

				public List<Patient> getData() {
					/* ================================================== */
					return this.relations;
					/* ================================================== */
				}

				public int getColumnCount() {
					/* ====================================================== */
					return 2;
					/* ====================================================== */
				}

				public int getRowCount() {
					/* ====================================================== */
					return relations.size();
					/* ====================================================== */
				}

				public Object getValueAt(int rowIndex, int columnIndex) {
					/* ====================================================== */
					switch (columnIndex) {
					case 0 : {
						Patient p = relations.get(rowIndex);
						if (p.isPersistent())
							return relations.get(rowIndex).getSurName() + ", " + relations.get(rowIndex).getFirstName();
						return (p.getSurName() != null ? p.getSurName() : "");
					}
					case 1 : return "";

					}
					return null;
					/* ====================================================== */
				}

				public void setNameAt(int row, String name) {
					/* ================================================== */
					try {
						relations.get(row).setSurName(name);
						relations.get(row).setId(null);
					} catch (Exception e) {
						// TODO: handle exception
					}
					/* ================================================== */
				}

				/* (non-Javadoc)
				 * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
				 */
				@Override
				public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
					/* ====================================================== */
					if (columnIndex == 0) {
						try {
							if ("".equals(aValue)) {
								// if the initial value is empty, remove the data set
								if (getValueAt(rowIndex, 0) == null
										|| getValueAt(rowIndex, 0).equals(""))
									relations.remove(rowIndex);
							}
							else {
									relations.get(rowIndex).setSurName((String) aValue);
									relations.get(rowIndex).setId(null);
							}
						} catch (Exception e) {
							logger.log(Level.WARN, "setting relations failed", e);
						}
					}
					fireTableDataChanged();
					PatientFamilyPanel.this.patientEditPanel.setModified(true);
					/* ====================================================== */
				}

				/* (non-Javadoc)
				 * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
				 */
				@Override
				public boolean isCellEditable(int rowIndex, int columnIndex) {
					/* ====================================================== */
					return (columnIndex == 0 ? true : false);
					/* ====================================================== */
				}


				public void setRowActive(int row){
					/* ================================================== */
					this.activeRow = row;
					/* ================================================== */
				}

				public int getActiveRow() {
					/* ================================================== */
					return this.activeRow;
					/* ================================================== */
				}

			}


			class RelationTableCellRenderer extends DefaultTableCellRenderer {

				private static final long serialVersionUID = 1L;


				private ImageIcon SEARCH_ICON = GECAMedModule.getMiniIcon(GECAMedIconNames.SEARCH);

				private JLabel label = new JLabel();

				public RelationTableCellRenderer() {
					label.setHorizontalAlignment(SwingConstants.CENTER);
					label.setVerticalAlignment(SwingConstants.BOTTOM);
				}

				/* (non-Javadoc)
				 * @see com.l2fprod.common.swing.renderer.DefaultCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
				 */
				@Override
				public Component getTableCellRendererComponent(JTable table, Object
				          value, boolean isSelected, boolean hasFocus, int row, int column) {
					/* ====================================================== */
					if (column == 1 && isSelected) {
							// show icon
							label.setIcon(SEARCH_ICON);
							return label;
						}
					return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
					/* ====================================================== */
				}
			}
    	}

		public List<Component> getComponentsForFocus() {
			/* ====================================================== */
			List<Component> list = new ArrayList<Component>(0);
//			/* ------------------------------------------------------- */
//			list.add(spouse);
//			list.add(patientEditPanel);
//			list.add(child1);
			/* ------------------------------------------------------- */
			return list;
			/* ====================================================== */
		}

		public boolean isFilledOK() {
		    return true;
		}
}
