/*****************************************************************************
 *                                                                           *
 *  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.certificate;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.SwingConstants;

import lu.tudor.santec.gecamed.billing.gui.BillingModule;
import lu.tudor.santec.gecamed.billing.utils.BillingAdminSettings;
import lu.tudor.santec.gecamed.core.ejb.session.beans.TemplateManagerBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.TemplateManagerInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedFonts;
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.gui.widgets.ErrorDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.PrintPreviewDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.print.PrintParameterFetcher;
import lu.tudor.santec.gecamed.core.utils.JasperTemplateBean;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.core.utils.PrintParameter;
import lu.tudor.santec.gecamed.core.utils.printing.ireport.UtilFormatter;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Office;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.utils.PatientNameFormatter;
import lu.tudor.santec.gecamed.usermanagement.gui.settings.UserSettingsPlugin;
import lu.tudor.santec.i18n.Translatrix;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;


/**
 * class that creates and fills up the "i was at the doctor" certificate template to be printed out. 
 * 
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @version
 * <br>$Log: CertificatePrinter.java,v $
 * <br>Revision 1.35  2013-12-27 18:09:26  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.34  2013-07-15 06:18:37  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.33  2013-01-22 14:21:36  ferring
 * <br>iReport templates will now be compiled only once until the server is stopped
 * <br>
 * <br>Revision 1.32  2012-01-26 13:42:43  troth
 * <br>Add tooltips to the buttons.
 * <br>
 * <br>Revision 1.31  2011-10-05 08:28:59  ferring
 * <br>iReport printing changed. Beans added, only one formatter used for everything and reports changed, so that they only use the bean (util) Parameter
 * <br>
 * <br>Revision 1.30  2011-02-28 15:41:45  troth
 * <br>To provide smaller resolutions for the user interface add the navigation bar icons and function bar icons to the user setting "use small icons"
 * <br>
 * <br>Revision 1.29  2011-02-08 07:11:11  ferring
 * <br>iReport parameter added for certificate printing
 * <br>
 * <br>Revision 1.28  2010-08-23 13:29:14  troth
 * <br>update iReport print formula prescription and certificate. standardize methods to print patient name, physician name and caisse maladie.
 * <br>
 * <br>Revision 1.27  2010-08-20 12:01:35  troth
 * <br>Incomplete - # 603: Formatierung der Matricle Nummer
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/603
 * <br>
 * <br>Revision 1.26  2010-07-19 15:15:35  troth
 * <br>#557: add caisse de maladie to the prescription printout
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/557
 * <br>
 * <br>Revision 1.25  2010-07-08 14:25:17  hermen
 * <br>added
 * <br>		param.put("patientCaisse", patient.getInsurance().getAcronym());
 * <br>		// for possible customizations
 * <br>		param.put("patient", patient);
 * <br>to report
 * <br>
 * <br>Revision 1.24  2010-07-06 13:54:51  hermen
 * <br>fixed template caching
 * <br>
 * <br>Revision 1.23  2010-07-06 13:10:21  troth
 * <br>Bug fix - # 542: Patient name no longer printed in the certificate address area
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/542
 * <br>
 * <br>Revision 1.22  2010-05-21 07:21:38  ferring
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.21  2010-04-27 15:11:14  mack
 * <br>Changes required by changes in template formatting class
 * <br>
 * <br>Revision 1.20  2010-04-08 14:57:14  hermen
 * <br>jasper templates are now compiled on demand from the jrxml files
 * <br>
 * <br>Revision 1.19  2010-04-08 11:01:48  hermen
 * <br>report is now compiled on demand
 * <br>
 * <br>Revision 1.18  2009-09-07 08:04:13  hermen
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.17  2009-06-30 08:56:05  hermen
 * <br>created getName4Printing in physician for printing the name
 * <br>
 * <br>Revision 1.16  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.15  2008-09-15 10:07:06  hermen
 * <br>now uses Physician Address if set
 * <br>
 * <br>Revision 1.14  2008-08-21 15:45:12  heinemann
 * <br>removed the bogus behaviour when there is no office entry in the database. The fields on the print outs are now left blank. The user gets an information that the office address is missing.
 * <br>
 * <br>Revision 1.13  2008-05-29 10:08:20  hermen
 * <br>now uses physician address for printing if set, else office address
 * <br>
 * <br>Revision 1.12  2008-02-07 15:53:41  mack
 * <br>Changes required by moving constants for settings in dedicated setting file in utils package
 * <br>
 * <br>Revision 1.11  2008-01-22 16:10:15  mack
 * <br>Added certifcateDate and patientTitle for printing certificates
 * <br>
 * <br>Revision 1.10  2008-01-21 14:16:33  hermen
 * <br>*** empty log message ***
 * <br>
 *
 */
