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

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JPanel;

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.ejb.entity.beans.Incident;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.incident.IncidentControler;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.Prescription;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrescriptionDrug;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrescriptionTemplate;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrescriptionType;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrintPrescription;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.TemplateDrug;
import lu.tudor.santec.gecamed.prescription.ejb.session.beans.PrescriptionManagerBean;
import lu.tudor.santec.gecamed.prescription.ejb.session.interfaces.PrescriptionManager;
import lu.tudor.santec.gecamed.prescription.gui.util.PrescriptionPrinter;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.ITemplateReceiver;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.TemplateControler;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;

/**
 * Controler for the prescription EditorPanel.
 * It holds all important functionalities for the EditorPanel.
 * All external components communicates to the editor by this controler
 * 
 * 
 * 
 * 
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: EditorControler.java,v $
 * <br>Revision 1.22  2013-12-27 18:09:24  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.21  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.20  2010-09-01 12:02:57  troth
 * <br>Incomplete - # 301: Prescription date appears in the accident filed in print out
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/301
 * <br>
 * <br>Revision 1.19  2008-10-21 12:28:27  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.18  2008-10-14 13:30:47  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.17  2008-09-25 09:43:08  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.16  2008-07-23 15:13:57  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.15  2008-07-23 10:00:50  heinemann
 * <br>removed stand_alone column from prescription and prescription_revisions table
 * <br>
 * <br>Revision 1.14  2008-05-13 11:53:41  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.13  2008-05-13 09:33:26  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.12  2008-05-09 15:24:16  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.11  2008-01-16 15:33:35  heinemann
 * <br>better documentation
 * <br>
 * <br>Revision 1.10  2008-01-15 13:40:46  heinemann
 * <br>better documentation
 * <br>
 * <br>Revision 1.9  2007-11-20 08:58:53  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:27  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2007/07/04 08:50:50  heinemann
 * <br>*** empty log message ***
 * <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/25 08:50:59  heinemann
 * <br>Added accident data to prescription.
 * <br>
 * <br>Revision 1.4  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.3  2007/03/07 09:45:05  heinemann
 * <br>bug fixes
 * <br>
 * <br>Revision 1.2  2007/03/02 08:28:42  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1.2.16  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.15  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.14  2007/01/19 12:44:17  heinemann
 * <br>Complete - # 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.13  2007/01/11 13:41:06  heinemann
 * <br>Complete - # 21: Context Menu -> create new prescription
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/21
 * <br>
 * <br>Revision 1.1.2.12  2007/01/08 09:51:59  heinemann
 * <br>Incomplete - # 21: Context Menu -> create new prescription
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/21
 * <br>
 * <br>Revision 1.1.2.11  2007/01/04 13:51:37  heinemann
 * <br>The great space cleaning lady has done a big bunch of refactoring
 * <br>
 * <br>Revision 1.1.2.10  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.9  2007/01/03 15:48:12  heinemann
 * <br>prescription was lost, when printing was aborted
 * <br>
 * <br>Revision 1.1.2.8  2006/12/28 15:47:15  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.7  2006/12/28 10:32:26  heinemann
 * <br>bug fixing and template improvements
 * <br>
 * <br>Revision 1.1.2.6  2006/12/21 15:56:06  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.5  2006/12/21 14:28:51  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.4  2006/12/21 14:26:43  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.3  2006/12/19 14:53:05  heinemann
 * <br>printing etc
 * <br>
 * <br>Revision 1.1.2.2  2006/12/15 15:59:11  heinemann
 * <br>presc
 * <br>
 * <br>Revision 1.1.2.1  2006/12/14 09:34:01  heinemann
 * <br>many changes
 * <br>
 */
public class EditorControler implements ITemplateReceiver {

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

	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(EditorControler.class.getName());

	public static final int STATE_READY 			  = 0;
	public static final int STATE_MODIFY_PRESCRIPTION = 1;



	private EditorModel model;
	private EditorPanel panel;
	protected EditorDrugTableModel drugTableModel;
	private Patient currentPatient;

	protected boolean editorEnabled = true;

	protected IncidentControler incidentControler;

	private String type;


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


