/*****************************************************************************
 *                                                                           *
 *  Copyright (c) 2010 by SANTEC/TUDOR www.santec.tudor.lu                   *
 *                                                                           *
 *                                                                           *
 *  This library is free software; you can redistribute it and/or modify it  *
 *  under the terms of the GNU Lesser General Public License as published    *
 *  by the Free Software Foundation; either version 2 of the License, or     *
 *  (at your option) any later version.                                      *
 *                                                                           *
 *  This software 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 along with this library; if not, write to the Free Software      *
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  *
 *                                                                           *
 *****************************************************************************/
package lu.tudor.santec.gecamed.patient.gui.incident;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.swing.JOptionPane;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Invoice;
import lu.tudor.santec.gecamed.billing.ejb.session.beans.InvoiceBean;
import lu.tudor.santec.gecamed.billing.ejb.session.interfaces.InvoiceInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedOptionPane;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Incident;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.IncidentEntry;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.MeasurementType;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.MeasurementValue;
import lu.tudor.santec.gecamed.patient.ejb.session.beans.IncidentManagerBean;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.IncidentManager;
import lu.tudor.santec.i18n.Translatrix;

/**
 * Controler class to gain access to/from the session bean
 * to/from the  incident model
 *
 *
 *
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: IncidentControler.java,v $
 * <br>Revision 1.28  2010-09-30 15:55:42  troth
 * <br>Complete - # 668: edit accident must modify GUI
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/668
 * <br>
 * <br>Revision 1.27  2010-09-17 09:04:35  troth
 * <br>Ticket # 634: Letztes Measurement Feld kann nicht gelöscht werden
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/634
 * <br>
 * <br>Revision 1.26  2010-09-15 13:12:44  troth
 * <br>Complete - # 633: Letzter S.O.A.P. Eintrag kann nicht geloöscht werden
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/633
 * <br>
 * <br>Revision 1.25  2010-09-07 16:22:16  troth
 * <br>Workaround for Ticket # 630: Abbruch reagiert falsch im Accident Modifizier-Dialog
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/630
 * <br>
 * <br>Revision 1.24  2010-09-06 16:18:03  troth
 * <br>Fix Bug - Now the parent_accident_incident_id of accident child can be deleted
 * <br>
 * <br>Revision 1.23  2010-09-03 08:40:25  troth
 * <br>Incomplete - # 620: Parentlink Verwaltung bei Accidents
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/620
 * <br>
 * <br>Revision 1.22  2010-09-02 11:20:03  troth
 * <br>fix wrong call of function GECAMedOptionPane.showOptionDialog
 * <br>
 * <br>Revision 1.21  2010-05-18 05:40:29  ferring
 * <br>just some style changed
 * <br>
 * <br>Revision 1.20  2010-05-12 09:43:10  troth
 * <br>fixed the incorrect saving of a consultation
 * <br>Incomplete - # 483: Unvollständiges Abspeichern einer Konsultation
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/483
 * <br>
 * <br>Revision 1.19  2010-05-07 08:59:35  troth
 * <br>edit call of function getRecentIncident() because the function getRecentIncident() move from class PrescriptionDataModel to PatientPanel
 * <br>
 * <br>Revision 1.18  2010-04-27 14:36:37  troth
 * <br>GECAMedOptionPane create now only a simple JOptionPane. May be later we build our own optionpane.
 * <br>
 * <br>Revision 1.17  2010-04-26 16:38:13  troth
 * <br>Redesign of the prescription view
 * <br>
 * <br>Revision 1.16  2009-03-02 08:31:17  heinemann
 * <br>the prescription haven't been saved when the "save Patient" button was pressed. Fixed.
 * <br>
 * <br>Revision 1.15  2009-02-27 09:03:20  heinemann
 * <br>huups. Import cefip action was .... absent
 * <br>
 * <br>Revision 1.14  2008-12-17 15:23:06  heinemann
 * <br>initial commit after merging of branch new prescription
 * <br>
 * <br>Revision 1.13.2.1  2008-12-15 14:08:21  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.13  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.12  2008-01-31 09:14:38  mack
 * <br>Changes required by refactoring of getInvoicesByAccident method
 * <br>
 * <br>Revision 1.11  2008-01-22 13:51:51  heinemann
 * <br>code cleanup and java doc
 * <br>
 * <br>Revision 1.10  2008-01-02 13:46:07  heinemann
 * <br>now using newstyle ManagerFactory
 * <br>
 * <br>Revision 1.9  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.8  2007-10-16 08:23:26  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2007/07/03 12:35:29  heinemann
 * <br>system.out removed
 * <br>
 * <br>Revision 1.6  2007/06/18 11:31:36  hermen
 * <br>cleanup of old stuff and moved some beans
 * <br>
 * <br>Revision 1.5  2007/04/26 12:11:47  heinemann
 * <br>change invoice accident data if accident data is changed in consultation
 * <br>
 * <br>Revision 1.2  2007/03/02 08:28:43  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1.2.2  2007/01/19 10:34:57  heinemann
 * <br>Incomplete - # 55: Check if a modified incident keeps it original date
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/55
 * <br>Incomplete - # 28: Accident Nr and date must appear on the prescription printout
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/28
 * <br>
 * <br>Revision 1.1.2.1  2007/01/04 13:48:42  heinemann
 * <br>The great space cleaning lady has done a big bunch of refactoring
 * <br>
 * <br>Revision 1.1.2.5  2007/01/04 12:13:53  heinemann
 * <br>Incomplete - # 22: Save consultation after a prescription was printed does not work
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/22
 * <br>
 * <br>fixed and some other changes like the behaviour of the prescription editor in case of printing and afterwards saving the consultation etc
 * <br>
 * <br>Revision 1.1  2006/12/01 14:38:35  heinemann
 * <br>initial checkin
 * <br>
 */
