/*****************************************************************************
 *                                                                           *
 *  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.ejb.session.interfaces;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.annotation.security.RolesAllowed;
import javax.ejb.Remote;

import lu.tudor.santec.gecamed.core.utils.IncidentFileInfo;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
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.prescription.ejb.entity.beans.Prescription;
import net.sf.jasperreports.engine.JRException;

/**
 * Remote interface for the incidentManager
 *
 *
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: IncidentManager.java,v $
 * <br>Revision 1.49  2013-11-14 18:17:17  donak
 * <br>Fixed versioning issue between JODConverter (Java 1.6) and JBOSS (Java 1.5). Server-side PDF ==> PDF/A conversion should work now.
 * <br>Fixed IncidentEntry getBinaryContent(). Now a call to this functions always provides the binary content of an incident entry, if any. function works on client and server side.
 * <br>Implemented function to update incident entry upload status w/o updating all bean properties.
 * <br>Fixed issue with retrieving default user inactivity logout delay from database
 * <br>
 * <br>Revision 1.48  2013-11-12 12:48:23  donak
 * <br>Document upload:
 * <br>* conversion to pdf/a using open office has been moved to the server. OpenOffice 4 has to be located in the jboss work directory. ATTENTION: it still has to be evaluated if the license agreement dialog occurs when instance is started the first time on the server.
 * <br>* If document contains a description, the first forty characters of the description followed by three dots will be used as title instead of the filename
 * <br>* Upload of incident type letters has been fixed
 * <br>* upload for docx files has been added
 * <br>
 * <br>Upload parameters:
 * <br>* database does now support storage of user dependent properties
 * <br>* The system will automatically remember the last chosen values for confidentiality, facility type, and speciality and propose them as default when the next document will be uploaded.
 * <br>
 * <br>Inactivity Monitor:
 * <br>* the event mouse wheel scrolling is now taken into account for resetting the logoff timer
 * <br>* the logoff delay is now stored in the database. If the database does not contain this parameter, it will be created
 * <br>
 * <br>General:
 * <br>* Optimized incident entry bean handling. Caching will now avoid copying the binary content and the generated pdf content of an incident entry as these elements should only be loaded when needed. Now it should be save to re-implement a proper getBinaryContent() handling.
 * <br>
 * <br>Revision 1.47  2013-10-10 13:08:56  donak
 * <br>Upload of prescriptions to eSanté DSP
 * <br>
 * <br>Revision 1.46  2013-09-30 10:43:05  ferring
 * <br>CDA entry added
 * <br>
 * <br>Revision 1.45  2013-09-11 11:00:28  troth
 * <br>Add global settings for the ImportantDataPanel to enable / disable and set the position of a Panel.
 * <br>
 * <br>Revision 1.44  2013-07-25 14:31:55  troth
 * <br>Now the global settings panel for consultation entries save the data in the setting table of the database.
 * <br>
 * <br>Revision 1.43  2013-06-10 08:22:14  ferring
 * <br>eSante POC
 * <br>
 * <br>Revision 1.42  2013-02-08 15:27:17  ferring
 * <br>Option added for files and letters to attach them to another incident
 * <br>
 * <br>Revision 1.41  2012-06-04 06:03:01  ferring
 * <br>file overview added in tools
 * <br>
 * <br>Revision 1.40  2012-01-24 14:38:52  ferring
 * <br>Errors and warnings of Jenkins build corrected
 * <br>
 * <br>Revision 1.39  2012-01-24 10:19:56  ferring
 * <br>Consultation class removed
 * <br>
 * <br>Revision 1.38  2011-03-21 14:18:56  troth
 * <br>Add one step to the database clear up script which try to fix incident entries where the incident id is null (over the incident id of there childs).
 * <br>
 * <br>Revision 1.37  2010-11-05 15:06:29  troth
 * <br>sub the new dialog to the main menu bar for delete the incidents how have no incident entries. The function of the dialog is now implement in the function 'create Incidententries for Prescription how have one together'.
 * <br>
 * <br>Revision 1.36  2010-11-03 17:45:06  troth
 * <br>expansion of the function that "create Incident Entries for Prescription how have one together" now it also
 * <br>1. sync the incidentIds of Prescriptions and there Incident Entry
 * <br>2. deletes Incidents how have no Incident Entries and no back link from a Prescription
 * <br>
 * <br>Revision 1.35  2010-10-15 14:57:42  troth
 * <br>add function to create Incidententries for Prescription how have one together
 * <br>
 * <br>Revision 1.34  2010-10-13 15:02:53  troth
 * <br>Add new dialog to the main menu bar for delete the incidents how have no incident entries.
 * <br>
 * <br>Revision 1.33  2010-10-12 07:56:17  troth
 * <br>Bug fix - add where clause how check the patient id to deleteNullIncident function in IncidentManager
 * <br>
 * <br>Revision 1.32  2010-09-30 07:02:41  ferring
 * <br>Method added to get an incident between 2 dates
 * <br>
 * <br>Revision 1.31  2010-09-28 16:12:29  troth
 * <br>Complete - # 663: Accident entry can not be individually deleted from the history view.
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/663
 * <br>
 * <br>Revision 1.30  2010-09-20 13:38:37  troth
 * <br>add delete function on (right-click) history popupmenu for S.O.A.P. entries and measurements
 * <br>
 * <br>Revision 1.29  2010-09-17 09:04:35  troth
 * <br>Ticket # 634: Last measurement field cannot be deleted
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/634
 * <br>
 * <br>Revision 1.28  2010-09-15 13:12:44  troth
 * <br>Complete - # 633: Last S.O.A.P. entry cannot be deleted
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/633
 * <br>
 * <br>Revision 1.27  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.26  2010-05-26 16:33:34  troth
 * <br>bugfix - change the way to get a new and create a incident. rename the method getRecentIncident() in class PatientPanel to getCurrentIncident()
 * <br>
 * <br>Revision 1.25  2009-05-06 16:00:05  heinemann
 * <br>added method to generate printable output of the incident entrys
 * <br>
 * <br>Revision 1.24  2009-02-27 15:25:56  hermen
 * <br>added button to create an empty incident for a patient visit
 * <br>
 * <br>Revision 1.23  2008-11-12 17:16:33  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.22  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.21  2008-07-10 10:14:32  hermen
 * <br>added delete incidentEntry by ID
 * <br>
 * <br>Revision 1.20  2008-06-03 12:59:11  weitz
 * <br>*letter package, release candidate
 * <br>
 * <br>Revision 1.19  2008-05-15 09:47:50  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.18  2008-04-11 09:56:45  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.17  2008-03-27 12:34:39  weitz
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.16  2008-03-20 16:08:14  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.15  2008-03-10 12:37:52  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.14  2008-03-06 15:34:27  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.13  2007-12-17 14:59:59  heinemann
 * <br>plugins and file store and open
 * <br>
 * <br>Revision 1.12  2007-11-21 15:17:23  heinemann
 * <br>checkin without warranty!!
 * <br>
 * <br>Revision 1.11  2007-11-20 08:06:36  heinemann
 * <br>Prepare file storage
 * <br>
 * <br>Revision 1.10  2007-10-16 08:23:26  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.9  2007/06/18 11:31:37  hermen
 * <br>cleanup of old stuff and moved some beans
 * <br>
 * <br>Revision 1.8  2007/04/24 13:48:43  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2007/04/11 07:38:47  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.6  2007/03/12 08:41:42  heinemann
 * <br>moved constants of generic measurement type fields to IncidentManager interface
 * <br>
 * <br>Revision 1.5  2007/03/02 08:28:39  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.3.2.3  2007/02/22 12:01:23  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.3.2.2  2006/12/14 10:41:17  hermen
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.3.2.1  2006/12/06 07:49:54  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.3  2006/12/01 14:50:42  heinemann
 * <br>initial checkin
 * <br>
 */
