/*****************************************************************************
 *                                                                           *
 *  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.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.IChangeListener;
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.IncidentEntryType;
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.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;

import org.apache.log4j.Logger;

/**
 *
 * The model for the incident view. It holds an Incident entity
 * and offers all the avalable data to the view.
 *
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: IncidentModel.java,v $
 * <br>Revision 1.32  2013-12-27 18:09:23  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.31  2013-10-30 15:01:03  troth
 * <br>Code clear up.
 * <br>
 * <br>Revision 1.30  2013-10-29 09:45:27  troth
 * <br>The new consultation view with more entries and the sickleave version 3 fix several bugs.
 * <br>
 * <br>Revision 1.29  2013-09-03 16:32:38  troth
 * <br>The new consultation view with more entries and the sickleave version 1 save entries work now.
 * <br>
 * <br>Revision 1.28  2013-09-03 11:17:11  troth
 * <br>The new consultation view with more entries and the sickleave (GUI only work).
 * <br>
 * <br>Revision 1.27  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.26  2013-03-14 07:38:03  kutscheid
 * <br>bugfixes for the import of measurements and incident entries
 * <br>
 * <br>Revision 1.25  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.24  2010-09-09 15:57:39  troth
 * <br>1. Now all S.O.A.P entries can be deleted
 * <br>2. Now measurements can be deleted
 * <br>3. Bug fix that create a empty entry form type prescription when saving the consultation
 * <br>
 * <br>Revision 1.23  2010-09-01 12:05:31  troth
 * <br>Bugfix - get incident from incident model not from incident control for prescription in the setPrescription function.
 * <br>
 * <br>Revision 1.22  2010-08-31 13:35:56  troth
 * <br>Incomplete - # 495: Mehrere Unstimmigkeiten mit Unfallnummer (auch #529)
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/495
 * <br>and Tickets 529, 613
 * <br>and new/redesign of AccidentPanel
 * <br>
 * <br>Revision 1.21  2009-02-02 14:32:06  heinemann
 * <br>prevents saving empty consultations
 * <br>
 * <br>Revision 1.20  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.19  2008-05-27 14:13:08  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.18  2008-04-15 12:40:51  heinemann
 * <br>select accident number when the date is choosen in consultation view
 * <br>
 * <br>Revision 1.17  2008-04-14 14:37:07  heinemann
 * <br>fixed problem with patient accident that was not transfered to the billing module when the current consultation, including the accident, was not saved before the creation of the invoice.
 * <br>
 * <br>Revision 1.16  2008-02-11 16:49:13  heinemann
 * <br>moved IChangeListener to core
 * <br>
 * <br>Revision 1.15  2008-01-22 13:51:52  heinemann
 * <br>code cleanup and java doc
 * <br>
 * <br>Revision 1.14  2008-01-02 13:47:03  heinemann
 * <br>fixed bug of checking the content of an consultation right before persisting.
 * <br>empty entries are now removed from the list.
 * <br>
 * <br>Revision 1.11  2007/06/18 11:31:37  hermen
 * <br>cleanup of old stuff and moved some beans
 * <br>
 * <br>Revision 1.10  2007/04/25 06:04:41  heinemann
 * <br>fixed nullpointer in setAccidentDate and number
 * <br>
 * <br>Revision 1.7  2007/03/14 09:07:08  heinemann
 * <br>best practise fixes
 * <br>
 * <br>Revision 1.6  2007/03/12 15:00:46  mack
 * <br>removed gremlin after notification
 * <br>
 * <br>Revision 1.5  2007/03/12 14:32:10  heinemann
 * <br>Complete - # 46: make printed prescriptions editable
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/46
 * <br>
 * <br>Revision 1.4  2007/03/06 13:32:51  heinemann
 * <br>Incomplete - # 8: Closing of consultation tabs
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/8
 * <br>
 * <br>editing the date of a consultation
 * <br>
 * <br>Revision 1.3  2007/03/06 06:48:05  heinemann
 * <br>Incomplete - # 8: Closing of consultation tabs
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/8
 * <br>
 * <br>Revision 1.2  2007/03/02 08:28:44  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1.2.6  2007/02/08 16:45:12  heinemann
 * <br>many changes
 * <br>
 * <br>Revision 1.1.2.5  2007/01/24 12:48:56  heinemann
 * <br>consultation and prescription update control.
 * <br>Modifications are displayed.
 * <br>And Incidents are not created if nothing has been entered in consultation, accident and prescription
 * <br>
 * <br>Revision 1.1.2.4  2007/01/22 10:24:07  heinemann
 * <br>Incomplete - # 13: print copies of prescriptions
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/13
 * <br>
 * <br>Revision 1.1.2.3  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.2  2007/01/10 13:46:52  heinemann
 * <br>fixed nullpointer when there are no physicians in the database
 * <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.7  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.2.6  2006/12/21 14:25:13  heinemann
 * <br>sysouts removed
 * <br>
 * <br>Revision 1.1  2006/12/01 14:38:35  heinemann
 * <br>initial checkin
 * <br>
 */
