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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import lu.tudor.santec.gecamed.agenda.ejb.entity.beans.AgendaCalendar;
import lu.tudor.santec.gecamed.agenda.ejb.entity.beans.Appointment;
import lu.tudor.santec.gecamed.agenda.ejb.entity.beans.AppointmentType;
import lu.tudor.santec.gecamed.agenda.ejb.session.beans.AppointmentManagerBean;
import lu.tudor.santec.gecamed.agenda.ejb.session.helper.TimeInterval;
import lu.tudor.santec.gecamed.agenda.ejb.session.interfaces.AppointmentManager;
import lu.tudor.santec.gecamed.agenda.gui.AgendaModule;
import lu.tudor.santec.gecamed.agenda.gui.AgendaSettingsPlugin;
import lu.tudor.santec.gecamed.agenda.gui.widgets.appointmenttype.AppointmentTypeComboBoxRenderer;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
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 bizcal.util.DateUtil;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.toedter.calendar.JDateChooser;

/**
 * 
 * Dialog to find a space for a new appointment with different constraint.
 * There are buttons to look for a space in 1,2,3 or 4 weeks. You can additionally define
 * day conditions when the appointment should be: morning, end of morning, lunch, afternoon, evening.
 * <br/><br/><br/>
 * 
 * @author martin.heinemann@tudor.lu
 * 16.07.2007
 * 09:16:06
 *
 *
 * @version
 * <br>$Log: FreeAppointmentFindDialog.java,v $
 * <br>Revision 1.31  2013-12-27 18:09:03  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.30  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.29  2013-02-19 12:07:34  ferring
 * <br>GECAMedLists changed. Will now automatically load list of all beans
 * <br>
 * <br>Revision 1.28  2013-02-06 15:21:20  troth
 * <br>Remove some System.out.printlin.
 * <br>
 * <br>Revision 1.27  2012-08-07 15:51:58  troth
 * <br>Fix Ticket #1016.
 * <br>
 * <br>Revision 1.26  2012-07-27 15:41:33  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.25  2012-07-26 12:37:28  troth
 * <br>Ticket #1016 point 1.
 * <br>
 * <br>Revision 1.24  2012-07-25 16:20:25  troth
 * <br>fix Ticket #873
 * <br>
 * <br>Revision 1.23  2012-07-23 15:41:24  troth
 * <br>Ticket #873 Point 6 and 7 fixed.
 * <br>
 * <br>Revision 1.22  2012-07-19 15:04:29  troth
 * <br>Ticket #873 Point 5, 8, 9 and 10 fixed.
 * <br>
 * <br>Revision 1.21  2012-07-17 14:36:01  troth
 * <br>Ticket #873 - Constraints are now static and the dialog is redesigned, add a today and 6 week button.
 * <br>
 * <br>Revision 1.20  2012-07-13 15:54:26  troth
 * <br>Label the time conditions with the start an end time. (Morning | 08:00 - 10:00)
 * <br>
 * <br>Revision 1.19  2012-07-04 16:22:48  troth
 * <br>fix bug: Ticket #878  Existing recurring appointments not taken into account by NAF (test version 3).
 * <br>
 * <br>Revision 1.18  2012-06-22 14:56:13  troth
 * <br>Appointment not longer move if the calendar, type or constraints is changed of the Appointment.
 * <br>
 * <br>Revision 1.17  2011-09-22 13:29:50  hermen
 * <br>- changed transparencies in appointmentlist renderer
 * <br>- fixed new column problem im appointmentfinder
 * <br>
 * <br>Revision 1.16  2009-12-15 11:06:24  hermen
 * <br>fixed NPE on add Calendar
 * <br>
 * <br>Revision 1.15  2008-10-21 12:28:27  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.14  2008-09-25 09:42:27  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.13  2008-07-04 13:38:58  heinemann
 * <br>fixed generic casting that the new eclipse does not want to accept.
 * <br>
 * <br>Revision 1.12  2008-04-14 13:11:36  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.11  2008-01-18 16:09:05  heinemann
 * <br>code cleanup and java doc
 * <br>
 * <br>Revision 1.10  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.9  2007-11-05 13:35:06  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.8  2007-11-05 10:21:06  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2007-09-17 13:06:04  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.6  2007-09-11 15:02:28  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.8  2007/08/29 11:05:07  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2007/08/29 07:54:24  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.6  2007/08/29 05:35:58  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.5  2007/08/28 09:16:14  hermen
 * <br>appointment types per calendar
 * <br>
 * <br>Revision 1.4  2007/08/23 08:57:30  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.3  2007/08/22 11:59:53  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.2  2007/08/09 14:10:34  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1  2007/07/19 14:09:47  heinemann
 * <br>*** empty log message ***
 * <br>
 *   
 */
public class FreeAppointmentFindDialog extends JDialog implements ActionListener, PropertyChangeListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * The logger Object for this class
	 */
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(FreeAppointmentFindDialog.class.getName());
	
	public static final String PROPOSAL_CHANGED = "propChanged";
	
	public static final String DIALOG_CLOSED = "dialogClosed";
	
	// Strings for the action commands of buttons
	private static final String CMD_BOX  = "box";
	private static final String CMD_WEEK = "week";
	private static final String CMD_TODAY = "today";
	
	// constants to mark the reset method to fade
	// to the current appointment or not
	private static final boolean FADE    = true;
	private static final boolean NO_FADE = false;
		
	private CellConstraints cc;


	private JPanel leftPanel;


	private JPanel mainPanel;


	private JLabel nameLabel;


	private JTextField nameTextField;


	private JButton nameSearchButton;


	private JPanel weekButtonPanel;


	private JDateChooser targetDateChooser;


	private JPanel proposalPanel;


	private JPanel rightPanel;


	private JLabel typeLabel;


	private JComboBox typeBox;


	private JLabel calendarLabel;


	private JComboBox calendarBox;


	private JPanel typePanel;


	private JPanel timeConstraintPanel;


	private ArrayList<JCheckBox> timeConstraintBoxes;


	private JButton nextProposalButton;


	private JButton okButton;


	private JButton cancelButton;


	private AbstractAction cancelAction;


	private AbstractAction okAction;


	private AbstractAction nextProposalAction;


	private AbstractAction searchPatientAction;
	
	protected Integer patientID;


	private JButton previousProposalButton;


	private AbstractAction previousProposalAction;


	private FreeAppointmentFinder appFinder;


	private AppointmentProposalArea proposalArea;


