/*******************************************************************************
 * 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.patient.gui.erisk;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
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.erisk.connector.EriskInterface;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmConstants;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmHCParty;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmHeader;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmItem;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmTransaction;
import lu.tudor.santec.gecamed.patient.gui.erisk.kmehr.KmehrWriter;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;
import org.jdom.Element;

import com.jacob.com.ComFailException;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;

/**
 * Class to open the Pfizer ERISK and E-KOMPAS applications 
 * with the data of the current patient.
 * Works on Windows only, applications have to be installed on the system.
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @version
 * <br>$Log: EriskStarter.java,v $
 * <br>Revision 1.13  2013-12-27 18:09:27  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.12  2013-12-05 16:38:19  ferring
 * <br>Throwables catching changed to get more output about errors
 * <br>
 * <br>Revision 1.11  2013-07-15 06:18:39  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.10  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.9  2008-08-19 10:25:08  heinemann
 * <br>cleanup
 * <br>
 * <br>Revision 1.8  2008-05-19 09:37:47  hermen
 * <br>removed stacktrace
 * <br>
 * <br>Revision 1.7  2008-01-21 14:57:22  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 *
 */
public class EriskStarter {

	private static final String GECAMED_ID = "Tudor.Santec.GECAMed";
	private static final String GECAMED_NAME = "GECAMed";
	
	private static final String ERISK_CALCULATOR_ID = "Pfizer.e-Risk.Calculator";
	private static final String ERISK_CALCULATOR_NAME = "E-risk Calculator";
	private static final String APPLICATION_EKOMPAS = "E-KOMPAS";
	private static final String APPLICATION_ERISK = "E-RISK";

	private DateFormat messageIdDateFormat = new SimpleDateFormat(
			"yyyyMMddHHmmssSSS");
	
	/** the logger Object for this class */
    private static Logger logger = Logger.getLogger(EriskStarter.class.getName());
	public static boolean unsavedChanges;
    
	
	
	/**
	 * starts the application.....
	 * @param app
	 * @throws Exception
	 */
	public void start(String app) throws Exception{
		
		if (unsavedChanges)
			JOptionPane.showMessageDialog(
					MainFrame.getInstance(),
					Translatrix.getTranslationString("erisk.unsavedChanges"));
		
		Patient patient = GECAMedModule.getCurrentPatient();
		Physician physician = GECAMedModule.getCurrentPhysician();

		KmehrWriter writer = new KmehrWriter();
			
		KmHeader header = new KmHeader(patient.getSocialSecurityNumber() + "." + messageIdDateFormat.format(new Date()));
		
		KmHCParty sendingPhysician = new KmHCParty(
				KmHCParty.PERSPHYSICIAN,
				ucm2KMehrID(physician.getUcmCode()), 
				physician.getFirstName(),
				physician.getName());
		
		KmHCParty sendingApp = new KmHCParty(
				KmHCParty.APPLICATION, 
				GECAMED_ID, 
				GECAMED_NAME);
		header.addSender(sendingApp.getElement());
		
		header.addSender(sendingPhysician.getElement());
		
		KmHCParty receivingApp = new KmHCParty(
				KmHCParty.APPLICATION,
				ERISK_CALCULATOR_ID, 
				ERISK_CALCULATOR_NAME);
		
		header.addRecipient(receivingApp.getElement());
		
		header.addRecipient(sendingPhysician.getElement());
		
		writer.setHeader(header);
		
		writer.newFolder();
		
		writer.setPatient(patient);
		
		KmTransaction.resetTransactionNr();
		
		KmTransaction transaction = new KmTransaction(
				KmConstants.TRANSACTION_REQUEST, 
				sendingPhysician.getElement(), 
				true, 
				true);
		
		
		KmItem.resetItemNr();
		KmItem item = new KmItem(KmItem.TYPE_TECHNICAL, KmItem.ITEMDEF_ERISK, KmItem.SEX);
		Element text = new Element("text");
		text.setText( patient.getGender());
		text.setAttribute("L", "en");
		item.addContent(text);

		transaction.addItem(item.getElement());
		
		writer.addTransaction(transaction);
		
		String message = new String(writer.writeMessage());
		logger.info(message);
		
		EriskInterface ie = new EriskInterface();
		
		ie.startEriskModule(message, app);
		
		new DispatchEvents(ie, new ERiskEvents());
		
		ie.safeRelease();
		
		unsavedChanges = true;
	}
	
	/**
	 * callback class to handle events from the external applications
	 * 
	 *
	 * @author Johannes Hermen johannes.hermen(at)tudor.lu
	 *
	 * @version
	 * <br>$Log: EriskStarter.java,v $
	 * <br>Revision 1.13  2013-12-27 18:09:27  donak
	 * <br>Cleanup of imports
	 * <br>
	 * <br>Revision 1.12  2013-12-05 16:38:19  ferring
	 * <br>Throwables catching changed to get more output about errors
	 * <br>
	 * <br>Revision 1.11  2013-07-15 06:18:39  ferring
	 * <br>logging changed
	 * <br>
	 * <br>Revision 1.10  2008-09-25 09:43:10  heinemann
	 * <br>fixed copyrights
	 * <br>
	 * <br>Revision 1.9  2008-08-19 10:25:08  heinemann
	 * <br>cleanup
	 * <br>
	 * <br>Revision 1.8  2008-05-19 09:37:47  hermen
	 * <br>removed stacktrace
	 * <br>
	 * <br>Revision 1.7  2008-01-21 14:57:22  hermen
	 * <br>updated Javadoc and refactured code
	 * <br>
	 *
	 */
	public class ERiskEvents {
		
		public void OnLoading(Variant[] args) {
			logger.info("ERiskEvent:loading");
		}

		public void OnReady(Variant[] args) {
			logger.info("ERiskEvent:ready");
		}
		
		public void OnQuit(Variant[] args) {
			logger.info("ERiskEvent:quit");
			unsavedChanges = false;
		}
		
		public void OnError(Variant[] args) {
			logger.info("ERiskEvent:error");
		}
		
		public void OnConsultationSaved(Variant[] args) {
//			Variant v = args[0];
//			String xmlString = v.getString().replaceAll("<", "\n<");			
			logger.info("ERiskEvent:consultationSaved");
			unsavedChanges = false;
		}
	}
	
	/**
	 * converts the ucm code to a kmehr compatible format 
	 * @param ucm
	 * @return
	 */
	private String ucm2KMehrID(String ucm) {
		String s = ucm.replaceAll("-", "");
		while (s.length() < 11) {
			s = s += 0;
		}
		return s;
	}
	
	
	/**
	 * checks if erisk is installed on the system.
	 * @return
	 */
	public static boolean checkErisk() {
		try {
			if (! System.getProperty("os.name").toUpperCase().startsWith("WIN"))
				return false;
			EriskInterface ie = new EriskInterface();
			Variant v = ie.findEriskCalculator();		
//			System.out.println(v.getvt());
			return true;
		} catch (ComFailException cfe) {
			logger.info("EriskInterface not found, Erisk Tools will not be available");
			return false;
		} catch (Throwable e) {
			logger.warn("Error creating EriskInterface, Erisk Tools will not be available", e);
			return false;
		}
	}


	/**
	 * starts ekompass
	 * @throws Exception
	 */
	public void startEKompass() throws Exception{
		start(APPLICATION_EKOMPAS);
	}


	/**
	 * starts erisk
	 * @throws Exception
	 */
	public void startERisk()  throws Exception {
		start(APPLICATION_ERISK);
	}

}