	/**
	 * @param incidentControler
	 */
	public EditorControler(IncidentControler incidentControler) {
		/* ====================================================== */

		this.incidentControler = incidentControler;

		// create a model
		this.model = new EditorModel(this);
		// create a model for the drug table
		this.drugTableModel = new EditorDrugTableModel();
		// create a panel
		this.panel = new EditorPanel(model, drugTableModel);

		/* ------------------------------------------------------- */
		// set the action for the cancelButton
		panel.cancelButton.setAction(new AbstractAction(
				Translatrix.getTranslationString("prescription.core.cancel")
				, GECAMedModule.getSmallIcon(
						GECAMedIconNames.CANCEL)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				Prescription p = new Prescription();
				p.setPrescriptionTypeId(model.getPrescription().getPrescriptionTypeId());
				p.setPrescriptionDate(new Date());
				model.setPrescription(p);
				model.fireModelChanged();
				/* ------------------------------------------------------- */
				// hide the cancel button
//				panel.cancelButton.setVisible(false);
				panel.setCancelButtonVisible(false);
				panel.setEditorBackground(Color.WHITE);
				/* ====================================================== */
			}

		});
		panel.cancelButton.setText("");
		panel.cancelButton.setToolTipText(Translatrix.getTranslationString("prescription.core.cancel"));
		