//	private int searchdays = 1;


	protected String patientNameTemp = "";

	private Appointment lastProposal;

	protected Appointment appointmentToUse;

	private boolean timeConstraintsChanged = false;

	private JLabel warningLabel;

	private AbstractAction previousDayAction;

	private AbstractAction nextDayAction;

	private JButton buttonMinus;

	private JButton buttonPlus;

	protected boolean listenersActive = true;
	
	public FreeAppointmentFindDialog() {
		/* ================================================== */
		this(false);
		/* ================================================== */
	}
	/**
	 * 
	 */
		/* ================================================== */
	public FreeAppointmentFindDialog(boolean debug) {
		super(MainFrame.getInstance(), Translatrix.getTranslationString("Agenda.findfree.header"));
	}
	
	public void init(boolean debug)
	{
		/* ------------------------------------------------------- */
		this.setLayout(new BorderLayout());
		this.getContentPane().setBackground(Color.WHITE);
		this.getContentPane().setBackground(GECAMedColors.c_GECAMedBackground);
		/* ------------------------------------------------------- */
		initComponent();
		if (!debug)
			initComboBoxes();
		initDateChooser();
		this.addWindowListener(new WindowAdapter() {

			/* (non-Javadoc)
			 * @see java.awt.event.WindowAdapter#windowClosed(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowClosing(WindowEvent e) {
				/* ====================================================== */
				appointmentToUse = null;
				FreeAppointmentFindDialog.this.firePropertyChange(DIALOG_CLOSED, "eins", null);
				super.windowClosed(e);
				setVisible(false);
//				AgendaModule.getInstance().fetchEventsForAllCalendars();
				/* ====================================================== */
			}
			
		});
		/* ================================================== */
	}
	
	/**
	 * @param patient
	 */
	public void setPatient(Patient patient) {
		/* ================================================== */
		if (patient == null) {
			this.patientID = null;
			nameTextField.setText("");
			return;
		}
			
		this.patientID = patient.getId();
//		String s = "";
//		if (patient.getMaidenName() != null && !"".equals(patient.getMaidenName()))
//			s = patient.getMaidenName();
//		else
//			if (patient.getSurName() != null)
//				s = patient.getSurName();
//		/* ------------------------------------------------------- */
//		if (patient.getFirstName() != null)
//			s = s + " " + patient.getFirstName();
//		this.patientNameTemp = s.trim();
//		nameTextField.setText(s.trim());
		this.patientNameTemp = patient.toShortString();
		nameTextField.setText(patient.toShortString());
		/* ------------------------------------------------------- */
		// set the patient
		/* ------------------------------------------------------- */
		lastProposal.setPatientId(patientID);
//		lastProposal.setSummary(s.trim());
		lastProposal.setSummary(patient.toShortString());
		firePropertyChange(PROPOSAL_CHANGED, null, lastProposal);
		/* ================================================== */
	}
	
	/**
	 * Set the appointmentFinder
	 * 
	 * @param finder
	 */
	public void setAppointmentFinder(FreeAppointmentFinder finder) {
		/* ================================================== */
		this.appFinder = finder;
//		this.appFinder.addPropertyChangeListener(this);
		/* ================================================== */
	}
	
	
	/**
	 * Set the appointment to the gui
	 * 
	 * @param app
	 */
	public void setAppointmentToView(Appointment app) {
		/* ================================================== */
		if (app == null) {
			this.proposalArea.setVisible(false);
			return;
		}
		AgendaCalendar cal = (AgendaCalendar) calendarBox.getSelectedItem();
		
		this.proposalArea.setAppointment(app, new Color(cal.getColor()));
		app.setCalendarId(cal.getId());
		app.setTypeId(getSelectedTypeId());
		/* ------------------------------------------------------- */
		app.setPatientId(patientID);
		app.setSummary(nameTextField.getText());
		
		/* ------------------------------------------------------- */
		// if in the past
		if (app.getStartDate().before(new Date())) {
			this.warningLabel.setVisible(true);
		}
		else
			this.warningLabel.setVisible(false);
		/* ------------------------------------------------------- */
		this.proposalArea.setVisible(true);
		/* ------------------------------------------------------- */
		this.lastProposal = app;
		firePropertyChange(PROPOSAL_CHANGED, null, lastProposal);
		/* ------------------------------------------------------- */
		proposalPanel.validate();
		proposalPanel.updateUI();
		/* ================================================== */
	}
	
	
	
	/**
	 * Init components
	 */
	private void initComponent() {
		/* ====================================================== */
		/* ------------------------------------------------------- */
		// header
		JPanel header = new JPanel(new FormLayout("3dlu, fill:pref:grow, 3dlu" , "3dlu, fill:pref, 3dlu"));
		header.setOpaque(false);
		
		JLabel lHeader = new JLabel("<html>"+Translatrix.getTranslationString("Agenda.findfree.header"));
		lHeader.setOpaque(true);
		lHeader.setBackground(Color.WHITE);
		lHeader.setBorder(BorderFactory.createTitledBorder(""));
		/* ------------------------------------------------------- */
		lHeader.setIcon(GECAMedModule.getIcon(GECAMedIconNames.INFO));
		/* ------------------------------------------------------- */
		lHeader.setVerticalTextPosition(SwingConstants.TOP);
		lHeader.setHorizontalTextPosition(SwingConstants.RIGHT);
		CellConstraints cc = new CellConstraints();
		header.add(lHeader, cc.xy(2, 2));
		/* ------------------------------------------------------- */
//		this.add(header, BorderLayout.NORTH);
		/* ------------------------------------------------------- */
		this.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				/* ====================================================== */
//				appointment = null;
				setVisible(false);
				/* ====================================================== */
			}
		});
		/* ------------------------------------------------------- */
		
		
		this.mainPanel = new JPanel();
		// main layout, 3 columns and 3 rows
		this.mainPanel.setLayout(new FormLayout(
				// cols
				"3dlu," +
				"fill:pref:grow," +
				"center:5dlu," +
				"fill:pref:grow," +
				"3dlu",
				// rows
				"3dlu," +
				"fill:pref:grow," +
				"3dlu"));
		this.cc = new CellConstraints();
		/* ------------------------------------------------------- */
		this.mainPanel.setBackground(GECAMedColors.c_GECAMedBackground);
		/* ------------------------------------------------------- */
		// separator in the middle