public class IncidentControler implements PropertyChangeListener {

	/* ***************************************************************
	 * Class Members
	 */

	/**
	 * The model
	 */
	private IncidentModel incidentModel;
	private IncidentPanel incidentPanel;
//	private PrescriptionModule prescriptionModul;
	private boolean isOld;
	private Boolean moduleState = false;

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


	/* ***************************************************************
	 * Constructors
	 */

	/**
	 *
	 */
	public IncidentControler(boolean isOld) {
		/* ====================================================== */
		this(null, isOld);
		/* ====================================================== */
	}

	/**
	 * @param model
	 * @param isOld if this is an existing incident
	 */
	public IncidentControler(IncidentModel model, boolean isOld) {
		/* ====================================================== */
		this.isOld = isOld;
		this.incidentModel = model;
		/* ====================================================== */
	}

	/* ---------------------------------------------------------------
	 * End of Constructors
	 * ************************************************************* */


	/* ***************************************************************
	 * Controll methods
	 */

	/**
	 * Get all measurement types
	 *
	 * @return
	 */
	public List<MeasurementType> getMeasurementTypes() {
		/* ====================================================== */
		List<MeasurementType> result = getManager().getMeasurementTypes();
		/* ------------------------------------------------------ */
		// if null, create an empty list
		if (result == null)
			result = new ArrayList<MeasurementType>();
		/* ------------------------------------------------------ */
		return result;
		/* ====================================================== */
	}

	/**
	 * @param model
	 */
	public void setIncidentModel(IncidentModel model) {
		/* ====================================================== */
		this.incidentModel = model;
		/* ====================================================== */
	}


	/**
	 * Returns the incident model
	 *
	 * @return
	 */
	public IncidentModel getIncidentModel() {
		/* ====================================================== */
		return this.incidentModel;
		/* ====================================================== */
	}