public class IncidentModel {

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

	/**
	 * The data
	 */
	private Incident incident;
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(IncidentModel.class.getName());


	protected final static int STATE_NEW 		= 0;
	protected final static int STATE_PERSISTANT 	= 1;

	/**
	 * List for listeners
	 */
	private ArrayList<IChangeListener> changeListeners = new ArrayList<IChangeListener>();


	private Patient patient;

	private boolean isModified = false;


	private List<MeasurementType> mTypes;

	private boolean isOld;

	private IChangeListener notificationListener;

	private String old_accidentNr;

	private Date old_accidentDate;

	protected int state = STATE_NEW;

	//@SuppressWarnings("unused")
	private boolean accidentModified = false;

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


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

	/**
	 * Creates a new model
	 */
	public IncidentModel() {
		/* ====================================================== */
		this(null, null, false);
		/* ====================================================== */
	}

	/**
	 * Creates a model with the given incident
	 *
	 * @param incident
	 */
	public IncidentModel(Incident incident, IncidentControler controler, boolean isOld) {
		/* ====================================================== */
		this.setIncident(incident);
		this.isOld = isOld;

		// get the measurement types
		this.mTypes = controler.getManager().getMeasurementTypes();
		/* ====================================================== */
	}
	/* ---------------------------------------------------------------
	 * End of Constructors
	 * ************************************************************* */


	/* ***************************************************************
	 * Getter/Setter
	 */


	/**
	 * @return
	 */
	public boolean isOld() {
		/* ====================================================== */
		return this.isOld;
		/* ====================================================== */
	}

	/* ----------------------------------------------------------- */
	// Subject
	/* ------------------------------------------------------------ */
	/**
	 * Get anamnesis text
	 *
	 * @return
	 */
	public String getAnamnesis() {
		/* ====================================================== */
		if (this.incident != null)
			try {
				return incident.getEntry(IncidentEntryType.TYPE_S).getTextContent();
			} catch (Exception e) {
				return "";
			}
		
		return "";
		/* ====================================================== */
	}

	/**
	 * Set anamnesis text
	 *
	 * @param text
	 */
	public void setAnamnesis(String text) {
		/* ====================================================== */
		if (this.incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(IncidentEntryType.TYPE_S);
			incident.getEntry(IncidentEntryType.TYPE_S).setTextContent(text);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}

	/**
	 * Returns the accident number
	 *
	 * @return
	 */
	public String getAccidentNr() {
		/* ====================================================== */
		if (incident != null) {
			try {
				return incident.getAccidentNr();
			} catch (Exception e) {
				return "";
			}
		}
		return "";
		/* ====================================================== */
	}

	/**
	 * Set the accident number
	 *
	 * @param number
	 */
	public void setAccidenNr(String number) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			if (state == STATE_PERSISTANT) {//&&
				// check if the accident has been changed
				if (this.old_accidentNr == null && number != null)
					this.accidentModified = true;
				/* ------------------------------------------------------- */
				else if(number == null && old_accidentNr != null)
					this.accidentModified = true;
				/* ------------------------------------------------------- */
				else if (this.old_accidentNr == null && number == null) {
					// do nothing
				}
				/* ------------------------------------------------------- */
			}
			if (old_accidentNr != null && !this.old_accidentNr.equals(number))
					this.accidentModified = true;
			else if (number != null && !"".equals(number.trim()))
					this.accidentModified = true;
			
			incident.setAccidentNr(number);
			publishAccident();
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}
	
	
	/**
	 * Updates the accident to the PatientManagerModule
	 */
	private void publishAccident() {
		/* ================================================== */
		if (incident.getIsAccident()) {
			PatientManagerModule.addPatientAccident(incident);
		} else {
			PatientManagerModule.removePatientAccident(incident);
		}
		/* ================================================== */
	}
	
	
	/**
	 * Get accident date
	 *
	 * @return
	 */
	public Date getAccidentDate() {
		/* ====================================================== */
		if (incident != null) {
			/* ====================================================== */
			try {
				/* ------------------------------------------------------ */
				return incident.getAccidentDate();
				/* ------------------------------------------------------ */
			} catch (Exception e) {
				return null;
			}
			/* ====================================================== */
		} 
		return null;
		/* ====================================================== */
	}