//		this.mainPanel.add(new JSeparator(SwingConstants.VERTICAL), cc.xy(3, 2));
		/* ------------------------------------------------------- */
		initLeftPanel();
		initRightPanel();
		mainPanel.add(leftPanel,  cc.xy(2, 2));
		mainPanel.add(rightPanel, cc.xy(4, 2));
		
		
		this.add(mainPanel, BorderLayout.CENTER);
		
		initButtonPanel();
		initButtonActions();
		/* ====================================================== */
	}
	
	
	/**
	 * Init the right panel
	 */
	private void initRightPanel() {
		/* ================================================== */
		this.rightPanel = new JPanel(new FormLayout(
				// cols
				"1dlu," +
				"fill:pref:grow," +
				"3dlu," +
				"fill:pref:grow," +
				"1dlu",
				// rows
				"1dlu," +			// 1
				"fill:pref," +		// 2
				"5dlu," +			// 3
				"fill:pref," +		// 4
				"5dlu," +			// 5
				"20dlu," +			// 6
				"1dlu"));			// 7 
		/* ------------------------------------------------------- */
		rightPanel.setOpaque(false);
		/* ------------------------------------------------------- */
		/* ------------------------------------------------------- */
		// type
		/* ------------------------------------------------------- */
		this.typeLabel = new JLabel(Translatrix.getTranslationString("calendar.core.type")+":");
		this.typeLabel.setIcon(AgendaModule.getMiniIcon(AgendaModule.TYPE));
		this.typeLabel.setHorizontalTextPosition(SwingConstants.RIGHT);

		this.typeBox = new JComboBox();

		/* ------------------------------------------------------- */
		// calendar
		/* ------------------------------------------------------- */
		this.calendarLabel = new JLabel(Translatrix.getTranslationString("calendar")+":");
		this.calendarLabel.setIcon(AgendaModule.getMiniIcon(AgendaModule.ICON_AGENDA));
		this.calendarLabel.setHorizontalTextPosition(SwingConstants.RIGHT);

		this.calendarBox = new JComboBox();

		/* ------------------------------------------------------- */
		// panel
		/* ------------------------------------------------------- */
		this.typePanel = new JPanel(new FormLayout(
				// cols
				"3dlu, fill:pref:grow,3dlu",
				//rows
				"3dlu," +
				"fill:pref," +
				"2dlu," +
				"fill:pref," +
				"3dlu," +
				"fill:pref," +
				"2dlu," +
				"fill:pref," +
				"3dlu"));

		this.typePanel.add(this.calendarLabel, cc.xy(2, 2));
		this.typePanel.add(this.calendarBox, cc.xy(2, 4));
		
		this.typePanel.add(this.typeLabel, cc.xy(2, 6));
		this.typePanel.add(this.typeBox, cc.xy(2, 8));

		this.typePanel.setBorder(BorderFactory.createTitledBorder(Translatrix.getTranslationString("calendar")));
		this.typePanel.setOpaque(false);
		/* ------------------------------------------------------- */
		
		/* ------------------------------------------------------- */
		// time constraints
		/* ------------------------------------------------------- */
		this.timeConstraintPanel = new JPanel(new GridLayout(0, 1));
		timeConstraintPanel.setOpaque(false);
		this.timeConstraintBoxes = new ArrayList<JCheckBox>();
		timeConstraintPanel.setBorder(BorderFactory.createTitledBorder(
				Translatrix.getTranslationString("Agenda.findfree.timeconstraints")));
		// create the checkboxes
		Date dayStart  = (Date) AgendaModule.getInstance().getAgendaSettingsPlugin().getValue(AgendaSettingsPlugin.START_HOUR);
		Date dayStop   = (Date) AgendaModule.getInstance().getAgendaSettingsPlugin().getValue(AgendaSettingsPlugin.STOP_HOUR);
		
		TimeInterval dayStartStop = new TimeInterval(dayStart, dayStop);
		int dayStartTime   = dayStartStop.getStarttime();
		int dayEndTime   = dayStartStop.getEndtime();
		
		for (int i = 0; i < FreeAppointmentFinder.timeConstraint.length; i++) {
			/* ------------------------------------------------------- */
			TimeInterval inv = appFinder.timeTable.get(FreeAppointmentFinder.timeConstraint[i]);
			String startTime = inv.getStarttime()/100 < 10 ? "0" + inv.getStarttime()/100 + ":00" : inv.getStarttime()/100 + ":00";
			String endTimeMin = inv.getEndtime()%100 < 10 ? "0" + inv.getEndtime()%100 : "" + inv.getEndtime()%100;
			String endTime = inv.getEndtime()/100 < 10 ? "0" + inv.getEndtime()/100 + ":" + endTimeMin : inv.getEndtime()/100 + ":" + endTimeMin;

			JCheckBox box = new JCheckBox(
					Translatrix.getTranslationString("Agenda.findfree.constraints." + FreeAppointmentFinder.timeConstraint[i]
					) + " | " + startTime  + " - " + endTime);
			
			box.setActionCommand(CMD_BOX+i);
			box.setOpaque(false);
			timeConstraintPanel.add(box);
			this.timeConstraintBoxes.add(box);
			box.addActionListener(this);
			// check if constraint boxes in the office time
			if(
					inv.getStarttime() >= dayStartTime && inv.getStarttime() <= dayEndTime
					||
					inv.getEndtime() >= dayStartTime && inv.getEndtime() <= dayEndTime
					) 
				box.setEnabled(true);
				else box.setEnabled(false);
				
			/* ------------------------------------------------------- */
		}
		
		/* ------------------------------------------------------- */
		// assemble
		rightPanel.add(typePanel , cc.xyw(2, 2, 3));
		rightPanel.add(timeConstraintPanel , cc.xyw(2, 4, 3));
//		rightPanel.add(previousProposalButton, cc.xy(2, 6));
//		rightPanel.add(nextProposalButton , cc.xy(4, 6));
		/* ================================================== */
	}
	

	/**
	 * init the left panel
	 */
	private void initLeftPanel() {
		/* ====================================================== */
		this.leftPanel = new JPanel(new FormLayout(
				// cols
				"1dlu," +			// 1
				"fill:pref:grow," +	// 2
				"1dlu", 			// 3
				// rows
				"1dlu," +			//  1
				"fill:pref," +		//  2
				"3dlu," +			//  3
				"fill:pref," +		//  4
				"center:6dlu," +	//  5
				"fill:pref," +		//  6
				"center:6dlu," +	//  7
				"fill:pref," +		//  8
				"3dlu," +			//  9
				"fill:pref," +		// 10
				"center:6dlu," +	// 11
				"fill:pref:grow," + // 12
				"1dlu"				// 13
				));
		/* ------------------------------------------------------- */
		this.leftPanel.setOpaque(false);
		/* ------------------------------------------------------- */
		// name
		this.nameLabel = new JLabel(Translatrix.getTranslationString("calendar.core.title")+":");
		this.nameLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
		/* ------------------------------------------------------- */
		this.nameTextField = new JTextField(20);
		this.nameTextField.setToolTipText(Translatrix.getTranslationString("calendar.newEvent.searchPatient"));
		this.nameSearchButton = new JButton();
		/* ------------------------------------------------------- */
		this.nameSearchButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
		// panel for textfield and search button
		JPanel namePanel = new JPanel(new BorderLayout(0, 10));
		namePanel.setOpaque(false);
		namePanel.add(this.nameTextField, BorderLayout.CENTER);
		namePanel.add(this.nameSearchButton, BorderLayout.EAST);
		/* ------------------------------------------------------- */
		// week buttons
		JPanel weekButtonPanelIntern = new JPanel(new GridLayout(0, 3));
		this.weekButtonPanel = new JPanel(new BorderLayout());
		/* ------------------------------------------------------- */
		JButton toDayButton = new JButton();
		toDayButton.setText(Translatrix.getTranslationString("Agenda.findfree.today"));
		/* ------------------------------------------------------- */
		toDayButton.addActionListener(this);
		toDayButton.setActionCommand(CMD_TODAY);
		toDayButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
		/* ------------------------------------------------------- */
		weekButtonPanelIntern.add(toDayButton);
		
		for (int i = 1; i < 6; i++) {
			/* ------------------------------------------------------- */
			JButton weekButton = new JButton();
			if (i == 1)
				weekButton.setText(i+" "+Translatrix.getTranslationString("Agenda.findfree.week"));
			else
				weekButton.setText(i+" "+Translatrix.getTranslationString("Agenda.findfree.weeks"));
			/* ------------------------------------------------------- */
			weekButton.addActionListener(this);
			weekButton.setActionCommand(CMD_WEEK+i);
			weekButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
			/* ------------------------------------------------------- */
			weekButtonPanelIntern.add(weekButton);
			/* ------------------------------------------------------- */
		}
		/* ------------------------------------------------------- */
		// day plus / day minus button
		this.buttonMinus = new JButton();
		this.buttonPlus  = new JButton();
		
		buttonMinus.setMargin(new java.awt.Insets(0, 0, 0, 0));
		buttonPlus.setMargin( new java.awt.Insets(0, 0, 0, 0));
		
		weekButtonPanel.add(buttonMinus, BorderLayout.WEST);
		weekButtonPanel.add(buttonPlus, BorderLayout.EAST);
		/* ------------------------------------------------------- */
		// previous and next button
		this.previousProposalButton = new JButton();
		this.nextProposalButton = new JButton();
		
		weekButtonPanel.add(previousProposalButton, BorderLayout.NORTH);
		weekButtonPanel.add(nextProposalButton, BorderLayout.SOUTH);
		
		
		/* ------------------------------------------------------- */
		weekButtonPanel.add(weekButtonPanelIntern, BorderLayout.CENTER);
		/* ------------------------------------------------------- */
		// target date
		JLabel targetDateLabel = new JLabel(Translatrix.getTranslationString("Agenda.findfree.targetDate"));
		this.targetDateChooser = GECAMedGuiUtils.getDateChooser(false);
		
		/* ------------------------------------------------------- */
		// proposal
		this.proposalPanel = new JPanel(new BorderLayout(5, 5));
		this.proposalPanel.setBorder(BorderFactory.createTitledBorder(
					Translatrix.getTranslationString("Agenda.findfree.proposal")));
		proposalPanel.setOpaque(false);
		proposalPanel.add(new JLabel(""), BorderLayout.NORTH);
		proposalPanel.add(new JLabel(""), BorderLayout.EAST);
		proposalPanel.add(new JLabel(""), BorderLayout.SOUTH);
		proposalPanel.add(new JLabel(""), BorderLayout.WEST);
				
		/* ------------------------------------------------------- */
		// assemble
		leftPanel.add(nameLabel, 			cc.xy(2,  2));
		leftPanel.add(namePanel, 			cc.xy(2,  4));
		/* ------------------------------------------------------- */
		leftPanel.add(new JSeparator(), 	cc.xy(2,  5));
		/* ------------------------------------------------------- */
		leftPanel.add(weekButtonPanel,		cc.xy(2,  6));
		/* ------------------------------------------------------- */
		leftPanel.add(new JSeparator(), 	cc.xy(2,  7));
		/* ------------------------------------------------------- */
		leftPanel.add(targetDateLabel,		cc.xy(2,  8));
		leftPanel.add(targetDateChooser,	cc.xy(2, 10));
		/* ------------------------------------------------------- */
		leftPanel.add(proposalPanel,		cc.xy(2, 12));
		/* ------------------------------------------------------- */
		
		/* ------------------------------------------------------- */
		this.proposalArea = new AppointmentProposalArea();
		proposalArea.setAlphaValue(0.1f);
		/* ------------------------------------------------------- */
		proposalArea.showHeader(false);
		/* ------------------------------------------------------- */
		proposalPanel.add(proposalArea);
		proposalArea.setVisible(false);
		/* ====================================================== */
	}
	
	/**
	 * 
	 */
	private void initButtonPanel() {
		/* ================================================== */
		/* ------------------------------------------------------- */
		// ==========================================================
		// button panel
		// ==========================================================
		this.okButton 		= new JButton();
		this.cancelButton 	= new JButton();
		ButtonBarBuilder bb = new ButtonBarBuilder();
		/* ------------------------------------------------------- */
		// label for warning messages
		this.warningLabel = new JLabel(Translatrix.getTranslationString("Agenda.findfree.eventInThePast"));
		warningLabel.setForeground(Color.RED);
		warningLabel.setVisible(false);
		/* ------------------------------------------------------- */
		warningLabel.setIcon(GECAMedModule.getMediumIcon(GECAMedIconNames.WARNING));
		warningLabel.setVerticalTextPosition(SwingConstants.CENTER);
		warningLabel.setHorizontalTextPosition(SwingConstants.TRAILING);
		
		
		/* ------------------------------------------------------- */
		bb.addRelatedGap();
		bb.addFixed(warningLabel);
		bb.addGlue();
		bb.addGridded(okButton);
		bb.addUnrelatedGap();
		bb.addGridded(cancelButton);
		/* ------------------------------------------------------- */
		bb.getPanel().setOpaque(false);
		/* ------------------------------------------------------- */
		// a panel to make a gap between the dialog border and the buttons
		JPanel gapPanel = new JPanel(new BorderLayout(5,5));
		gapPanel.setOpaque(true);
		gapPanel.setBackground(Color.WHITE);
		gapPanel.add(bb.getPanel(), BorderLayout.CENTER);
		gapPanel.add(new JLabel(""), BorderLayout.SOUTH);
		gapPanel.add(new JLabel(""), BorderLayout.EAST);
		gapPanel.add(new JLabel(""), BorderLayout.NORTH);
		/* ------------------------------------------------------- */
//		gapPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		/* ------------------------------------------------------- */

		this.add(gapPanel, BorderLayout.SOUTH);
		/* ================================================== */
	}
	
	
	/**
	 * 
	 */
	private void initDateChooser() {
		/* ================================================== */
		this.targetDateChooser.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				/* ====================================================== */
				
				if ("date".equals(evt.getPropertyName())) {
					int tDays = DateUtil.getDateDiff(targetDateChooser.getDate(), new Date());
					resetFinder(NO_FADE);
					switchToDay(tDays+1);
				}
				/* ====================================================== */
			}

			});
		/* ================================================== */
	}
	
	/**
	 * 
	 */
	private void initButtonActions() {
		/* ================================================== */
		this.cancelAction = new AbstractAction(Translatrix.getTranslationString("calendar.core.cancel"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				appointmentToUse = null;
				FreeAppointmentFindDialog.this.firePropertyChange(DIALOG_CLOSED, "eins", null);
				setVisible(false);
//				AgendaModule.getInstance().fetchEventsForAllCalendars();
				/* ====================================================== */
			}
		};
		/* ------------------------------------------------------- */
		this.okAction = new AbstractAction(Translatrix.getTranslationString("calendar.core.ok"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.OK)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				appointmentToUse = lastProposal;
				FreeAppointmentFindDialog.this.firePropertyChange(DIALOG_CLOSED, "eins", appointmentToUse);
				setVisible(false);
				/* ====================================================== */
			}
		};

		this.okButton.setAction(okAction);
		this.cancelButton.setAction(cancelAction);

		// =================================================================
		// N E X T
		// =================================================================
		// Translatrix.getTranslationString("Agenda.findfree.next")
		this.nextProposalAction = new AbstractAction("", AgendaModule.getMediumIcon(AgendaModule.NEXT))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
