/*******************************************************************************
 * 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.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

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.interfaces.AppointmentManager;
import lu.tudor.santec.gecamed.agenda.gui.AgendaAdminSettingsPlugin;
import lu.tudor.santec.gecamed.agenda.gui.AgendaModule;
import lu.tudor.santec.gecamed.agenda.gui.DefaultNamedCalendar;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;

import bizcal.common.Event;
import bizcal.util.DateUtil;

import com.jgoodies.forms.builder.ButtonBarBuilder;

/**
 * Dialog to create and modify appointments. It offers panels to create normal appointment,
 * recurring appointments and holidays.
 * 
 * 
 * @author martin.heinemann@tudor.lu
 * 29.05.2007
 * 10:32:02
 *
 *
 * @version
 * <br>$Log: AppointmentCreateDialog.java,v $
 * <br>Revision 1.20  2013-12-27 18:08:17  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.19  2011-11-16 16:04:40  troth
 * <br>fix some warnings
 * <br>
 * <br>Revision 1.18  2011-11-07 15:35:24  troth
 * <br>Fix some GUI Bugs.
 * <br>
 * <br>Revision 1.17  2011-10-26 08:48:02  troth
 * <br>fix little bug - now the subframe 'Patient Appointments' closed when cancel the dialog
 * <br>
 * <br>Revision 1.16  2011-10-20 15:04:28  troth
 * <br>1. add new functions of ticket #879
 * <br>2. fix ticket #904
 * <br>3. new bizcal lib
 * <br>
 * <br>Revision 1.15  2011-10-05 15:28:13  troth
 * <br>Do some translations for Ticket #879.
 * <br>
 * <br>Revision 1.14  2011-10-05 10:53:56  troth
 * <br>clear up code
 * <br>
 * <br>Revision 1.13  2011-10-04 12:13:32  troth
 * <br>fix Ticket #892 - Patient matricule and treatment type automatically added to agenda entry description
 * <br>
 * <br>Revision 1.12  2011-09-22 15:28:52  troth
 * <br>Fist Version of function 'logging Agenda modifications in the admin log' Ticket #894 Logging for Agenda modifications
 * <br>
 * <br>Revision 1.11  2011-09-02 14:11:55  troth
 * <br>Add the new agenda appointment printing for patient function.
 * <br>
 * <br>Revision 1.10  2011-07-27 12:05:51  troth
 * <br>Translatrix // Translations
 * <br>
 * <br>Revision 1.9  2011-07-14 12:40:15  troth
 * <br>Fix Ticket #862 | Show future appointment of one patient.
 * <br>
 * <br>Revision 1.8  2011-06-28 13:48:27  troth
 * <br>testing agenda
 * <br>
 * <br>Revision 1.5  2011-05-12 12:49:14  troth
 * <br>Fix little Bug - Dialog was not reset to init values when create a new appointment.
 * <br>
 * <br>Revision 1.4  2011-05-11 15:07:08  troth
 * <br>fix followup bug of Ticket  839 http://santec.tudor.lu/trac/gecamed/ticket/839
 * <br>
 * <br>Revision 1.3  2011-05-10 16:50:52  troth
 * <br>code clean up
 * <br>
 * <br>Revision 1.2  2011-05-09 14:30:20  troth
 * <br>Fix Ticket 839: "End after [X] occurrences" not taken into account
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/839
 * <br>
 * <br>Revision 1.1  2011-04-04 11:38:31  troth
 * <br>Redesign of the appointment create dialog and the right navi bar.
 * <br>
 * <br>Revision 1.31  2011-02-16 10:47:41  troth
 * <br>check in new bizcal jar and add the new bizcal view layout to the agenda
 * <br>
 * <br>Revision 1.30  2009-12-01 16:22:34  mack
 * <br>Changes required by the introduction of locale parameter in DefaultNamedCalendar
 * <br>
 * <br>Revision 1.29  2008-09-25 09:42:27  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.28  2008-06-24 13:18:48  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.27  2008-05-30 11:46:43  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.26  2008-04-14 13:11:36  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.25  2008-02-28 15:36:27  heinemann
 * <br>moved loading of patient file to PatientManagerModule
 * <br>
 * <br>Revision 1.24  2008-02-27 08:22:10  heinemann
 * <br>removed buggy fading
 * <br>
 * <br>Revision 1.23  2008-01-18 16:09:05  heinemann
 * <br>code cleanup and java doc
 * <br>
 * <br>Revision 1.22  2008-01-03 14:44:46  heinemann
 * <br>cleaned imports
 * <br>
 * <br>Revision 1.21  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.10  2007/06/15 13:19:25  hermen
 * <br>startet implementing recurring events
 * <br>
 * <br>Revision 1.9  2007/06/12 11:31:47  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.8  2007/06/12 08:14:38  hermen
 * <br>split up NewAppointmentDialog and added HolidayPanel
 * <br>
 * <br>Revision 1.4  2007/06/04 11:37:27  heinemann
 * <br>fix for moving events between calendars
 * <br>
 *
 */