		/* ------------------------------------------------------- */
		// chronical box
		/* ------------------------------------------------------- */
		panel.chronicalCheckBox.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				setCurrentChronic(panel.chronicalCheckBox.isSelected());
				/* ====================================================== */
			}
			
		});
		
		/* ====================================================== */
	}



	/* ************************************************************
	 * Methods
	 */


	/**
	 * @return
	 */
	public boolean isModified() {
		/* ====================================================== */
		if (drugTableModel.isModified() || model.isModified())
			return true;
		
		return false;
		/* ====================================================== */
	}

	/**
	 * Switch the prescription type
	 *
	 * @param type
	 */
	public void switchType(String type) {
		/* ====================================================== */
		panel.switchType(type);
		model.switchType(type);
		this.type = type;
		/* ====================================================== */
	}

	/**
	 * Reset the widget, for new patient, or new consultation
	 */
	public void reset() {
		/* ====================================================== */
		model.reset();
		panel.reset();
		drugTableModel.reset();

		panel.setBackground(Color.WHITE);
		panel.setCancelButtonVisible(false);
		panel.setEditorBackground(Color.WHITE);
		/* ====================================================== */
	}

	/**
	 * Get the panel
	 *
	 * @return
	 */
	public JPanel getPanel() {
		/* ====================================================== */
		return this.panel;
		/* ====================================================== */
	}



	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.ITemplateReceiver#receiveTemplate(lu.tudor.santec.gecamed.prescription.ejb.entity.beans.v1.PrescriptionTemplate)
	 *
	 * Receive the temlpate from the template list
	 *
	 */
	public void receiveTemplate(PrescriptionTemplate template) {
		/* ============================================= */

		if (editorEnabled) {
			this.model.addTemplate(template);
			if (template.getTemplateDrugs() != null) {
				Set<PrescriptionDrug> ds = new HashSet<PrescriptionDrug>();
				for (TemplateDrug t : template.getTemplateDrugs()) {
					/* ------------------------------------------------------ */
					PrescriptionDrug d = TemplateControler.templateDrug2Drug(t);
					ds.add(d);
					/* ------------------------------------------------------ */
				}
	//			this.drugTableModel.setNewDrugs(ds);
				drugTableModel.addDrugs(ds);
			}
		}
		/* ============================================= */
	}

	/**
	 * @param prescArr
	 */
	public void represcribe(Object[] prescArr) {
		/* ====================================================== */
		if (prescArr != null && prescArr.length > 0) {
			/* ------------------------------------------------------ */
			StringBuffer buff = new StringBuffer();
			Set<PrescriptionDrug> drugs = new LinkedHashSet<PrescriptionDrug>();
			for (Object o : prescArr) {
				/* ------------------------------------------------------ */
				Prescription p = (Prescription) o;
				buff.append(p.getTextContent()+"\n\n");
				if (this.type.equals(PrescriptionType.MEDICINE)) {
					// drugs
					if (p.getPrescriptionDrugs() != null) {
						for (PrescriptionDrug d : p.getPrescriptionDrugs()) {
							/* ------------------------------------------------------ */
							drugs.add(d.copy());
							/* ------------------------------------------------------ */
						}
					}
				}
				/* ------------------------------------------------------ */
			}
			if (this.type.equals(PrescriptionType.MEDICINE)) {
				drugTableModel.reset();
				drugTableModel.setNewDrugs(drugs);
			} else {
				model.setTextContent(buff.toString());
				model.fireModelChanged();
			}
		}
			/* ------------------------------------------------------ */
		/* ====================================================== */
	}






	/**
	 * Save all prescriptions for the current consultation
	 */
	public void saveData(Incident incident) {
		/* ============================================= */
		// as prescriptions can not be modified, we mustn't check
		// whether the prescriptions is persistant or not
		// just do it =)
		if (incident != null && incident.isPersistent()) {
			/* ------------------------------------------------------ */
			// save
			List<Prescription> ps = getManager().savePrescription(
					model.getModifiedPrescriptions(incident,
													PatientManagerModule.getCurrentPatient()));
			model.setPrescriptions(ps);
			/* ------------------------------------------------------ */
			// try to set the drugs
//			for (Prescription p : ps) {
//				if (p.getPrescriptionDrugs() != null
//						&& p.getPrescriptionDrugs().size() > 0) {
//					drugTableModel.reset();
//					drugTableModel.addDrugs(new HashSet<PrescriptionDrug>(p.getPrescriptionDrugs()));
//				}
//			}
			// now the modul is reseted
			this.reset();
			/* ------------------------------------------------------ */
			/* ------------------------------------------------------ */
		}
		panel.setBackground(Color.WHITE);
		model.fireModelChanged();
		/* ============================================= */
	}

	protected static PrescriptionManager getManager() {
		/* ====================================================== */
		return (PrescriptionManager) ManagerFactory.getRemote(
				PrescriptionManagerBean.class);
		/* ====================================================== */
	}



	/**
	 * @param currentPatient
	 */
	public void setPatient(Patient currentPatient) {
		/* ============================================= */
		this.currentPatient = currentPatient;
		/* ============================================= */
	}


	/**
	 * Returns the printButton from the EditorPanel
	 *
	 * @return
	 */
	public JButton getPrintButton() {
		/* ====================================================== */
		return panel.printButton;
		/* ====================================================== */
	}

	/**
	 * @return
	 */
	public JButton getTemplateButton() {
		/* ====================================================== */
		return panel.templateButton;
		/* ====================================================== */
	}

	/**
	 *
	 * Print the current Prescription and save the incident, the prescription
	 * and the PrescriptionPrint
	 *
	 * @param incidentForPrescription
	 */
	public boolean printPrescription(Incident incident) {
		/* ============================================= */
//		 as prescriptions can not be modified, we mustn't check
		// whether the prescriptions is persistant or not
		// just do it =)
		if (incident != null && incident.isPersistent()) {
			/* ------------------------------------------------------ */
			// get the appropriate prescription
			Prescription p = model.getCurrentPrescriptionForPrint(
					currentPatient);
			if (p == null)
				return false;
			p.setIncidentId(incident.getId());
			/* ------------------------------------------------------- */
			// add accident data
//			p.setAccidentDate(incident.getAccidentDate());
//			p.setAccidentNr(incident.getAccidentNr());

			/* ------------------------------------------------------ */
			Prescription newPresc = doPrint(p);
			if (newPresc != null) {
				model.setPrescription(newPresc);
				model.fireModelChanged();
				return true;
			}

			/* ------------------------------------------------------ */
		}
		
		return false;
		/* ============================================= */
	}

	
	
	
	
	public static Prescription doPrint(Prescription p) {
		/* ====================================================== */
		//	print
		if (PrescriptionPrinter.print(p, false, false)) {
			/* ------------------------------------------------------ */
			// create PrescriptionPrint object
			PrintPrescription print = new PrintPrescription();

			print.setPrintedById(MainFrame.getCurrentUserId());
			print.setPrintDate(new Date());
			print.setIsCopy(false);
			print.setPrescription(p);
			if (p.getPrintPrescriptions() == null)
				p.setPrintPrescriptions(new HashSet<PrintPrescription>());
			p.getPrintPrescriptions().add(print);
			// and save the Prescription
			Prescription newPresc = getManager().savePrescription(p);

			return newPresc;
			/* ------------------------------------------------------ */
		}
		
		logger.error("Unable to print prescription!!!!");
		return null;
		/* ====================================================== */
	}


	/**
	 * @param presc
	 */
	public static void printCopy(Prescription presc) {
		/* ====================================================== */
		if (presc != null && presc.isPersistent()) {
			/* ------------------------------------------------------ */
//			 print
			if (PrescriptionPrinter.print(presc, true, false)) {
				/* ------------------------------------------------------ */
				// create PrescriptionPrint object
				PrintPrescription print = new PrintPrescription();

				print.setPrintedById(MainFrame.getCurrentUserId());
				print.setPrintDate(new Date());
				print.setIsCopy(true);
				print.setPrescription(presc);
				if (presc.getPrintPrescriptions() == null)
					presc.setPrintPrescriptions(new HashSet<PrintPrescription>());
				presc.getPrintPrescriptions().add(print);
				// and save the Prescription
				getManager().savePrescription(presc);

				/* ------------------------------------------------------ */
			}
			else {
				logger.error("Unable to print prescription!!!!");
			}
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */
	}
	
	
	public void setCurrentChronic(boolean b) {
		/* ================================================== */
		model.getPrescription().setIsChronic(b);
//		model.fireModelChanged();
		/* ================================================== */
	}
	
	
//	/**
//	 * Checks, whether the current prescription is a standalone
//	 * prescription or not
//	 *
//	 * @param incident
//	 * @return
//	 */
//	private boolean checkStandAlone(Incident incident) {
//		/* ====================================================== */
////		if ((incident.getConsultations() == null
////				|| incident.getConsultations().size() == 0)
//		if ((incident.getIncidentEntries() == null
//				|| incident.getIncidentEntries().size() == 0)
//				&&
//				(incident.getMeasurementValues() == null
//						|| incident.getMeasurementValues().size() == 0))
//			/* ------------------------------------------------------ */
//			return true;
//		/* ------------------------------------------------------ */
//		return false;
//		/* ====================================================== */
//	}



	/**
	 * Trys to load prescriptions, that might be attached to this incident
	 *
	 * @param id
	 */
	public void loadPrescriptions(Integer id) {
		/* ============================================= */
		if (id == null) {
			this.editorEnabled = true;
			return;
		}
		/* ------------------------------------------------------ */
		List<Prescription> presc = getManager().getPrescriptionByIncidentId(id);
		if (presc != null) {
			/* ------------------------------------------------------ */
			model.setPrescriptions(presc);

			/* ------------------------------------------------------ */
			// try to set the drugs
			for (Prescription p : presc) {
				if (p.getPrescriptionDrugs() != null
						&& p.getPrescriptionDrugs().size() > 0)
					drugTableModel.addDrugs(new HashSet<PrescriptionDrug>(p.getPrescriptionDrugs()));
			}
			/* ------------------------------------------------------ */
		}
		/* ------------------------------------------------------ */
		// in order to keep the old prescriptions save, disable the
		// editor
//		panel.setEnableEditorArea(false);
		this.editorEnabled = true;


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



	public void modifyPrescription(Object[] selectedValues) {
		/* ====================================================== */
		if (selectedValues != null && selectedValues.length > 0) {
			/* ------------------------------------------------------- */
			panel.setEditorBackground(new Color(155, 221, 78));
			/* ------------------------------------------------------- */
			Prescription p = (Prescription) selectedValues[0];
			model.setPrescription(p);
			model.fireModelChanged();
			panel.setCancelButtonVisible(true);
			/* ------------------------------------------------------- */
		}
		/* ====================================================== */
	}

	/* ------------------------------------------------------------
	 * End of Methods
	 * *********************************************************** */
}