@Remote
public interface IncidentManager {

	/*
	 * Constants for the measurement types
	 */

	public static final String SYS 	  = "SYS";
	public static final String DIA 	  = "DIA";
	public static final String POULSE = "POULSE";
	public static final String HEIGHT = "HEIGHT";
	public static final String WEIGHT = "WEIGHT";
	/* ------------------------------------------------------ */
//	 constants for the entries in the database
	public static final String MEAS_1 = "measurement_1";
	public static final String MEAS_2 = "measurement_2";
	public static final String MEAS_3 = "measurement_3";

	
	public static final String SOAP_S = "soap.s";
	public static final String SOAP_O = "soap.o";
	public static final String SOAP_A = "soap.a";
	public static final String SOAP_P = "soap.p";
	public static final String CONS_1 = "cons.1";
	public static final String CONS_2 = "cons.2";
	public static final String CONS_3 = "cons.3";
	
	// constants for the order panels of the important data panel
	public static final String ACTIVE_PROBLEMS = "active_problems";
	public static final String ALLERGIES = "allergies";
	public static final String ANTECEDENTS = "antecedents";
	public static final String CHRONICAL_TREATMENTS = "chronical_treatments";
	
	//Constants for the history tabs panel
	public static final String FULL_VIEW = "full_view";
	public static final String DIAG = "diagnosis";
	public static final String LETTERS = "letters";
	public static final String FILES = "files";
	public static final String PRESCR = "prescriptions";
	public static final String FORMS = "forms";
	//public static final String CDA = "cda";
	