public class AppointmentCreateDialog extends JDialog implements ChangeListener, PropertyChangeListener, ComponentListener, WindowListener, WindowFocusListener {

	/**
	 *
	 */
	private static final long 				serialVersionUID = 1L;
	
	/** the logger Object for this class */
	private static Logger					logger = Logger.getLogger(AppointmentCreateDialog.class.getName());

	private static AppointmentCreateDialog 	instance = new AppointmentCreateDialog();

	private final String 					DEFAULT_CARD = Translatrix.getTranslationString("Agenda.appointment");
	
	private final String 					HOLIDAY_CARD = Translatrix.getTranslationString("Agenda.unavailable");
	
	private final String 					BLOCKPERIOD_CARD = Translatrix.getTranslationString("Agenda.officeClosed");

	private JButton 						okButton;

	private JButton 						cancelButton;

	private JTabbedPane 					metaPanel;

	private AbstractAction 					cancelAction;

	private AbstractAction 					okAction;

	private Appointment 					appointment;

	private AppointmentEditPanel 			generalPanel;

	private AppointmentEditPanel 			holidayPanel;
	
	private AppointmentEditPanel 			blockPeriodPanel;
	
	private JButton 						openPatientButton;

	private AbstractAction 					openPatienAction;

	private Timer 							movingTimer;

	private boolean 						triggerActionAfterShowing = false;
	
	// popup which show the next appointments of the patient
	private FadingPopup 					popFader;
	
	private DateFormat 						df = DateFormat.getDateInstance(DateFormat.SHORT);
	
	private Integer							lastPatientid;
	