//				Appointment last = appFinder.getLastProposal();
				/* ------------------------------------------------------- */
				// set time constraints
				if (timeConstraintsChanged) {
					appFinder.setTimeConstraint(getTimeConstraint());
					timeConstraintsChanged = false;
				}
				/* ------------------------------------------------------- */
				Appointment ap = appFinder.next();
//				if (ap != null)
//					previousProposalButton.setEnabled(true);
//				if (ap != null && ap.equals(last))
//					ap = appFinder.next();
				/* ------------------------------------------------------- */
				setAppointmentToView(ap);
				/* ====================================================== */
			}
		};
		this.nextProposalButton.setAction(nextProposalAction);
		

		// =================================================================
		// P R E V I O U S
		// =================================================================
		// Translatrix.getTranslationString("Agenda.findfree.previous")
		this.previousProposalAction = new AbstractAction("", AgendaModule.getMediumIcon(AgendaModule.PREVIOUS))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
//				Appointment last = appFinder.getLastProposal();
				/* ------------------------------------------------------- */
				// set time constraints
				if (timeConstraintsChanged) {
					appFinder.setTimeConstraint(getTimeConstraint());
					timeConstraintsChanged = false;
				}
				/* ------------------------------------------------------- */
				Appointment ap = appFinder.previous();
					
				/* ------------------------------------------------------- */
				setAppointmentToView(ap);
				/* ====================================================== */
			}
		};
		this.previousProposalButton.setAction(previousProposalAction);
		
		
		
		// =================================================================
		// P R E V I O U S  -  D A Y
		// =================================================================
		this.previousDayAction = new AbstractAction("", AgendaModule.getMediumIcon(AgendaModule.PREVIOUS_DAY)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				// set time constraints
				if (timeConstraintsChanged) {
					appFinder.setTimeConstraint(getTimeConstraint());
					timeConstraintsChanged = false;
				}
				// shift to previous day
				Appointment previousDayApp = appFinder.previousDay();
				setAppointmentToView(previousDayApp);
				/* ====================================================== */
			}
		};
		
		this.buttonMinus.setAction(this.previousDayAction);
		this.buttonMinus.setToolTipText(Translatrix.getTranslationString("Agenda.findfree.previousDay"));
		
		// =================================================================
		// N E X T - D A Y
		// =================================================================
		this.nextDayAction = new AbstractAction("", AgendaModule.getMediumIcon(AgendaModule.NEXT_DAY)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				// set time constraints
				if (timeConstraintsChanged) {
					appFinder.setTimeConstraint(getTimeConstraint());
					timeConstraintsChanged = false;
				}
				// shift to next day
				Appointment nextDayApp = appFinder.nextDay();
				setAppointmentToView(nextDayApp);
				/* ====================================================== */
			}
		};
		this.buttonPlus.setAction(nextDayAction);
		this.buttonPlus.setToolTipText( Translatrix.getTranslationString("Agenda.findfree.nextDay"));
		// ===================================================
		// S E A R C H Action
		// ===================================================
		this.searchPatientAction = new AbstractAction("", GECAMedModule.getMiniIcon(GECAMedIconNames.SEARCH)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				Patient p = PatientSearchDialog.searchPatient(nameTextField.getText());
				if (p == null)
					return;
				/* ------------------------------------------------------- */
				setPatient(p);
				/* ====================================================== */
			}

		};

		this.nameSearchButton.setAction(this.searchPatientAction);
		this.nameSearchButton.setToolTipText(Translatrix.getTranslationString("calendar.newEvent.searchPatient"));
		// =================================================================

		
		
		// =================================================================
		// define dialog wide key mappings
		// =================================================================
		KeyStroke strokeEsc = KeyStroke.getKeyStroke("ESCAPE");

		((JPanel) this.getContentPane()).getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
					.put(strokeEsc, "continue");
		((JPanel) this.getContentPane()).getActionMap().put("continue", cancelAction);
		/* ================================================== */
	}
	
	
	/**
	 * fill comboboxes
	 */
	private void initComboBoxes() {
		/* ================================================== */

		this.calendarBox.setRenderer(new CalendarComboBoxRenderer());

		GECAMedLists.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				/* ====================================================== */
				if (evt.getPropertyName().equals(AgendaCalendar.class.getSimpleName())) {
					/* ------------------------------------------------------- */
					refreshCalendars();
					/* ------------------------------------------------------- */
				}
			}
		}, AgendaCalendar.class);

		// the calendars