	/**
	 * @param date
	 */
	public void setAccidentDate(Date date) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			if (state == STATE_PERSISTANT &&
					!(old_accidentDate == null && date == null)) {
				/* ------------------------------------------------------- */
				// check if the accident has been changed
				/* ------------------------------------------------------- */
				if (this.old_accidentDate == null && date != null)
					this.accidentModified = true;
				/* ------------------------------------------------------- */
				else if (date == null && old_accidentDate != null)
					this.accidentModified = true;
				/* ------------------------------------------------------- */
				else if (this.old_accidentDate == null && date == null) {
					// do nothing
				} 
				/* ------------------------------------------------------- */
			}
			if (old_accidentDate != null && !this.old_accidentDate.equals(date))
					this.accidentModified = true;
			else if (date != null && !date.equals(this.old_accidentDate))
					this.accidentModified = true;
			
			incident.setAccidentDate(date);
			/* ------------------------------------------------------- */
			publishAccident();
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}

	/**
	 * Returns the anamnesis codes
	 *
	 * @return
	 */
	public String getAnamnesisCodes() {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(IncidentEntryType.TYPE_S).getCode();
			} catch (Exception e) {
				return "";
			}
			/* ------------------------------------------------------ */
		}
		return "";
		/* ====================================================== */
	}

	/**
	 * Set the anamnesis codes
	 *
	 * @param codes
	 */
	public void setAnamnesisCodes(String codes) {
		/* ====================================================== */
		if (incident != null) {
			checkEntity(IncidentEntryType.TYPE_S);
			incident.getEntry(IncidentEntryType.TYPE_S).setCode(codes);
		}
		/* ====================================================== */
	}

	/* ------------------------------------------------------------ */
	// Finding
	/* ------------------------------------------------------------ */

	/**
	 * Returns the finding
	 *
	 * @return
	 */
	public String getFinding() {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(IncidentEntryType.TYPE_O).getTextContent();
			} catch (Exception e) {
				return "";
			}
			/* ------------------------------------------------------ */
		}
		return "";

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

	/**
	 * Set the finding text
	 *
	 * @param text
	 */
	public void setFinding(String text) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(IncidentEntryType.TYPE_O);
			incident.getEntry(IncidentEntryType.TYPE_O).setTextContent(text);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}


	/* -------------------------------------------------------------- */
	// Diagnosis
	/* -------------------------------------------------------------- */

	/**
	 * Return the diagnosis
	 *
	 * @return
	 */
	public String getDiagnosis() {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				/* ------------------------------------------------------ */
				return incident.getEntry(IncidentEntryType.TYPE_A).getTextContent();
				/* ------------------------------------------------------ */
			} catch (Exception e) {
				return "";
			}
			/* ------------------------------------------------------ */
		}
		return "";
		/* ====================================================== */
	}

	/**
	 * Set diagnosis text
	 *
	 * @param text
	 */
	public void setDiagnosis(String text) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(IncidentEntryType.TYPE_A);
			incident.getEntry(IncidentEntryType.TYPE_A).setTextContent(text);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}

	/**
	 * Get the diagnosis codes
	 *
	 * @return
	 */
	public String getDiagnosisCodes() {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				/* ------------------------------------------------------ */
				return incident.getEntry(IncidentEntryType.TYPE_A).getCode();
				/* ------------------------------------------------------ */
			} catch (Exception e) {
				return "";
			}
			/* ------------------------------------------------------ */
		}
		return "";
		/* ====================================================== */
	}

	/**
	 * Set the diagnosis codes
	 *
	 * @param codes
	 */
	public void setDiagnosisCodes(String codes) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(IncidentEntryType.TYPE_A);
			incident.getEntry(IncidentEntryType.TYPE_A).setCode(codes);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}


	/* --------------------------------------------------------------- */
	// Treatment
	/* --------------------------------------------------------------- */

	/**
	 * Return the treatment text
	 *
	 * @return
	 */
	public String getTreatment() {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(IncidentEntryType.TYPE_P).getTextContent();
			} catch (Exception e) {
				return "";
			}
			/* ------------------------------------------------------ */
		}
		return "";
		/* ====================================================== */
	}

	/**
	 * Set the treatment text
	 *
	 * @param text
	 */
	public void setTreatment(String text) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(IncidentEntryType.TYPE_P);
			incident.getEntry(IncidentEntryType.TYPE_P).setTextContent(text);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}


	/**
	 * Returns the value of a measurement by its type<br>
	 * Use<ul>
	 *  <li>IncidentManager.SYS</li>
	 *  <li>IncidentManager.DIA</li>
	 *  <li>IncidentManager.POULSE</li>
	 *  <li>IncidentManager.WEIGHT</li>
	 *  <li>IncidentManager.HEIGHT</li>
	 * </ul>
	 * @param type
	 * @return
	 */
	public String getMeasurementValue(String type) {
		/* ====================================================== */
		if (!"".equals(type)) {
			if (incident != null) {
				if (incident.getMeasurementValues() != null) {
					// find the value
					for (MeasurementValue m : incident.getMeasurementValues())
						if (type.equals(m.getMeasurementType().getName())) {
							if (m.getMeasurementType().isNumericType())
								return ""+(m.getValueNumeric() != null ?
										m.getValueNumeric() : "");
							return (m.getValueString() != null ?
									m.getValueString() : "");
						}

				}
			}
		}
		return "";
	}
	
	/**
	 * Returns the value of a measurement by its type<br>
	 * Use<ul>
	 *  <li>IncidentManager.SYS</li>
	 *  <li>IncidentManager.DIA</li>
	 *  <li>IncidentManager.POULSE</li>
	 *  <li>IncidentManager.WEIGHT</li>
	 *  <li>IncidentManager.HEIGHT</li>
	 * </ul>
	 * @param type
	 * @return
	 */
	public String getMeasurementValue(String type, boolean isStandard) {
		if (!"".equals(type)) {
			if (incident != null) {
				if (incident.getMeasurementValues() != null) {
					// find the value
					for (MeasurementValue m : incident.getMeasurementValues())
						if (type.equals(m.getMeasurementType().getName()) && m.getMeasurementType().isDefault() == isStandard) {
							if (m.getMeasurementType().isNumericType())
								return ""+(m.getValueNumeric() != null ?
										m.getValueNumeric() : "");
							return (m.getValueString() != null ?
									m.getValueString() : "");
						}

				}
			}
		}
		return "";
	}


	/**
	 * Set a measurementvalue
	 *
	 * @param type
	 * @param stringValue
	 * @param numericValue
	 */
	public void setMeasurementValue(String type,
			String stringValue, Double numericValue) {
		/* ====================================================== */
		if (!"".equals(type)) {
			/* ------------------------------------------------------ */
			// if there are no measurements yet, create a new HashSet
			if (this.incident.getMeasurementValues() == null)
				incident.setMeasurementValues(new HashSet<MeasurementValue>());
			/* ------------------------------------------------------ */
			// find the type object for the string
			MeasurementType valueType = null;
			/* ------------------------------------------------------ */
			for (MeasurementType t : mTypes)
				if (t.getName().equals(type)) {
					valueType = t;
					break;
				}
			/* ------------------------------------------------------ */
			if (valueType != null) {
				/* ------------------------------------------------------ */
				// find the value for the type
				for (MeasurementValue mv : incident.getMeasurementValues()) {
					/* ------------------------------------------------------ */
					if (mv.getMeasurementType().equals(valueType)) {
						/* ------------------------------------------------------ */
						// set the data
						if (valueType.isNumericType()) {
							mv.setValueNumeric(numericValue);
							return;
						}
						/* ------------------------------------------------------- */
						mv.setValueString(stringValue);
						return;
						/* ------------------------------------------------------ */
					}
					/* ------------------------------------------------------ */
				}
				/* ------------------------------------------------------ */
				// if we got here, we must create a new measurement value object
				MeasurementValue mvNew = new MeasurementValue();
				/* ------------------------------------------------------ */
				// find the type
				for (MeasurementType t : mTypes)
					if (t.getName().equals(type)) {
						mvNew.setMeasurementType(t);
						break;
					}
				/* ------------------------------------------------------ */
				// if there is no type for the measurement, exit!
				if (mvNew.getMeasurementType() == null) {
					logger.error("Cannot find MeasurementType for string " + type);
					return;
				}
				/* ------------------------------------------------------ */
				// fill the value
				mvNew.setIncident(this.incident);
				mvNew.setMeasurementDate(new Date());
				if (mvNew.getMeasurementType().isNumericType()) {
					mvNew.setValueNumeric(numericValue);
				} else
					mvNew.setValueString(stringValue);
				/* ------------------------------------------------------ */
				// add to the set of incident
				this.incident.getMeasurementValues().add(mvNew);
				// Thats all
			/* ------------------------------------------------------ */
			}

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

	/* ---------------------------------------------------------------
	 * End of Getter/Setter
	 * ************************************************************* */




	/* ***************************************************************
	 * Controls
	 */

	/**
	 * Checks if there is an IncidentEntry object for the type.
	 * If not, a new is created
	 * 
	 * @param typeId
	 */
	private void checkEntity(String typeName) {
		/* ================================================== */
		IncidentEntry e = this.incident.getEntry(typeName);
		if (e == null)
			addEntity(typeName);
		/* ================================================== */
	}
	

	/**
	 * Creates a new IncidentEntry object and adds it to the incident
	 * 
	 * @param typeId
	 */
	private void addEntity(String typeName) {
		/* ================================================== */
		IncidentEntry e = new IncidentEntry(typeName);
		if (incident.getIncidentEntries() == null)
			incident.setIncidentEntries(new ArrayList<IncidentEntry>(0));
		
		this.incident.getIncidentEntries().add(e);
		/* ================================================== */
	}
	
	
	/**
	 * Add a change listener
	 *
	 * @param listener
	 */
	public void addChangeListener(IChangeListener listener) {
		/* ====================================================== */
		changeListeners.add(listener);
		/* ====================================================== */
	}

	/**
	 * Notifies all registered listeners.
	 */
	public void fireModelChanged() {
		/* ====================================================== */
		if (changeListeners != null)
			for (IChangeListener l : changeListeners)
				l.fireEvent();
		/* ====================================================== */
	}


	/**
	 * Get the incident
	 *
	 * @return
	 */
	public Incident getIncident() {
		/* ====================================================== */
		//old // if there is nothing in the textfields, we do not need to save this
		//old if (this.isModified && findInputChanges()) {
		
		// save if the consultation has change with empty text field the consultation will
		// be delete
		if (this.isModified){// && findInputChanges()) {
			// set the physician
			this.incident.setPhysicianId(MainFrame.getCurrentPhysician().getId());
			/* ------------------------------------------------------- */
			return this.incident;
			/* ------------------------------------------------------- */
		}
		/* ------------------------------------------------------- */
		return null;
		/* ====================================================== */
	}

	/**
	 *  set an incident
	 *
	 * @param incident
	 */
	public void setIncident(Incident incident) {
		/* ====================================================== */
		this.incident = incident;
		if (this.incident.isPersistent()) {
			/* ------------------------------------------------------- */
			this.old_accidentNr 	= this.incident.getAccidentNr();
			this.old_accidentDate 	= this.incident.getAccidentDate();

			state = STATE_PERSISTANT;
			/* ------------------------------------------------------- */
		} else {
			/* ------------------------------------------------------- */
			this.old_accidentNr 	= null;
			this.old_accidentDate 	= null;

			state = STATE_NEW;
			/* ------------------------------------------------------- */
		}
		this.accidentModified = false;
		this.fireModelChanged();
		/* ====================================================== */
	}

	/**
	 * Returns the pure incident, even if there are no changes!
	 *
	 * @return
	 */
	public Incident getIncidentForPrescription() {
		/* ====================================================== */
		// set the physician
		try {
			this.incident.setPhysicianId(MainFrame.getCurrentPhysician().getId());
		} catch (Exception e) {
			logger.warn("Cannot set physician id to incident. " +
					"Are there any physicians in the database? ");
		}
		return this.incident;
		/* ====================================================== */
	}

	
	/**
	 * @return
	 */
	public Incident getPureIncident() {
		/* ================================================== */
		return this.incident;
		/* ================================================== */
	}
	
	
	/* ---------------------------------------------------------------
	 * End of controls
	 * ************************************************************* */

	/**
	 * Set the patient to use
	 * 
	 * @param patient
	 */
	public void setPatient(Patient patient) {
		/* ============================================= */
		this.patient = patient;

		// add the patient id
		if (this.patient != null && this.incident != null && this.incident.getPatientId() == null) {
			this.incident.setPatientId(this.patient.getId());
		}
		/* ============================================= */
	}

	public Patient getPatient() {
		/* ================================================== */
		return this.patient;
		/* ================================================== */
	}

	/**
	 * @return
	 */
	public boolean isModified() {
		/* ====================================================== */
		return this.isModified;
		/* ====================================================== */
	}

	/**
	 * @param b
	 */
	public void setModified(boolean b) {
		/* ====================================================== */
		this.isModified = b;
		/* ------------------------------------------------------- */
		// notify listener
		if (this.notificationListener != null)
			notificationListener.fireEvent();

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

	/**
	 * Add a listener that is notified when something changes
	 * 
	 * @param listener
	 */
	public void addNotificationListener(IChangeListener listener) {
		/* ================================================== */
		this.notificationListener = listener;
		/* ================================================== */
	}

	/**
	 * @return
	 */
	public boolean isAccidentModified() {
		/* ================================================== */
		/* ------------------------------------------------------- */
		// check accident changes
		if (state == STATE_PERSISTANT) {
			/* ------------------------------------------------------- */
			// accident date
			boolean accDateChanged = false;
			if (!(this.old_accidentDate == null && this.incident.getAccidentDate() == null)) {
				/* ------------------------------------------------------- */
				if (this.old_accidentDate != null && !this.old_accidentDate.equals(getAccidentDate()))
					accDateChanged = true;
				if (this.getAccidentDate() != null && !this.getAccidentDate().equals(old_accidentDate))
					accDateChanged = true;
				/* ------------------------------------------------------- */
			}
			// accident number
			boolean accNrChanged = false;
			if (!(this.old_accidentNr == null && this.incident.getAccidentNr() == null)) {
				/* ------------------------------------------------------- */
				if (this.old_accidentNr != null && !this.old_accidentNr.equals(getAccidentNr()))
					accNrChanged = true;
				if (this.getAccidentNr() != null && !this.getAccidentNr().equals(old_accidentNr))
					accNrChanged = true;
				/* ------------------------------------------------------- */
			}

			return (accDateChanged || accNrChanged);
		}
		return false;
		/* ================================================== */
	}

	public String getOriginalAccidentNumber() {
		/* ================================================== */
		return this.old_accidentNr;
		/* ================================================== */
	}

	public Date getOriginalAccidentDate() {
		/* ================================================== */
		return this.old_accidentDate;
		/* ================================================== */
	}

	// TODO method are not used
	/**
	 * Return true, if there is some text in a field
	 *
	 * @return
	 */
	private boolean findInputChanges() {
		/* ====================================================== */
		boolean inc = false;
		boolean meas = false;
		/* ------------------------------------------------------- */
		if (containsContent(IncidentEntryType.TYPE_S))
			inc = true;
		if (containsContent(IncidentEntryType.TYPE_O))
			inc = true;
		if (containsContent(IncidentEntryType.TYPE_A))
			inc = true;
		if (containsContent(IncidentEntryType.TYPE_P))
			inc = true;
		
		/* ------------------------------------------------------- */
		// measurements
		if (incident.getMeasurementValues() != null
				&& incident.getMeasurementValues().size() > 0) {
			/* ------------------------------------------------------ */
			// check for content
			for (MeasurementValue v : incident.getMeasurementValues()) {
				// if there is at least in one field some content,
				// we can break the loop and set meas to true
				if (!"".equals(this.getMeasurementValue(v.getMeasurementType().getName()))
					&& !"null".equals(this.getMeasurementValue(v.getMeasurementType().getName()))) {
					/* ------------------------------------------------------ */
					meas = true;
					break;
					/* ------------------------------------------------------ */
				}
			}
			/* ------------------------------------------------------ */
		}

		return ( inc || meas || accidentModified) ? true : false;

		/* ====================================================== */
	}
	
	// TODO method are not used
	/**
	 * @param typeName
	 * @return
	 * @throws Exception 
	 */
	@SuppressWarnings("null")
	private boolean containsContent(String typeName) {
		/* ================================================== */
		
		// TODO  handle all types of entries
		if (       !typeName.equals(IncidentEntryType.TYPE_S) 
				&& !typeName.equals(IncidentEntryType.TYPE_O)
				&& !typeName.equals(IncidentEntryType.TYPE_A)
				&& !typeName.equals(IncidentEntryType.TYPE_P)) {
			/* ------------------------------------------------------- */
			// muhahahaha
			// this is the emergency fallback if there are unchecked entry types
			// You, the developer, have to add the additional checks for content on 
			// this type. At the moment, there is only code and text to check.
			Incident iTemp = null;
			iTemp.getId();
			/* ------------------------------------------------------- */
		}
		
		IncidentEntry e = this.incident.getEntry(typeName);
		if (e == null)
			return false;
		/* ------------------------------------------------------- */
		if (e.getTextContent() != null && !"".equals(e.getTextContent()))
			return true;
		if (e.getCode() != null && !"".equals(e.getCode()))
			return true;
		/* ------------------------------------------------------- */

		// now done in saveIncident in IncidentManagerBean
//		incident.getIncidentEntries().remove(e);
		return false;
		/* ================================================== */
	}

	/**
	 * Returns the text of the entry
	 *
	 * @return
	 */
	public String getEntryTextContent(String entryType) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(entryType).getTextContent();
			} catch (Exception e) {
				return null;
			}
			/* ------------------------------------------------------ */
		}
		return null;

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

	/**
	 * Set the text of the entry
	 *
	 * @param text
	 */
	public void setEntryTextContent(String text, String entryType) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			checkEntity(entryType);
			incident.getEntry(entryType).setTextContent(text);
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}

	/**
	 * Returns the code of the entry
	 *
	 * @return
	 */
	public String getEntryCode(String entryType) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(entryType).getCode();
			} catch (Exception e) {
				return null;
			}
			/* ------------------------------------------------------ */
		}
		return null;
		/* ====================================================== */
	}

	/**
	 * Set the code of the entry
	 *
	 * @param codes
	 */
	public void setEntryCode(String code, String entryType) {
		/* ====================================================== */
		if (incident != null) {
			checkEntity(entryType);
			incident.getEntry(entryType).setCode(code);
		}
		/* ====================================================== */
	}
	
	/**
	 * Returns the start date of a entry from type sick leave
	 *
	 * @return
	 */
	public Date getSickLeaveStartDate(String entryType) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(entryType).getSickLeaveStartDate();
			} catch (Exception e) {
				return null;
			}
			/* ------------------------------------------------------ */
		}
		return null;
		/* ====================================================== */
	}

	/**
	 * Set the start date of a entry form type sick leave
	 *
	 * @param codes
	 */
	public void setSickLeaveStartDate(Date sickLeaveStartDate, String entryType) {
		/* ====================================================== */
		if (incident != null) {
			checkEntity(entryType);
			incident.getEntry(entryType).setSickLeaveStartDate(sickLeaveStartDate);
		}
		/* ====================================================== */
	}
	
	/**
	 * Returns the end date of a entry from type sick leave
	 *
	 * @return
	 */
	public Date getSickLeaveEndDate(String entryType) {
		/* ====================================================== */
		if (incident != null) {
			/* ------------------------------------------------------ */
			try {
				return incident.getEntry(entryType).getSickLeaveEndDate();
			} catch (Exception e) {
				return null;
			}
			/* ------------------------------------------------------ */
		}
		return null;
		/* ====================================================== */
	}

	/**
	 * Set the end date of a entry form type sick leave
	 *
	 * @param codes
	 */
	public void setSickLeaveEndDate(Date sickLeaveEndDate, String entryType) {
		/* ====================================================== */
		if (incident != null) {
			checkEntity(entryType);
			incident.getEntry(entryType).setSickLeaveEndDate(sickLeaveEndDate);
		}
		/* ====================================================== */
	}
}