	/**
	 *
	 */
	private AppointmentCreateDialog() {
	/* ================================================== */
		super(MainFrame.getInstance(),
				Translatrix.getTranslationString("calendar.newEvent"),
				true);
		Translatrix.addBundle("lu.tudor.santec.gecamed.agenda.gui.resources.Translatrix");
		
		//initRecurrencePanel();
		initComponent();
		initButtonActions();
		this.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				/* ====================================================== */
				appointment = null;
				instance.setVisible(false);
				/* ====================================================== */
			}
			
		});
		
		/* ------------------------------------------------------- */
		// a timertask to show the list when the dialog has been
		// moved to make the moving smoother
		// the timer
		this.movingTimer = new Timer();
	/* ================================================== */
	}

	/**
	 * @return
	 */
	public static AppointmentCreateDialog getInstance() {
		/* ================================================== */
		return instance;
		/* ================================================== */
	}

	/**
	 * Show the AppointmentCreateDialog to create a new appointment.
	 * 
	 * @param calendar the calendar of the appointment
	 * @param start the start date of the appointment
	 * @param end the end date of the appointment
	 */
	public void showDialog(AgendaCalendar calendar, Date start, Date end) {
		/* ================================================== */
		// init appointment
		this.appointment = new Appointment();
		this.appointment.setCalendarId(calendar.getId());
		this.appointment.setStartDate(start);
		this.appointment.setEndDate(end);
		// init Dialog
		lastPatientid = null;
		showPatientAppointment(false);
		updateForms();
		this.pack();
		RecurrenceOptionDialog.getInstance().wasOpen = false;
		AgendaModule.userAktionToLog = AgendaModule.CREATE_APPOINTMENT;
		instance.pack();
		// show Dialog
		MainFrame.showDialogCentered(instance);
		/* ================================================== */		
	}

	/**
	 * Show the AppointmentCreateDialog to edit a appointment.
	 * 
	 * @param appointment the appointment to edit 
	 */
	public void showDialog(Appointment appointment) {
		/* ================================================== */
		// init appointment
		this.appointment = (Appointment) appointment.clone();
		// init Dialog
		lastPatientid = null;
		showPatientAppointment(true);
		updateForms();
		this.pack();
		RecurrenceOptionDialog.getInstance().wasOpen = false;
//		if(appointment.getFrequency() != Appointment.NO_RECUR)
//			RecurrenceOptionDialog.getInstance().getRecurrencePanel().initRecurrencePanel(true);
//		else
//			RecurrenceOptionDialog.getInstance().getRecurrencePanel().initRecurrencePanel(false);
		AgendaModule.userAktionToLog = AgendaModule.CHANGE_APPOINTMENT;
		instance.pack();
		// show Dialog
		MainFrame.showDialogCentered(instance);
		/* ================================================== */
	}



	public Appointment getAppointment() {
		/* ================================================== */
		return this.appointment;
		/* ================================================== */
	}


	/**
	 * Updates the forms with the data from the appointment object
	 */
	private void updateForms() {
		// ==================================================
		// set appointment to all dialog panels
		this.generalPanel.setAppointment(this.appointment);
		this.holidayPanel.setAppointment(this.appointment);
		this.blockPeriodPanel.setAppointment(this.appointment);
		// set the recurrence status
		this.setRecurrenceStatus(appointment);
		 
		// ==================================================
		// check the type of appointment an open it in the correct card
		if (this.appointment.getTypeId() != null  
				&& AppointmentType.BLOCK_PERIOD.equals(AgendaModule.getTypeForId(this.appointment.getTypeId()).getAppointmentTypeClass())) {
			this.metaPanel.setSelectedComponent(this.blockPeriodPanel);
		}else{
			if (this.appointment.getIsBackground()) {
				this.metaPanel.setSelectedComponent(this.holidayPanel);
			} else {
				this.metaPanel.setSelectedComponent(this.generalPanel);
			}
		}
		// ==================================================
	}


	/**
	 * Fills the appointment with the data from the form fields
	 */
	private void fillAppointment() {
		// ==================================================
		if (this.appointment == null)
		{
			this.appointment = new Appointment();	
		}
		// ==================================================
		AppointmentEditPanel currPanel = (AppointmentEditPanel)this.metaPanel.getSelectedComponent();
		currPanel.getAppointment(this.appointment);
//		if (currPanel instanceof RecurrencePanel)
//			generalPanel.getAppointment(this.appointment);
		// ==================================================
	}


	/**
	 * Init component
	 */
	private void initComponent() {
		// ==================================================
		this.getContentPane().setBackground(Color.WHITE);
		this.setLayout(new BorderLayout());
		/* ------------------------------------------------------- */
		this.metaPanel = new JTabbedPane();
		/* ------------------------------------------------------- */
		metaPanel.setOpaque(false);
		this.add(metaPanel,  BorderLayout.NORTH);
		this.initGeneralPanel();
		this.initHolidayPanel();
		this.initblockPeriodPanel();
		/* ------------------------------------------------------- */
		
		this.popFader = new FadingPopup(this);
		/* ------------------------------------------------------- */
		// add tabs
		metaPanel.addTab(this.DEFAULT_CARD, 	this.generalPanel.getIcon(), 		this.generalPanel);
		metaPanel.addTab(this.HOLIDAY_CARD, 	this.holidayPanel.getIcon(), 		this.holidayPanel);
		metaPanel.addTab(this.BLOCKPERIOD_CARD, this.blockPeriodPanel.getIcon(), 	this.blockPeriodPanel);
		
		metaPanel.addChangeListener(this);
		// ==========================================================
		// button panel
		// ==========================================================
		this.openPatientButton 	= new JButton();
		this.okButton 			= new JButton();
		this.cancelButton 		= new JButton();
		ButtonBarBuilder bb 	= new ButtonBarBuilder();
		/* ------------------------------------------------------- */
		bb.addGridded(openPatientButton);
		
		bb.addGlue();
		bb.addGridded(okButton);
		bb.addRelatedGap();
		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(false);
		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.add(new JLabel(""), BorderLayout.WEST);
		/* ------------------------------------------------------- */
		gapPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		/* ------------------------------------------------------- */

		this.add(gapPanel, BorderLayout.SOUTH);
		// add a component to let the list popup stay alway besides the dialog
		// when it is moving
		this.addComponentListener(this);
		this.addWindowListener(this);
		this.addWindowFocusListener(this);
		/* ================================================== */
	}

	private void initGeneralPanel() {
		/* ================================================== */
		this.generalPanel = new GeneralPanel();
		generalPanel.addPropertyChangeListener(this);
		/* ================================================== */
	}

	private void initHolidayPanel() {
		/* ================================================== */
		this.holidayPanel = new HolidayPanel();
		/* ================================================== */
	}

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

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				appointment = null;
//				if (pop != null)
//					pop.hide();
//				pop = null;
//				popFader.hidePopup();
				showPatientAppointment(false);
				instance.setVisible(false);
				RecurrenceOptionDialog.getInstance().wasOpen = false;
				/* ====================================================== */
			}
		};
		// ok button action
		this.okAction = new AbstractAction(Translatrix.getTranslationString("calendar.core.ok"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.OK)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				fillAppointment();
//				if (pop != null) 
//					pop.hide();
//				pop = null;
//				popFader.hidePopup();
				showPatientAppointment(false);
				instance.setVisible(false);
				RecurrenceOptionDialog.getInstance().getRecurrencePanel().setIsEnabled(false);
				RecurrenceOptionDialog.getInstance().wasOpen = false;				
				/* ====================================================== */
			}
		};
		
		/* ------------------------------------------------------- */
		this.openPatienAction = new AbstractAction(Translatrix.getTranslationString("calendar.newEvent.openPatient"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.OPEN)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				GeneralPanel gp = (GeneralPanel) generalPanel;
				if (gp.isShowing() && gp.getPatientId() != null) {
					/* ------------------------------------------------------- */
					popFader.setListData(new Vector<Event>(0));
					popFader.hidePopup();
					instance.setVisible(false);
					PatientManagerModule.getInstance().loadPatient(gp.getPatientId());
//					try {
//						/* ------------------------------------------------------- */
//						PatientAdminInterface pManager =  (PatientAdminInterface) 
//								ManagerFactory.getRemote(PatientAdminBean.class);
//						Patient patient = pManager.getPatient(gp.getPatientId());
//						
//						popFader.setListData(new Vector<Event>(0));
//						popFader.hidePopup();
//						
//						// set the patient
//						GECAMedModule.setCurrentPatient(patient);
//						MainFrame.getInstance().selectModule(PatientManagerModule.MODULE_NAME);
//						instance.setVisible(false);
//						/* ------------------------------------------------------- */
//					} catch (Exception ex) {
//						ex.printStackTrace();
//					}
					/* ------------------------------------------------------- */
				}

//				instance.setVisible(false);
				/* ====================================================== */
			}
		};
		/* ------------------------------------------------------- */
		this.okButton.setAction(okAction);
		this.cancelButton.setAction(cancelAction);
		this.openPatientButton.setAction(openPatienAction);
		/* ------------------------------------------------------- */