//		if (GECAMedLists.getArray(AgendaCalendar.class) == null) {
//			// try to obtain the calendars
//			AgendaModule.loadCalendars();
//		} else
			refreshCalendars();

		// ============================================================
		// load the appointment types
		// into GECAMedList and in the combobox
		// ============================================================

		this.typeBox.setRenderer(new AppointmentTypeComboBoxRenderer());

		GECAMedLists.addPropertyChangeListener(new PropertyChangeListener() {

			public void propertyChange(PropertyChangeEvent evt) {
				/* ====================================================== */
				if (evt.getPropertyName().equals(AppointmentType.class.getSimpleName())) {
					refreshAppointmentTypes();
				}
				/* ====================================================== */
			}

		}, AppointmentType.class);
		
//		if (GECAMedLists.getArray(AppointmentType.class) == null)
//			AgendaModule.loadApointmentTypes();
//		else
			refreshAppointmentTypes();
		/* ------------------------------------------------------- */
		
		
		/* ------------------------------------------------------- */
		// change listener for the comboboxes to update
		// the search set
		this.calendarBox.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				if (! listenersActive ) return;
				/* ====================================================== */
				// set new calendar
				AgendaCalendar cal = (AgendaCalendar) calendarBox.getSelectedItem();
				lastProposal.setCalendarId(cal.getId());
				// refresh the appointment types
				refreshAppointmentTypes();
				// select calendar in the navibar
				AgendaModule.getInstance().selectCalendar(lastProposal.getCalendarId());
				// set appoinment type
				AppointmentType type = getSelectedType();
				if (type != null)
					lastProposal.setEndDate(DateUtil.moveByMinute(lastProposal.getStartDate(), type.getDuration()));
				else
					lastProposal.setEndDate(DateUtil.moveByMinute(lastProposal.getStartDate(), 30));
				// show appointment in view
				setAppointmentToView(lastProposal);