	/**
	 * This is only used in the client to sort the entries. Do not
	 * create an Entry with this type!!!
	 */
	public static final String ACCIDENT 	= "Ac";
	public static final String MEASUREMENT  = "measurement";
	public static final String PRESCRIPTION = "prescription";
	public static final String FILE 		= "file";	
	public static final String LETTER		= "letter";
	public static final String SICK_LEAVE	= "sick_leave";
	public static final String CDA			= "cda";

	public static final String HISTORY_TABS = "HISTORY_TABS";
	
	/**
	 * Get all measurment types
	 *
	 * @return
	 */
	@RolesAllowed("gecam")
	public List<MeasurementType> getMeasurementTypes();


	/**
	 * Save or update a measurment type
	 *
	 * @param type
	 */
	@RolesAllowed("gecam")
	public void saveMeasurementType(MeasurementType type);

	/**
	 * Return a MeasurmentType object matching the name string
	 *
	 * @param name
	 * @return
	 */
	@RolesAllowed("gecam")
	public MeasurementType getMeasurementType(String name);
	
	/**
	 * Returns all measurement values of an incident entry
	 * 
	 * @param incidentEntryId
	 * @return
	 */
	@RolesAllowed("gecam")
	public List<MeasurementValue> getMeasurementsByIncidentEntry(Integer incidentEntryId);
	
	/**
	 * Get all measurementvalues for a patient.
	 * 
	 * @param patientId
	 * @return
	 */
	@RolesAllowed("gecam")
	public List<MeasurementValue> getMeasurments(Integer patientId);
	
	/**
	 * Save the incident
	 *
	 * @param incident
	 */
	@RolesAllowed("gecam")
	public Incident saveIncident(Incident incident);
	
	/**
	 * retrieves an Incident by its ID
	 * @param id the incident id
	 * @return the incident
	 */
	@RolesAllowed("gecam")
	public Incident getIncident(Integer id);

	/**
	 * Gets all incidents, that are the first consultation of an accident
	 *
	 * @param patientId
	 * @return
	 */
	@RolesAllowed("gecam")
	public List<Incident> getAccidents(Integer patientId);

	/**
	 * Returns all child accident incidents
	 *
	 * @param incidentId
	 * @return
	 */
	@RolesAllowed("gecam")
	public Long getChildAccidentIncidentAmount(Integer incidentId);

	/**
	 * Sets the accident data from the given incident to all connected
	 * incidents
	 *
	 * @param incident
	 */
	@RolesAllowed("gecam")
	public Incident setNewAccidentDataForNestedIncidents(Incident incident);

	/**
	 * Removes the given incident from an accident relation chain.
	 * If it is a parent, the first child will be used as new parent for
	 * the rest.
	 * If it is a child, the parent id is delete an the <strong>unmerged</strong> incident
	 * is returned.
	 * 
	 * @param incident
	 * @return
	 */
	@RolesAllowed("gecam")
	public Incident removeIncidentFromAccidentList(Incident incident);
	
//	/**
//	 * @param patientId
//	 */
//	@RolesAllowed("gecam")
//	public void convertIncident(Integer incidentId);
	
	
//	/**
//	 * Returns a Hash of patient id and name for all
//	 * patients that have at least one consultation
//	 * 
//	 * @return
//	 */
//	public HashMap<Integer, String> getPatientNames();
	
	
//	/**
//	 * Simply counts all consultations in the database
//	 * 
//	 * @return
//	 */
//	@RolesAllowed("gecam")
//	public Long getIncidentCount();
	
//	/**
//	 * Returns all incidents for the patient that have consultations
//	 * @param patientId
//	 * @return
//	 */
//	@RolesAllowed("gecam")
//	public List<Integer> getIncidentIdsWithConsultations(Integer patientId);
	