//		this.openPatientButton.setEnabled(false);
		// =================================================================


		// =================================================================
		// 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);


//		KeyStroke strokeEnter = KeyStroke.getKeyStroke("ENTER");
//
//		((JPanel) this.getContentPane()).getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
//					.put(strokeEnter, "ok");
//		((JPanel) this.getContentPane()).getActionMap().put("ok", okAction);
		/* ================================================== */
	}
	
	
//	/**
//	 * Init the JList for the upcoming appointment of a patient
//	 */
//	private void initAppointmentList() {
//		/* ================================================== */
//		
//		/* ================================================== */
//	}
	
	
	
	
	public void stateChanged(ChangeEvent e) {
		/* ====================================================== */
		if (metaPanel.getSelectedComponent().equals(generalPanel)
				&& ((GeneralPanel) generalPanel).getPatientId() != null) {
			showPatientAppointment(true);
		}
		else {
			showPatientAppointment(false);
		}
		/* ====================================================== */
	}
	
	public void propertyChange(PropertyChangeEvent evt) {
		/* ====================================================== */
		if (GeneralPanel.PATIENT_ID_CHANGED.equals(evt.getPropertyName())) {
			stateChanged(null);
			if (((GeneralPanel) generalPanel).getPatientId() != null)
				openPatientButton.setEnabled(true);
			else
				openPatientButton.setEnabled(false);
		}
		if (GeneralPanel.DATE_INTERVAL_CHANGED.equals(evt.getPropertyName())) { //TODO
//			/* ------------------------------------------------------- */
//			// check the duration of the interval and disable the
//			// appropriate reccurance intervals
//			/* ------------------------------------------------------- */
//			Date start = ((GeneralPanel) generalPanel).getStartDate();
//			Date end   = ((GeneralPanel) generalPanel).getEndDate();
//			/* ------------------------------------------------------- */
//			// if the two dates are in the same day, enable all
//			/* ------------------------------------------------------- */
//			RecurrencePanel recPanel = (RecurrencePanel) this.recurrencePanel;
//			if (DateUtil.isSameDay(start, end)) {
//				/* ------------------------------------------------------- */
//				// enable all
//				/* ------------------------------------------------------- */
//				recPanel.enablePanel(Appointment.DAILY,   true);
//				recPanel.enablePanel(Appointment.WEEKLY,  true);
//				recPanel.enablePanel(Appointment.MONTHLY, true);
//				recPanel.enablePanel(Appointment.YEARLY,  true);
//				/* ------------------------------------------------------- */
//			} else
//				if (DateUtil.isSameWeek(start, end) && !DateUtil.isSameDay(start, end)) {
//					/* ------------------------------------------------------- */
//					// disable daily recurrance
//					/* ------------------------------------------------------- */
//					recPanel.enablePanel(Appointment.DAILY,   false);
//					recPanel.enablePanel(Appointment.WEEKLY,  true);
//					recPanel.enablePanel(Appointment.MONTHLY, true);
//					recPanel.enablePanel(Appointment.YEARLY,  true);
//					/* ------------------------------------------------------- */
//				} else
//					/* ------------------------------------------------------- */
//					// If the two dates are not in the same wee, but the duration
//					// of the event is not longer than a week, we can enable the 
//					// weekly recurrance
//					/* ------------------------------------------------------- */
//					if (!DateUtil.isSameWeek(start, end) && DateUtil.getDiffDay(start, end) < DateUtil.MILLIS_DAY*7) {
//						/* ------------------------------------------------------- */
//						// disable daily 
//						/* ------------------------------------------------------- */
//						recPanel.enablePanel(Appointment.DAILY,   false);
//						recPanel.enablePanel(Appointment.WEEKLY,  true);
//						recPanel.enablePanel(Appointment.MONTHLY, true);
//						recPanel.enablePanel(Appointment.YEARLY,  true);
//						/* ------------------------------------------------------- */
//					} else
//						/* ------------------------------------------------------- */
//						// if the dates are in the same month, disable daily and weekly
//						/* ------------------------------------------------------- */
//						if (DateUtil.isSameMonth(start, end)) {
//							/* ------------------------------------------------------- */
//							// disable daily, weekly
//							/* ------------------------------------------------------- */
//							recPanel.enablePanel(Appointment.DAILY,   false);
//							recPanel.enablePanel(Appointment.WEEKLY,  false);
//							recPanel.enablePanel(Appointment.MONTHLY, true);
//							recPanel.enablePanel(Appointment.YEARLY,  true);
//							/* ------------------------------------------------------- */
//						} else
//							/* ------------------------------------------------------- */
//							// if the two dates are in the same year, enable only yearly
//							/* ------------------------------------------------------- */
//							if (DateUtil.isSameYear(start, end)) {
//								/* ------------------------------------------------------- */
//								// disable daily, weekly, monthly
//								/* ------------------------------------------------------- */
//								recPanel.enablePanel(Appointment.DAILY,   false);
//								recPanel.enablePanel(Appointment.WEEKLY,  false);
//								recPanel.enablePanel(Appointment.MONTHLY, false);
//								recPanel.enablePanel(Appointment.YEARLY,  true);
//								/* ------------------------------------------------------- */
//							} else {
//								// disable all
//								recPanel.enablePanel(Appointment.DAILY,   false);
//								recPanel.enablePanel(Appointment.WEEKLY,  false);
//								recPanel.enablePanel(Appointment.MONTHLY, false);
//								recPanel.enablePanel(Appointment.YEARLY,  false);
//							}
//			
//			/* ------------------------------------------------------- */
		}
		/* ====================================================== */
	}
	
	/**
	 * Shows the list with the appointment of the patient
	 * @param b
	 */
	private void showPatientAppointment(boolean b) {
		/* ================================================== */
		if (!this.isShowing()) {
			/* ------------------------------------------------------- */
			// if the dialog is not visible at the moment, we will trigger the
			// fade when its visible the next time
			this.triggerActionAfterShowing  = true;
			return;
			/* ------------------------------------------------------- */
		}
		if (b) { // show
			/* ------------------------------------------------------- */
			final Integer	patientId		= ((GeneralPanel) generalPanel).getPatientId();
			
			if (patientId != null)
			{
				final Thread t = new Thread() {
					@SuppressWarnings("unchecked")
					public void run() {
						/* ================================================== */
						boolean reload	= !patientId.equals(lastPatientid);
						lastPatientid	= patientId;
						if (reload)
						{
							// get the appointments of the patient
							try {
								/* ------------------------------------------------------- */
								AppointmentManager aManager = (AppointmentManager) 
										ManagerFactory.getRemote(AppointmentManagerBean.class);
								List<Appointment> result = aManager.getAppointments(patientId, 20);
								/* ------------------------------------------------------- */
								// reset the list if no results were returned
								if (result == null) {
									popFader.setListData(new Vector<Event>(0));
									return;
								}
								// convert to Event objects
								List<Event> futureApps = new ArrayList<Event>();
								// create a limit data, lets say from to day plus 400 days
								Date destination = DateUtil.getDiffDay(new Date(), 400);
								
								for (Appointment app : result) {
									/* ------------------------------------------------------- */
									List<Event> tList = DefaultNamedCalendar.createRecurrEvents(app, new Date(), destination,(Locale)AgendaModule.getInstance().getAgendaAdminSettingsPlugin().getValue(AgendaAdminSettingsPlugin.CALENDAR_LOCALE));
									// set the color to the events
									for (Event tE : tList)
									{
										if(tE.getStart().getTime() >= new Date().getTime())
										{
										  tE.setColor(new Color(AgendaModule.getCalendarForId(app.getCalendarId()).getColor()));
										  // set Calendar id to Event
										  tE.set(Event.CALENDAR_ID, app.getCalendarId());
										  // set Calendar isBackground to Event
										  tE.set(Event.CALENDAR_IS_BACKGROUND, AgendaModule.getCalendarForId(app.getCalendarId()).isBackground());
										  futureApps.add(tE);
										}
									}
									
									/* ------------------------------------------------------- */
									//futureApps.addAll(tList);
									/* ------------------------------------------------------- */
								}
								/* ------------------------------------------------------- */
								Collections.sort(futureApps);
								// set the events to the JList
								popFader.setListData(futureApps);
							} catch (Exception e) {
								logger.error("Error while trying to load future appointments", e);
							}
						}
						/* ------------------------------------------------------- */
						if (popFader.getAppointmentCount() > 0 && AppointmentCreateDialog.this.isVisible())
						{
							// show the panel
							popFader.showPopup();
						}
						/* ------------------------------------------------------- */
						/* ================================================== */
					}
				};
				t.start();
			}
			/* ------------------------------------------------------- */
		} else { // hide
			/* ------------------------------------------------------- */
			popFader.hidePopup();
			/* ------------------------------------------------------- */
		}
			
		/* ================================================== */
	}
	
	
	// ================================================================
	// ComponentListener methods to move
	// the list pop when the dialog
	// moves
	// ================================================================


	public void componentMoved(ComponentEvent e) {
		/* ====================================================== */
//		if (pop == null)
//			return;
//		/* ------------------------------------------------------- */
//		pop.hide();
//		popFader.hidePopup();
		showPatientAppointment(false);
		showPatientAppointment(true);
		/* ------------------------------------------------------- */
		try {
			movingTimer.cancel();
		} catch (Exception ex) {}
		
		movingTimer = new Timer();
		movingTimer.schedule(new TimerTask() {
								@Override
								public void run() {
									/* ====================================================== */
//									fadeList();
//									popFader.showPopup();
									showPatientAppointment(true);
									/* ====================================================== */
								}
							}, 500);
		
		/* ====================================================== */
	}

	public void componentHidden(ComponentEvent e) {}
	public void componentResized(ComponentEvent e) {}
	public void componentShown(ComponentEvent e) {}

	public void windowActivated(WindowEvent e) {}
	public void windowClosed(WindowEvent e) {}
	public void windowClosing(WindowEvent e)
	{
		showPatientAppointment(false);
	}
	public void windowDeactivated(WindowEvent e) {}
	public void windowDeiconified(WindowEvent e) {}
	public void windowIconified(WindowEvent e) {}

	public void windowOpened(WindowEvent e) {
		/* ====================================================== */
		//
		if (triggerActionAfterShowing) {
			triggerActionAfterShowing = false;
			movingTimer = new Timer();
			movingTimer.schedule(new TimerTask() {
				@Override
				public void run() {
					/* ====================================================== */
					showPatientAppointment(true);
					/* ====================================================== */
				}
				
			}, 500);
		}
		/* ====================================================== */
	}
	
	
	
	public void windowGainedFocus(WindowEvent e) {
		/* ====================================================== */
//		if (pop != null)
//			fadeList();
		showPatientAppointment(true);
		/* ====================================================== */
	}

	public void windowLostFocus(WindowEvent e) {
		/* ====================================================== */
//		if (pop != null)
//			pop.hide();
//		popFader.hidePopup();
		showPatientAppointment(false);
		/* ====================================================== */
	}
	
	public void recurrenceButtonAction(Appointment appointment) {
		
		if (appointment != null){
			// set appointment to the other tabs
			this.generalPanel.setAppointment(appointment);
			this.holidayPanel.setAppointment(appointment);
			this.blockPeriodPanel.setAppointment(appointment);
			// set the recurrence status
			this.setRecurrenceStatus(appointment);
		}
	}
	
	public void setRecurrenceStatus(Appointment appointment)
	{
		StringBuffer sb = new StringBuffer("  ");
		
		// set the recurrence status
		if (appointment.getFrequency() == Appointment.NO_RECUR)
		{
			sb.append(Translatrix.getTranslationString("Agenda.Recurrence.infoMessage.noRecurrence"));
		} else if (appointment.getFrequency() == Appointment.DAILY)
		{
			sb.append(Translatrix.getTranslationString("Agenda.Recurrence.dailyRecurrence"));
			sb.append(" - ");
		} else if (appointment.getFrequency() == Appointment.WEEKLY)
		{
			sb.append(Translatrix.getTranslationString("Agenda.Recurrence.weeklyRecurrence"));
			sb.append(" - ");
		} else if (appointment.getFrequency() == Appointment.MONTHLY)
		{
			sb.append(Translatrix.getTranslationString("Agenda.Recurrence.monthlyRecurrence"));
			sb.append(" - ");
		} else if (appointment.getFrequency() == Appointment.YEARLY)
		{
			sb.append(Translatrix.getTranslationString("Agenda.Recurrence.yearlyRecurrence"));
			sb.append(" - ");
		}
		
		// get the end date of the recurrence
		if(appointment.getFrequency() != Appointment.NO_RECUR)
		{
			if(appointment.getUntil() != null)
			{
				sb.append(Translatrix.getTranslationString("Agenda.Recurrence.enddate") + ": " + df.format(appointment.getUntil()));
			}else{
				sb.append(Translatrix.getTranslationString("Agenda.Recurrence.noEnddate"));
			}
		}
		
		this.generalPanel.setRecurrenceStatus(sb.toString());
		this.holidayPanel.setRecurrenceStatus(sb.toString());
		this.blockPeriodPanel.setRecurrenceStatus(sb.toString());
	}
}