//				// select calendar in the navibar
//				AgendaModule.getInstance().selectCalendar(lastProposal.getCalendarId());
				pack();
				/* ====================================================== */
			}
		});
		
		this.typeBox.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e)
			{
				if (! listenersActive) return;
				/* ====================================================== */
				// Set the new duration to the appointment and show it in View
				lastProposal.setTypeId(getSelectedTypeId());
				AppointmentType type = getSelectedType();
				if (type != null)
					lastProposal.setEndDate(DateUtil.moveByMinute(lastProposal.getStartDate(), type.getDuration()));
				else
					lastProposal.setEndDate(DateUtil.moveByMinute(lastProposal.getStartDate(), 30));
				
				setAppointmentToView(lastProposal);
				/* ====================================================== */
			}
		});
		/* ================================================== */
	}
	
	
	/**
	 * @param days
	 */
	private void switchToDay(int days) {
		/* ================================================== */
		this.resetFinder(NO_FADE);
		if (days > 0) {
			/* ------------------------------------------------------- */
			// forward
			Appointment ap = appFinder.nextDays(days);
			setAppointmentToView(ap);
			/* ------------------------------------------------------- */
		} else
			if (days < 0) {
				/* ------------------------------------------------------- */
				// backwards
				Appointment ap = appFinder.previousDays(days);
				setAppointmentToView(ap);
				/* ------------------------------------------------------- */
			}
		/* ================================================== */
	}
	
	
	/**
	 * Show the dialog
	 */
	public void showDialog(AgendaCalendar calendar) {
		/* ================================================== */
		// reset the time constraints
		resetTimeConstraints();
		appFinder.setTimeConstraint(null);
		/* ------------------------------------------------------- */
		// reset name
		this.nameTextField.setText("");
		// reset date chooser to today
		this.targetDateChooser.setDate(new Date());
		/* ------------------------------------------------------- */
		this.calendarBox.setSelectedItem(calendar);
		/* ------------------------------------------------------- */
		this.pack();
		MainFrame.showDialogCentered(this);
		
//		 create an initial Appointment to start
		resetFinder(FADE);
		/* ================================================== */
	}
	
	/**
	 * Call after the the dialog has been closed to get the selected appointment
	 * 
	 * @return
	 */
	public Appointment getAppointment() {
		/* ================================================== */
		return this.appointmentToUse;
		/* ================================================== */
	}
	
	/**
	 * Resets the finder to an appointment starting now
	 * 
	 * @param fade if true, the view is fading to the appointment
	 */
	private void resetFinder(boolean fade) {
		/* ================================================== */
		final Appointment ai = new Appointment();
		ai.setCalendarId(((AgendaCalendar) calendarBox.getSelectedItem()).getId());
		ai.setTypeId(getSelectedTypeId());
		/* ------------------------------------------------------- */
		// set the start date
		/* ------------------------------------------------------- */
		ai.setStartDate(DateUtil.roundNice(new Date()));
		/* ------------------------------------------------------- */
		// set the end date. If a type is selected, we take the
		// defined duration. Otherwise, 30 minutes
		/* ------------------------------------------------------- */
		AppointmentType type = getSelectedType();
		if (type != null)
			ai.setEndDate(DateUtil.moveByMinute(ai.getStartDate(), type.getDuration()));
		else
			ai.setEndDate(DateUtil.moveByMinute(ai.getStartDate(), 30));
		/* ------------------------------------------------------- */
		appFinder.setLastProposal(ai);
		/* ------------------------------------------------------- */
		if (fade) {
			SwingUtilities.invokeLater(new Runnable() {

				public void run() {
					/* ====================================================== */
					fadeToAppointment(ai);
					/* ====================================================== */
				}
				
			});
		}
		/* ================================================== */
	}
	//TODO