public class CertificatePrinter {

	private static Logger logger = Logger.getLogger(CertificatePrinter.class
			.getName());
	
	public static final String TEMPLATE_CERTIFICATE_MORNING = "cert_morning";
	public static final String TEMPLATE_CERTIFICATE_AFTERNOON = "cert_afternoon";
	
	private DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

	private CertificateDialog dialog;

//	private UtilFormatter formatter;
	
	private TemplateManagerInterface templateManager;

//	private HashMap<String,JasperReport> compiledDefaultTemplates = new HashMap<String, JasperReport>();
	
	private static PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
	
//	private static SSNFormatter ssnFormatter = new SSNFormatter();
	
	public CertificatePrinter() {
		dialog = new CertificateDialog();
//		formatter = new UtilFormatter ();
//		formatter.setPatientNamePrintMode(PatientNameFormatter.CAPITALIZE_WORDS);
//		try {
//			formatter.setReferenceAddress(MainFrame.getCurrentOffice().getLatestOfficeAddress());
//		} catch (Exception e) {
//		}
		try {
			templateManager = (TemplateManagerInterface)ManagerFactory.getRemote(TemplateManagerBean.class);
		} catch (Exception e) {
			logger.log(Level.WARN, "error getting templateManager", e);
		}
	}
	
	/**
	 * prints the template using the PrintPreviewDialog
	 * @return has been printed
	 */
	public boolean printCertificate() {
		
		try {
			JasperPrint prescPrint = createCertificate();
			if (prescPrint == null) 
				return false;
			return printPreviewDialog.doPrint(prescPrint);
		} catch (Exception e) {
			logger.log(Level.WARN, "error printing certificate", e);
			return false;
		}
	}
	
	
	/**
	 * fills and compiles the jasper template
	 * @return the filled JasperPrint object.
	 * @throws JRException
	 */
	private JasperPrint createCertificate() throws JRException {
		
		Physician phy = GECAMedModule.getCurrentPhysician();
		Office office = MainFrame.getCurrentOffice();
		Patient p = GECAMedModule.getCurrentPatient();
		JasperReport cert = null;
		
		if (! dialog.showDialog()) {
			return null;
		}
		
		HashMap<String, Object> param = PrintParameterFetcher.createDefaultPrintParameter(dialog.getDate(), dialog.getAccident());
//		param.put(PrintParameterFetcher.PRINT_PARAMETER_FORMATER, formatter);
		UtilFormatter formatter = (UtilFormatter) param.get(PrintParameter.PRINT_PARAMETER_FORMATTER);
		formatter.setPatientNamePrintMode(PatientNameFormatter.CAPITALIZE_WORDS);
		
		if (dialog.isMorning())
//			cert = findTemplate(TEMPLATE_CERTIFICATE_MORNING, phy.getId(),dialog.getDate());
			cert = findTemplate(JasperTemplateBean.CERTIFICATE_MORNING, phy.getId(), dialog.getDate());
		else
//			cert = findTemplate(TEMPLATE_CERTIFICATE_AFTERNOON, phy.getId(),dialog.getDate());
			cert = findTemplate(JasperTemplateBean.CERTIFICATE_AFTERNOON, phy.getId(), dialog.getDate());
		
		if (cert == null) {
		    ErrorDialog.showErrorDialog(MainFrame.getInstance(), "Printing Problem! ", "No Template found...", "");
		    return null;
		}
		
		if (BillingModule.getInstance() != null && (Boolean) BillingModule.getSetting (BillingAdminSettings.c_SplitBillingSetting)) {
			param.put("ucmCode", phy.getUcmCode());
		} else {
			if (office != null)
				param.put("ucmCode", office.getUcmCode());
		}
		
		param.put("certificateDate", df.format(dialog.getDate()));
		
		param.put("drName", formatter.formatPhysicianName(phy, true));
		param.put("drType", phy.getSpeciality());
		
		param.put("officeName", office.getName());
		
		param.put("officeAddress", formatter.formatPhysicianAddress(phy));
		param.put("officeAddressLine", formatter.formatPhysicianName(phy, true) + ", " + formatter.formatPhysicianLine(phy));
//		
//		
//		if (phy.getPhysicianAddress() != null) {
//		    param.put("officeAddress", formatter.formatPhysicianAddress(phy));
//		    if(office.getName().equals("") || office.getName() == null) param.put("officeAddressLine", formatter.formatPhysicianName(phy, true) + ", " + formatter.formatPhysicianLine(phy));
//		    else param.put("officeAddressLine", office.getName() + ", " + formatter.formatPhysicianLine(phy));
//		} else {
//		    param.put("officeAddress", formatter.formatOfficeAddress(office));
//		    if(office.getName().equals("") || office.getName() == null) param.put("officeAddressLine", formatter.formatPhysicianName(phy, true) + ", " + formatter.formatOfficeLine(office));
//		    else param.put("officeAddressLine", office.getName() + ", " + formatter.formatOfficeLine(office));
//		}
		
		param.put("officePhone", formatter.formatOfficePhones(office, phy));
		
		param.put("patientTitle", Translatrix.getTranslationString("Title." + p.getTitle()));
		
		String ssn = formatter.formatSSN(p.getSocialSecurityNumber());
		param.put("patientMatricule", ssn);
		
		String patientName = formatter.formatPatientName(p,true,false);
		param.put("patientName", patientName);
		
		/* ------------------------------------------------------- */

		param.put("patientAddress", patientName + System.getProperty("line.separator") + formatter.formatPatientHomeAddress(p));

		if (p.getInsurance() != null)
			param.put("patientCaisse", p.getInsurance().toString());
		else
			param.put("patientCaisse", "");
		
		// for possible customizations
		param.put("patient", p);
		
		if (dialog.getAccident().isPersistent()) {
			param.put("accNumber", dialog.getAccident().getAccidentNr());
			param.put("accDate", dialog.getAccident().getAccidentDate());
		}

		if (phy.getPhysicianAddress() != null) {
		    param.put("location_date", phy.getPhysicianAddress().getLocality() + ", le " +
			    df.format(dialog.getDate()));
		} else {
			if (office != null && office.getLatestOfficeAddress() != null) {
			    param.put("location_date", office.getLatestOfficeAddress().getLocality() + ", le " +
				    df.format(dialog.getDate()));
			}
		}

		try {
			JasperPrint jp = templateManager.createJasperPrint(cert, param);
			jp.setName(formatter.formatPatientName(p,PatientManagerModule.isMaidenConfig(),false) + " " + dialog.getDate());
			return jp;		
		} catch (Exception e) {
			logger.log(Level.WARN, "error creating JasperPrint for certificate", e);
		}
		return null;
	}
	
	
	/**
	 * retrieves the template to use for the certificate
	 * @param templateName name of the used template
	 * @param physicianId current physician
	 * @param dateOfInterest time period for the template, as old/new templates can be used.
	 * @return
	 */
	private JasperReport findTemplate(String templateName, Integer physicianId, Date dateOfInterest) 
	{
		return templateManager.findTemplate(templateName, physicianId, dateOfInterest);
		
//		JasperReport jasperReport = null;
//		try {
//			Template t = null;
//			try {
//				t = templateManager.getTemplate(templateName, physicianId,dateOfInterest);
//			} catch (Exception e) {
//			}
//			if (t != null ) {
//				jasperReport = (JasperReport)JRLoader.loadObject(new ByteArrayInputStream(t.getJasper()));
//			} else {
//			    
//			    if (compiledDefaultTemplates.get(templateName) == null) {
//				JasperDesign design = (JasperDesign)JRXmlLoader.load(CertificatePrinter.class.getResourceAsStream("templates/" + templateName + ".jrxml"));
//				compiledDefaultTemplates.put(templateName, templateManager.compileReport(design));
//			    }
//			    jasperReport = compiledDefaultTemplates.get(templateName);
//			    	
//			}
//
//		} catch (Exception e) {
//			logger.log(Level.WARN, "error finding certificate", e);
//		}
//		return jasperReport;
	}
	
	
	/**
	 * returns the buttons that will be shown in the patient navi bar on the right of the screen
	 * @return JButton to print a certificate
	 */
	public Vector<JButton> getButtons() {
		Vector<JButton> v = new Vector<JButton>();
		
		boolean smallIcons = false;
		try {
			smallIcons = (Boolean) MainFrame.getInstance().userSettings.getValue(UserSettingsPlugin.SMALL_ICONS);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		JButton b = new JButton(Translatrix.getTranslationString("patient.certificate.printCertificate"), 
				(smallIcons?GECAMedModule.getMiniIcon(GECAMedIconNames.PRINT):GECAMedModule.getMediumIcon(GECAMedIconNames.PRINT)));
		b.setHorizontalAlignment(SwingConstants.LEFT);
		b.setEnabled(true);
		b.setToolTipText(Translatrix.getTranslationString("patient.certificate.printCertificateTip"));
		b.setIconTextGap(1);
		b.setFont(GECAMedFonts.BUTTON_FONT);
		b.setMargin(new java.awt.Insets(0, 0, 0, 0));
		b.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				printCertificate();
			}
		});
		v.add(b);
		return v;
	}	
}