	/**
	 * Get all IncidentEntryTypes
	 * 
	 * @return
	 */
	@RolesAllowed("gecam")
	public Collection<IncidentEntryType> getAllEntryTypes();
	
	
	/**
	 * Loads the binary content of the incident entry
	 * 
	 * @param entry
	 * @return
	 */
	@RolesAllowed("gecam")
	public IncidentEntry loadBinary(IncidentEntry entry) throws FileNotFoundException, Exception;
	
	
	/**
	 * Loads the binary content of the incident entry
	 * 
	 * @param fileName the physical name of the file
	 * @Param patientId the ID of the patient to get the file for
	 * @return A byte array representing the data of the file.
	 */
	public byte[] loadBinary (String fileName, Integer patientId);
	
	/**
	 * Converts the content of the incident entry to pdf/a format.
	 * 
	 * @param entry
	 *            The incident entry of which the content should be converted
	 * @return The pdf/a version of the incident entry content
	 * @throws IOException
	 *             If the incident entry data could not be found or if there is no appropriate access to the file system (e.g. privileges)
	 * @throws JRException
	 *             If the incident entry data could not be converted to pdf/a (e.g. unsupported format or missing open office installation)
	 */
	public byte[] transformToPdfA(IncidentEntry entry) throws Exception;
	
	/**
	 * Sets the upload indicator for an incident entry. This indicator usually consists of the oid that is assigned to the incident entry, when it is uploaded to the eSanté DSP. That way, it is avoided that an incident entry is uploaded twice.<br>
	 * The upload indicator is stored in table patient.incident_entry, column cda_unique_id
	 * @param entry The incident entry of which the upload indicator (property {@link IncidentEntry#cdaUniqueId} will be saved to db
	 * @param uploadIndicator The value for the uload indicator (usually the oid of the upload)
	 */
	public void saveUploadIndicator(IncidentEntry entry);
	
	/**
	 * Saves the entry and the attached entry type
	 * Returns the merged entry without binary data. must be loaded separately.
	 * 
	 * @param entry
	 * @param type if you do not have a type object, just give the name. mime_type will be blank. Be aware, that
	 * if there is more than one entry type for this name, the first one is chosen. If you want to do more precisely, use
	 * the saveEntry method with an additional mimetype string.
	 * @return
	 */
	@RolesAllowed("gecam")
	public IncidentEntry saveEntry(IncidentEntry entry, String type);
	
	/**
	 * @param entry
	 * @param typename
	 * @param mimetype
	 * @return
	 */
	public IncidentEntry saveEntry(IncidentEntry entry, String typename, String mimetype);
	
	/**
	 * Returns the IncidentEntryType object for that name
	 * 
	 * @param name
	 * @return
	 */
	@RolesAllowed("gecam")
	public IncidentEntryType getTypeByName(String name, String mimetype);
	
	
	/**
	 * @param incidentId
	 * @param entryType
	 * @return
	 */
	@RolesAllowed("gecam")
	public IncidentEntry getEntryForInsert(Integer incidentId, String entryType);
	
//	/**
//	 * @return
//	 */
//	@RolesAllowed("gecam")
//	public boolean convertPrescriptionRevisions();
	
	
//	/**
//	 * @return
//	 */
//	@RolesAllowed("gecam")
//	public boolean convertPrescriptions();
	
	@RolesAllowed("gecam")
	public List<Integer> getPrescriptionIdsToConvert();
	
	@RolesAllowed("gecam")
	public boolean convertPrescription(Integer prescId);
	
	/**
	 * @return
	 */
	@RolesAllowed("gecam")
	public boolean convertMeasurementValues();
	
	
	/**
	 * Delete an MeasurementValues.
	 * 
	 * @param entry
	 * @return
	 */
	@RolesAllowed("gecam")
	public Boolean deleteMeasurementValues(Integer incidentId);
	
	/**
	 * Delete an entry and its binary content.
	 * 
	 * @param entry
	 * @return
	 */
	@RolesAllowed("gecam")
	public Boolean removeIncidentEntry(IncidentEntry entry);
	