//	private void resetFinder(boolean fade) {
//		/* ================================================== */
//		final Appointment ai = new Appointment();
//		ai.setCalendarId(((AgendaCalendar) calendarBox.getSelectedItem()).getId());
//		ai.setTypeId(getSelectedTypeId());
//		/* ------------------------------------------------------- */
//		// set the start date
//		/* ------------------------------------------------------- */
//		ai.setStartDate(DateUtil.roundNice(new Date()));
//		/* ------------------------------------------------------- */
//		// set the end date. If a type is selected, we take the
//		// defined duration. Otherwise, 30 minutes
//		/* ------------------------------------------------------- */
//		AppointmentType type = getSelectedType();
//		if (type != null)
//			ai.setEndDate(DateUtil.moveByMinute(ai.getStartDate(), type.getDuration()));
//		else
//			ai.setEndDate(DateUtil.moveByMinute(ai.getStartDate(), 30));
//		/* ------------------------------------------------------- */
//		appFinder.setLastProposal(ai);
//		/* ------------------------------------------------------- */
//		if (fade) {
//			SwingUtilities.invokeLater(new Runnable() {
//
//				public void run() {
//					/* ====================================================== */
//					fadeToAppointment(ai);
//					/* ====================================================== */
//				}
//				
//			});
//		}
//		/* ================================================== */
//	}
	
	/**
	 *
	 */
	private void refreshCalendars() {
		/* ================================================== */
	    	listenersActive = false;
		// get calendars from GECAMedLists
		List<AgendaCalendar> cals = GECAMedLists.getListReference(AgendaCalendar.class);
		/* ------------------------------------------------------- */
		try {
		    calendarBox.removeAllItems();
		} catch (Exception e) {
		    e.printStackTrace();
		}

		if (cals.size() > 0)
			for (AgendaCalendar obj : cals) {
				if(!obj.isBackground())
					calendarBox.addItem(obj);
		}
		listenersActive = true;
		/* ================================================== */
	}

	/**
	 * Refresh appointment types
	 */
	private void refreshAppointmentTypes() {
	    listenersActive = false;
	    /* ================================================== */
	    try {
		this.typeBox.removeAllItems();
	    } catch (Exception e) {
		e.printStackTrace();
	    }

		// get the list of appointments for the calendar
		AgendaCalendar selectedCalendar = (AgendaCalendar) calendarBox.getSelectedItem();
		/* ------------------------------------------------------- */
		if (selectedCalendar == null)
			return;
		/* ------------------------------------------------------- */
		try {
			/* ------------------------------------------------------- */
			AppointmentManager aManager = (AppointmentManager)
				ManagerFactory.getRemote(AppointmentManagerBean.class);
			
			Collection<AppointmentType> result = aManager.getAppointmentTypesByID(
													AppointmentType.GENERAL,
													selectedCalendar.getId(),
													false);
			
			if (result != null) {
				/* ------------------------------------------------------- */
				for (AppointmentType t : result)
					typeBox.addItem(t);
				/* ------------------------------------------------------- */
			}
			/* ------------------------------------------------------- */
		} catch (Exception e) {
			e.printStackTrace();
		}
		listenersActive = true;
		/* ================================================== */
	}

	
	/**
	 * @param app
	 */
	public void fadeToAppointment(Appointment app) {
		/* ================================================== */
		appFinder.setLastProposal(app);
		Appointment a = appFinder.next();
//		Appointment a = appFinder.getFreeAppointment(app, AppointmentManager.FORWARD);
		setAppointmentToView(a);
		/* ================================================== */
	}
	
	/**
	 * week buttons
	 */
	public void actionPerformed(ActionEvent e) {
		/* ====================================================== */
		int days = 0;
		// first the today
		if(CMD_TODAY.equals(e.getActionCommand()))
		{
			Date startDate = lastProposal.getStartDate();
			Date endDate = lastProposal.getEndDate();
			try {
				startDate  = (DateUtil.setTimeOfDate(new Date(), DateUtil.getTimeOfDay(startDate)));
				endDate  = (DateUtil.setTimeOfDate(new Date(), DateUtil.getTimeOfDay(endDate)));
			} catch (Exception ex) {
				logger.log(Level.WARN, "Couldn't set start and end date of appointment to todays date.", ex);
			}
			lastProposal.setStartDate(startDate);
			lastProposal.setEndDate(endDate);
			appFinder.setTimeConstraint(getTimeConstraint());
			timeConstraintsChanged = false;
			Appointment ap = appFinder.next();//appFinder.getFreeAppointment(lastProposal, FORWARD);
			setAppointmentToView(ap);
			return;
		} else
		// second the week buttons
		if ((CMD_WEEK+"1").equals(e.getActionCommand())) {
			days = FreeAppointmentFinder.WEEK_1;
		} else 
		if ((CMD_WEEK+"2").equals(e.getActionCommand())) {
			days = FreeAppointmentFinder.WEEK_2;
		} else
		if ((CMD_WEEK+"3").equals(e.getActionCommand())) {
			days = FreeAppointmentFinder.WEEK_3;
		} else
		if ((CMD_WEEK+"4").equals(e.getActionCommand())) {
			days = FreeAppointmentFinder.WEEK_4;
		} else
		if ((CMD_WEEK+"5").equals(e.getActionCommand())) {
			days = FreeAppointmentFinder.WEEK_5;
		} else {
			// thirdly, the timeconstraint boxes
			if (e.getActionCommand().startsWith(CMD_BOX)) {
				// set state to reload proposals because
				// the limiting time constraints may have changed
				this.timeConstraintsChanged = true;
				return;
			}
			
		}
//		appFinder.setTimeConstraint(null);
		appFinder.setTimeConstraint(getTimeConstraint());
		timeConstraintsChanged = false;
		switchToDay(days);
		/* ====================================================== */
	}
	
	
	/**
	 * returns the id of the selected appointment type.
	 * 
	 * @return the id of the type, null if to type is selected
	 */
	private Integer getSelectedTypeId() {
		/* ================================================== */
		Integer id = null;
		try {
			/* ------------------------------------------------------- */
			id = ((AppointmentType) typeBox.getSelectedItem()).getId();
			/* ------------------------------------------------------- */
		} catch (Exception e) {}
		return id;
		/* ================================================== */
	}
	
	
	/**
	 * @return
	 */
	private AppointmentType getSelectedType() {
		/* ================================================== */
		try {
			/* ------------------------------------------------------- */
			return ((AppointmentType) typeBox.getSelectedItem());
			/* ------------------------------------------------------- */
		} catch (Exception e) {}
		return null;
		/* ================================================== */
	}
	
	
	/**
	 * sets all timeconstraint checkboxes to unchecked
	 */
	private void resetTimeConstraints() {
		/* ================================================== */
		for (JCheckBox box : timeConstraintBoxes)
			box.setSelected(false);
		timeConstraintsChanged = false;
		/* ================================================== */
	}
	
	
	/**
	 * Returns a list of all selected time constraints
	 * 
	 * @return
	 */
	private List<String> getTimeConstraint() {
		/* ================================================== */
		ArrayList<String> returnList = new ArrayList<String>();
		for (JCheckBox box : timeConstraintBoxes) {
			/* ------------------------------------------------------- */
			if (box.isSelected()) {
				/* ------------------------------------------------------- */
				String s = box.getActionCommand().replaceFirst(CMD_BOX, "");
				// now convert string to int
				int pos = Integer.parseInt(s);
				if (null != FreeAppointmentFinder.timeConstraint[pos])
					returnList.add(FreeAppointmentFinder.timeConstraint[pos]);
				/* ------------------------------------------------------- */
			}
			/* ------------------------------------------------------- */
		}
		return returnList;
		/* ================================================== */
	}
	
	
	/**
	 * called by the appointment finder, when a proposal has been faded
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		/* ====================================================== */
		if (FreeAppointmentFinder.PROPOSAL_FADED.equals(evt.getPropertyName()))
			setAppointmentToView(appFinder.getLastProposal());
		/* ====================================================== */
	}

}