	/**
	 * @param panel
	 */
	public void setIncidentPanel(IncidentPanel panel) {
		/* ====================================================== */
		this.incidentPanel = panel;
		// create presription part
//		this.prescriptionModul = new PrescriptionModule(this);
//
//		panel.setPrescriptionModule(this.prescriptionModul);

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

	/**
	 * Return the incident panel
	 *
	 * @return
	 */
	public IncidentPanel getIncidentPanel() {
		/* ====================================================== */
		return this.incidentPanel;
		/* ====================================================== */
	}

	/**
	 * Save the current incident
	 */
	public Boolean saveIncident() {
		/* ====================================================== */
		if (this.incidentModel.getIncident() != null) {
			// get ID - if incident have one it is not a new created
			Integer oldId = incidentModel.getIncident().getId();
			/* ------------------------------------------------------ */
			// if there are changes -> dialog
			// check if there are invoices attached to the old accident data
			if (incidentModel.isAccidentModified()) {
				/* ------------------------------------------------------- */
				// check if some incidents have to get the new accident data
				checkNestedAccidentIncident();

				/* ------------------------------------------------------- */
				InvoiceInterface iManager = (InvoiceInterface)
					ManagerFactory.getRemote(InvoiceBean.class);
				/* ------------------------------------------------------- */
				List<Invoice> invoices =
					iManager.getInvoicesForAccident (incidentModel.getOriginalAccidentNumber(),
												     incidentModel.getOriginalAccidentDate(),
												     incidentModel.getPatient());
				/* ------------------------------------------------------- */
				if (invoices != null && invoices.size() > 0) {
					AccidentInvoiceRelationDialog ai = AccidentInvoiceRelationDialog.getInstance();
					ai.showDialog(invoices);
					if (ai.getSelectedInvoices() != null) {
						Incident incid = incidentModel.getIncident();
						for (Invoice in : ai.getSelectedInvoices()) {
							
							in.setAccidentDate(incid.getAccidentDate());
							in.setAccidentNumber(incid.getAccidentNr());


							try {
								iManager.saveInvoice(in);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
			
			// set back to the last running version
			Incident newIncident =
					getManager().saveIncident(incidentModel.getIncident());
			
			incidentModel.setIncident(newIncident);
			incidentModel.setModified(false);
			incidentModel.fireModelChanged();
			
			// if this was a new incident, we must pipe this
			// information to the incident tab
			if (oldId == null)
				return true;
			
		}
		return false;
	}


	/* ---------------------------------------------------------------
	 * End of Controlls
	 * ************************************************************* */


	/* ***************************************************************
	 * Helper methods
	 */


	/**
	 * Asks if the accident data should be changed to all
     * nested accident consultations
	 *
	 * @return
	 */
	public boolean checkNestedAccidentIncident() {
		/* ================================================== */
		/* ------------------------------------------------------- */
		// ask if the accident data should be changed to all
		// nested accident consultations
		// get number of child incidents
		IncidentManager incidentManager = (IncidentManager)
					ManagerFactory.getRemote(IncidentManagerBean.class);

		Incident curInc = incidentModel.getIncident();
		// =================================================================
		// If the current incident has a parentAccidentId, there is at least
		// one more incident that needs new accident data -> show dialog
		//
		// if the current incident is a parent accident incident, we must
		// check if there are children, if yes, --> show dialog
		// =================================================================
		boolean showAccidentChangeDialog = false;
		/* ------------------------------------------------------- */
		if (curInc.getParentAccidentIncidentId() == null) {
			/* ------------------------------------------------------- */
			Long amount = incidentManager.getChildAccidentIncidentAmount(
											incidentModel.getIncident().getId());
			if (amount > 0)
				showAccidentChangeDialog = true;
			/* ------------------------------------------------------- */
		} else
			showAccidentChangeDialog = true;
		/* ------------------------------------------------------- */
		// show dialog
		if (showAccidentChangeDialog) {
			int res = GECAMedOptionPane.showOptionDialogWithoutClose(MainFrame.getInstance(),
						Translatrix.getTranslationString("patient.incident.accident.changeDialogTitle"),
						Translatrix.getTranslationString("patient.incident.accident.changeDialogMsg"),
						JOptionPane.YES_NO_OPTION);
						//GECAMedOptionPane.ICON_QUESTION);
			if (res == JOptionPane.YES_OPTION) {
				/* ------------------------------------------------------- */
				curInc = incidentManager.setNewAccidentDataForNestedIncidents(curInc);
				incidentModel.setIncident(curInc);
				return true;
				/* ------------------------------------------------------- */
			}
			else if (res == JOptionPane.NO_OPTION) {
				/* ------------------------------------------------------- */
				// remove all connections to other accidents
				curInc = incidentManager.removeIncidentFromAccidentList(curInc);
				incidentModel.setIncident(curInc);
				return true;
				/* ------------------------------------------------------- */
			} else if (res == JOptionPane.CANCEL_OPTION) {
				return false;
			}

		}

		return true;
		/* ================================================== */
	}



	/**
	 * Returns the IncidentManager SessionBean
	 *
	 * @return
	 */
	protected IncidentManager getManager() {
		/* ====================================================== */
		return (IncidentManager)
			ManagerFactory.getRemote(IncidentManagerBean.class);
		/* ====================================================== */
	}

	/**
	 * @return
	 */
	public Incident getIncident() {
		/* ============================================= */

		return incidentModel.getIncidentForPrescription();
		/* ============================================= */
	}


//	/**
//	 * @return Returns the controler of the prescription editor.
//	 */
//	public EditorControler getEditorControler() {
//		/* ====================================================== */
//		try {
//			return this.prescriptionModul.getEditorControler();
//		} catch (Exception e) {
//			return null;
//		}
//		/* ====================================================== */
//	}



	/**
	 * Returns the current incident. Normally used to store prescriptions.
	 * If the incident has not been saved, it will be done here. 
	 * 
	 * @return
	 */
	public Incident getIncidentForPrescription() {
		/* ============================================= */
		// if not persistent, create a new one, persist it and
		// pipe it to the EditorControler/return
		// AND !!!
		// set this persisted incident for the current consultation
		Incident incident = incidentModel.getIncidentForPrescription();
		/* ------------------------------------------------------ */
		// if not persistent, we must save it
		if (!incident.isPersistent()) {
			/* ------------------------------------------------------ */
			// without the consultation data
//			Collection<Consultation> consultations = incident.getConsultations();
//			incident.setConsultations(null);
			List<IncidentEntry> consultationEntries = incident.getIncidentEntries();
			incident.setIncidentEntries(null);
			/* ------------------------------------------------------ */
			// and without the measurements
			Set<MeasurementValue> values = incident.getMeasurementValues();
			incident.setMeasurementValues(null);
			/* ------------------------------------------------------ */
			incident = getManager().saveIncident(incident);
			/* ------------------------------------------------------ */
			// set the consulations back
//			incident.setConsultations(consultations);
			incident.setIncidentEntries(consultationEntries);
			// set the measurements back
			incident.setMeasurementValues(values);
			// write back to the model
			incidentModel.setIncident(incident);
			/* ------------------------------------------------------ */
		}
		return incident;
		/* ============================================= */
	}

//	/**
//	 * @return 
//	 */
//	public PrescriptionModule getPrescriptionModule() {
//		/* ====================================================== */
//		return this.prescriptionModul;
//		/* ====================================================== */
//	}

	/**
	 * @return true if an old consultation is open
	 */
	public boolean isOld() {
		/* ============================================= */
		return this.isOld;
		/* ============================================= */
	}

	/* (non-Javadoc)
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		/* ====================================================== */
		if (IncidentTab.INCIDENT_ACTIVATION.equals(evt.getPropertyName())) {
			this.moduleState  =  (Boolean) evt.getNewValue();
		}
		/* ====================================================== */
	}


	/**
	 * @return
	 */
	public Boolean isModuleActive() {
		/* ================================================== */
		return this.moduleState;
		/* ================================================== */
	}

	/* ---------------------------------------------------------------
	 * End of Helper Methods
	 * ************************************************************* */


}