	/**
	 * Releases the IncidentEntry from its current Incident and adds it to the target Incident.<br> 
	 * <b>THE INCIDENT ENTRY AND BOTH INCIDENTS HAVE TO BE RELOADED FROM THE DATABASE AFTERWARDS</b>
	 * 
	 * @param entry2Move The IncidentEntry to move.
	 * @param targetIncident The Incident the entry2Move shall be added to.
	 */
	@RolesAllowed("gecam")
	public void moveIncidentEntry (IncidentEntry entry2Move, Incident targetIncident);
	
	/**
	 * Delete an entry and its binary content.
	 * 
	 * @param nicidentEntryID
	 * @return
	 */
	@RolesAllowed("gecam")
	public Boolean removeIncidentEntry(Integer incidentEntryID);
	
	/**
	 * Returns all incidents of the patient.
	 * 
	 * @param patientId The id of the patient
	 * @return
	 */
	public List<Incident> getIncidentsOfPatient (Integer patientId);
	
	/**
	 * Returns the latest incident for the patient that is newer than the specified date
	 * if none -> null
	 * @param patientId
	  * @param  newerThan
	 * @return
	 */
	@RolesAllowed("gecam")
	public Incident getIncidentNewerThan(Integer patientId, Integer physicianId, Date newerThan);

	/**
	 * Set accident data of Incident to false and delete Incident if it have no entries
	 * 
	 * @param incidentId the id of the accident incident
	 */
	@RolesAllowed("gecam")
	public void deleteAccidentIncident(Integer incidentId);

	/**
	 * Returns the latest incident for the patient that is newer, respectively older than the specified dates
	 * if none -> null
	 * @param patientId
	  * @param  newerThan
	 * @return
	 */
	@RolesAllowed("gecam")
	public Incident getIncidentNewerThan(Integer patientId, Integer physicianId, Date newerThan, Date olderThan);
	
	/**
	 * Checks if there are any Incidents of a patient who have no IncidentEntries and are no accidents and deletes them.
	 * 
	 * @param patientId the patient id
	 */
	@RolesAllowed("gecam")
	public Integer deleteNullIncident(Integer patientId);

	/**
	 * Get all patient id's that have Incidents without IncidentEntries and which are no accidents.
	 * 
	 * @return a Integer list of patient id's
	 */
	@RolesAllowed("gecam")
	public List<Integer> getNullIncident();
	
	/**
	 * Get all IncidentEntry id's with more than one prescription
	 * 
	 * @return a Integer list of IncidentEntry id's 
	 */
	@RolesAllowed("gecam")
	public List<Integer> getIncidentEntriesIdWithPrescriptions();
	
	
	/**
	 * Get all prescriptions of the one incidentEntry
	 * 
	 * @param incidentEntryId
	 * @return a Prescription list of all Prescription
	 */
	@RolesAllowed("gecam")
	public List<Prescription> getAllPrescriptionsOfIncidentEntry(Integer incidentEntryId);
	
	
	/**
	 * Provides the prescription that corresponds to the incident
	 * 
	 * @param incidentEntryId
	 *            The id of the incident of which the corresponding prescription is desired
	 * @return The corresponding prescription or null if such a prescription does not exist
	 */
	@RolesAllowed("gecam")
	public Prescription getCorrespondingPrescription(Integer incidentEntryId);


	
	/**
	 * Get IncidentEntry by id
	 * 
	 * @param incidentEntryId
	 * @return the incidentEntry
	 */
	@RolesAllowed("gecam")
	public IncidentEntry getIncidentEntry(Integer incidentEntryId);


	/**
	 * Get all IncidentEntries ids where the incident is null.
	 * 
	 * @return a list of IncidentEntries ids.
	 */
	@RolesAllowed("gecam")
	public List<Integer> getIncidentEntriesIdWhereIncidentIdIsNull();

	/**
	 * Deletes a incidentEntry.
	 * 
	 * @param the incidentEntry.
	 */
	@RolesAllowed("gecam")
	public void deleteIncidentEntry(Integer incidentEntryId);
	
	/**
	 * Get all IncidentEntries that represent attached files
	 * 
	 * @param getApprovedFiles Get also those which are already approved
	 * @return
	 */
	@RolesAllowed("gecam")
	public Collection<IncidentFileInfo> getIncidentFiles (boolean loadApprovedFiles, Physician loadForPhysician);
	
	/**
	 * Change the code in the entry and store and return it
	 * 
	 * @param entry
	 * @param code
	 * @return
	 */
	@RolesAllowed("gecam")
	public IncidentEntry setEntryCode(IncidentEntry entry, String code);
}