package lu.tudor.santec.gecamed.importexport.gui.export;

import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import javax.swing.border.TitledBorder;

import lu.tudor.santec.gecamed.address.ejb.session.beans.AddressManagerBean;
import lu.tudor.santec.gecamed.address.ejb.session.interfaces.AddressManagerInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
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.utils.xslfo.TransFOmer;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.core.utils.printing.ireport.UtilFormatter;
import lu.tudor.santec.gecamed.importexport.ejb.session.beans.ImportExportBean;
import lu.tudor.santec.gecamed.importexport.ejb.session.interfaces.ImportExportInterface;
import lu.tudor.santec.gecamed.importexport.gui.ImporterClass;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.ejb.session.beans.PatientAdminBean;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.IncidentManager;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.PatientAdminInterface;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.patientexport.PatientExportPanel;
import lu.tudor.santec.gecamed.patient.gui.settings.ConsultationEntryConfig;
import lu.tudor.santec.gecamed.patient.gui.settings.PatientModuleSettings;
import lu.tudor.santec.i18n.Translatrix;

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

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * @author Thorsten Roth thorsten.roth(at)tudor.lu
 *
 * @version
 * <br>$Log: ExportDialog.java,v $
 * <br>Revision 1.48  2013-12-27 18:09:12  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.47  2013-11-15 12:46:31  troth
 * <br>Add label the Luxembourg ID to fo export patient template.
 * <br>
 * <br>Revision 1.46  2013-11-14 15:49:29  troth
 * <br>Add the new consultation entries to the patient export.
 * <br>
 * <br>Revision 1.45  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.44  2013-07-10 09:58:34  troth
 * <br>Add UTF-8 encoding.
 * <br>
 * <br>Revision 1.43  2013-07-09 11:26:44  troth
 * <br>Change libs serializer.jar and xalan.jat form 2.7.0 to 2.7.1.
 * <br>
 * <br>Revision 1.42  2013-07-09 08:33:34  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.41  2013-07-09 08:32:49  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.40  2013-06-26 15:30:16  troth
 * <br>Add function to load xsl-fo template form server.
 * <br>
 * <br>Revision 1.39  2013-06-25 12:19:26  troth
 * <br>New xsl-fop lib.
 * <br>
 * <br>Revision 1.38  2013-06-20 13:29:36  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.37  2013-06-18 11:55:32  troth
 * <br>Add CurrentPhysician as value to the fo-document.
 * <br>
 * <br>Revision 1.36  2013-06-17 16:17:19  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.35  2013-06-13 15:44:25  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.34  2013-06-12 15:37:49  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.33  2013-06-12 12:09:25  troth
 * <br>1. Escape the html named entities like '&nbsp;' in the xml data.
 * <br>2. If export stop because of a parsing error.
 * <br>
 * <br>Revision 1.32  2013-06-12 12:00:28  troth
 * <br>1. Escape the html named entities like '&nbsp;' in the xml data.
 * <br>2. If export stop because of a parsing error.
 * <br>
 * <br>Revision 1.31  2013-06-12 12:00:02  troth
 * <br>1. Escape the html named entities like '&nbsp;' in the xml data.
 * <br>2. If export stop because of a parsing error.
 * <br>
 * <br>Revision 1.30  2013-06-04 14:27:37  troth
 * <br>Decode html tags in xmlData.
 * <br>
 * <br>Revision 1.29  2013-06-04 14:17:31  troth
 * <br>Decode html tags in xmlData.
 * <br>
 * <br>Revision 1.28  2013-05-29 15:00:03  troth
 * <br>Fix translation bug in fo document.
 * <br>
 * <br>Revision 1.27  2013-05-06 14:37:56  troth
 * <br>New version of fo document with translations.
 * <br>
 * <br>Revision 1.26  2013-04-25 13:33:41  troth
 * <br>Select/deselect the all-option-select-checkbox if export options changes.
 * <br>
 * <br>Revision 1.25  2013-04-25 09:49:54  troth
 * <br>1. Checkboxes in exportpanel now deselect if patient is export.
 * <br>2. Add applybox to the 'Export-Done'-Dialog and function to open the directory where the export files are save.
 * <br>
 * <br>Revision 1.24  2013-04-24 13:00:06  troth
 * <br>Bug Fix: Find not patient if start and end date was the same date.
 * <br>
 * <br>Revision 1.23  2013-04-24 07:43:07  troth
 * <br>Check in light version for release.
 * <br>
 * <br>Revision 1.22  2013-04-24 07:20:07  troth
 * <br>Fix Bug: DB-query select patients with acts and invoices when the condition attending or treated physician was select.
 * <br>
 * <br>Revision 1.21  2013-04-23 12:26:41  troth
 * <br>Bug Fix: Export all and not the selected Patients.
 * <br>
 * <br>Revision 1.20  2013-04-22 12:58:26  troth
 * <br>GUI changes.
 * <br>
 * <br>Revision 1.19  2013-04-22 10:02:11  troth
 * <br>Smaller export version for 1.3.02 release.
 * <br>
 * <br>Revision 1.18  2013-04-15 09:44:38  troth
 * <br>Add some translations.
 * <br>Correct the count of patients which are successfully exported / opened.
 * <br>Code clearup.
 * <br>
 * <br>Revision 1.17  2013-04-11 14:42:46  troth
 * <br>Remove and Rename package for the xsl-fo transfer from lu.tudor.santec.gecamed.formeditor.gui.controller.fo to lu.tuodr.santec.gecamed.core.utils.xslfo .
 * <br>
 * <br>Revision 1.16  2013-04-11 14:11:49  troth
 * <br>Add the transfer form export xml data to the formats rtf, pdf and html.
 * <br>Add function to open and save the files in the different formats.
 * <br>
 * <br>Revision 1.15  2013-03-21 15:35:44  troth
 * <br>1. Add a dialog inform the user if patienten search limit is reach.
 * <br>2. Make some GUI changes.
 * <br>
 * <br>Revision 1.14  2013-03-20 10:43:02  troth
 * <br>Fix: Exit export function if file chooser canceled.
 * <br>
 * <br>Revision 1.13  2013-03-11 10:08:14  troth
 * <br>Little GUI changes.
 * <br>
 * <br>Revision 1.12  2013-03-07 17:02:35  troth
 * <br>Add exception handling.
 * <br>
 * <br>Revision 1.11  2013-03-06 17:04:44  troth
 * <br>Change export and info dialog style. Add some translations.
 * <br>
 * <br>Revision 1.10  2013-03-06 10:57:20  kutscheid
 * <br>update the XML exporter to throw exceptions if files could not be found
 * <br>also add some minor updates to the import xsd
 * <br>
 * <br>Revision 1.9  2013-03-05 17:23:49  troth
 * <br>Add new progress bar and export finishing dialog.
 * <br>
 * <br>Revision 1.8  2013-03-05 14:48:24  troth
 * <br>Add ProgressBar in export dialog.
 * <br>
 * <br>Revision 1.7  2013-03-05 13:20:34  troth
 * <br>Export more than one patient.
 * <br>
 * <br>Revision 1.6  2013-02-25 13:52:42  troth
 * <br>Add two data types options 'attached files' and 'letter templates' to patient export dialog.
 * <br>
 * <br>Revision 1.5  2013-02-25 10:33:35  troth
 * <br>add the extra buttons to open and save export in different ways.
 * <br>
 * <br>Revision 1.4  2013-02-20 09:47:43  kutscheid
 * <br>commit changes in the XMLExporter
 * <br>
 * <br>Revision 1.3  2013-02-19 15:08:58  troth
 * <br>Add functionality to export the first patient in list in the syso, by press ok-button only for testing.
 * <br>
 * <br>Revision 1.2  2013-02-19 13:58:03  troth
 * <br>Add the patient export dialog GUI.
 * <br>
 * <br>Revision 1.1  2013-02-12 17:22:12  troth
 * <br>add new function for the MM Export tab to search for patient.
 * <br>
 */
public class ExportDialog extends GECAMedBaseDialogImpl implements ItemListener
{
	/**
	 * 
	 */
	private static final long 		serialVersionUID = 1L;

	private static Logger 			logger	= Logger.getLogger(ExportDialog.class.getName());
		
	// load the Translatrix
	static
	{
		Translatrix.addBundle("lu.tudor.santec.gecamed.importexport.gui.resources.Translatrix");
	}
	
	private static final Map<String, String> HTML_NAMED_ENTITIES;
    static {
        Map<String, String> aMap = new HashMap<String, String>();
        aMap.put("&quot;", "&#34;");
        aMap.put("&amp;", "&#38;");
        aMap.put("&lt;", "&#60;");
        aMap.put("&gt;", "&#62;");
        aMap.put("&nbsp;", "&#160;");
        aMap.put("&iexcl;", "&#161;");
        aMap.put("&cent;", "&#162;");
        aMap.put("&pound;", "&#163;");
        aMap.put("&curren;", "&#164;");
        aMap.put("&yen;", "&#165;");
        aMap.put("&brvbar;", "&#166;");
        aMap.put("&sect;", "&#167;");
        aMap.put("&uml;", "&#168;");
        aMap.put("&copy;", "&#169;");
        aMap.put("&ordf;", "&#170;");
        aMap.put("&laquo;", "&#171;");
        aMap.put("&not;", "&#172;");
        aMap.put("&shy;", "&#173;");
        aMap.put("&reg;", "&#174;");
        aMap.put("&macr;", "&#175;");
        aMap.put("&deg;", "&#176;");
        aMap.put("&plusmn;", "&#177;");
        aMap.put("&sup2;", "&#178;");
        aMap.put("&sup3;", "&#179;");
        aMap.put("&acute;", "&#180;");
        aMap.put("&micro;", "&#181;");
        aMap.put("&para;", "&#182;");
        aMap.put("&middot;", "&#183;");
        aMap.put("&cedil;", "&#184;");
        aMap.put("&sup1;", "&#185;");
        aMap.put("&ordm;", "&#186;");
        aMap.put("&raquo;", "&#187;");
        aMap.put("&frac14;", "&#188;");
        aMap.put("&frac12;", "&#189;");
        aMap.put("&frac34;", "&#190;");
        aMap.put("&iquest;", "&#191;");
        aMap.put("&Agrave;", "&#192;");
        aMap.put("&Aacute;", "&#193;");
        aMap.put("&Acirc;", "&#194;");
        aMap.put("&Atilde;", "&#195;");
        aMap.put("&Auml;", "&#196;");
        aMap.put("&Aring;", "&#197;");
        aMap.put("&AElig;", "&#198;");
        aMap.put("&Ccedil;", "&#199;");
        aMap.put("&Egrave;", "&#200;");
        aMap.put("&Eacute;", "&#201;");
        aMap.put("&Ecirc;", "&#202;");
        aMap.put("&Euml;", "&#203;");
        aMap.put("&Igrave;", "&#204;");
        aMap.put("&Iacute;", "&#205;");
        aMap.put("&Icirc;", "&#206;");
        aMap.put("&Iuml;", "&#207;");
        aMap.put("&ETH;", "&#208;");
        aMap.put("&Ntilde;", "&#209;");
        aMap.put("&Ograve;", "&#210;");
        aMap.put("&Oacute;", "&#211;");
        aMap.put("&Ocirc;", "&#212;");
        aMap.put("&Otilde;", "&#213;");
        aMap.put("&Ouml;", "&#214;");
        aMap.put("&times;", "&#215;");
        aMap.put("&Oslash;", "&#216;");
        aMap.put("&Ugrave;", "&#217;");
        aMap.put("&Uacute;", "&#218;");
        aMap.put("&Ucirc;", "&#219;");
        aMap.put("&Uuml;", "&#220;");
        aMap.put("&Yacute;", "&#221;");
        aMap.put("&THORN;", "&#222;");
        aMap.put("&szlig;", "&#223;");
        aMap.put("&agrave;", "&#224;");
        aMap.put("&aacute;", "&#225;");
        aMap.put("&acirc;", "&#226;");
        aMap.put("&atilde;", "&#227;");
        aMap.put("&auml;", "&#228;");
        aMap.put("&aring;", "&#229;");
        aMap.put("&aelig;", "&#230;");
        aMap.put("&ccedil;", "&#231;");
        aMap.put("&egrave;", "&#232;");
        aMap.put("&eacute;", "&#233;");
        aMap.put("&ecirc;", "&#234;");
        aMap.put("&euml;", "&#235;");
        aMap.put("&igrave;", "&#236;");
        aMap.put("&iacute;", "&#237;");
        aMap.put("&icirc;", "&#238;");
        aMap.put("&iuml;", "&#239;");
        aMap.put("&eth;", "&#240;");
        aMap.put("&ntilde;", "&#241;");
        aMap.put("&ograve;", "&#242;");
        aMap.put("&oacute;", "&#243;");
        aMap.put("&ocirc;", "&#244;");
        aMap.put("&otilde;", "&#245;");
        aMap.put("&ouml;", "&#246;");
        aMap.put("&divide;", "&#247;");
        aMap.put("&oslash;", "&#248;");
        aMap.put("&ugrave;", "&#249;");
        aMap.put("&uacute;", "&#250;");
        aMap.put("&ucirc;", "&#251;");
        aMap.put("&uuml;", "&#252;");
        aMap.put("&yacute;", "&#253;");
        aMap.put("&thorn;", "&#254;");
        aMap.put("&yuml;", "&#255;");
        aMap.put("&Alpha;", "&#913;");
        aMap.put("&alpha;", "&#945;");
        aMap.put("&Beta;", "&#914;");
        aMap.put("&beta;", "&#946;");
        aMap.put("&Gamma;", "&#915;");
        aMap.put("&gamma;", "&#947;");
        aMap.put("&Delta;", "&#916;");
        aMap.put("&delta;", "&#948;");
        aMap.put("&Epsilon;", "&#917;");
        aMap.put("&epsilon;", "&#949;");
        aMap.put("&Zeta;", "&#918;");
        aMap.put("&zeta;", "&#950;");
        aMap.put("&Eta;", "&#919;");
        aMap.put("&eta;", "&#951;");
        aMap.put("&Theta;", "&#920;");
        aMap.put("&theta;", "&#952;");
        aMap.put("&Iota;", "&#921;");
        aMap.put("&iota;", "&#953;");
        aMap.put("&Kappa;", "&#922;");
        aMap.put("&kappa;", "&#954;");
        aMap.put("&Lambda;", "&#923;");
        aMap.put("&lambda;", "&#955;");
        aMap.put("&Mu;", "&#924;");
        aMap.put("&mu;", "&#956;");
        aMap.put("&Nu;", "&#925;");
        aMap.put("&nu;", "&#957;");
        aMap.put("&Xi;", "&#926;");
        aMap.put("&xi;", "&#958;");
        aMap.put("&Omicron;", "&#927;");
        aMap.put("&omicron;", "&#959;");
        aMap.put("&Pi;", "&#928;");
        aMap.put("&pi;", "&#960;");
        aMap.put("&Rho;", "&#929;");
        aMap.put("&rho;", "&#961;");
        aMap.put("&Sigma;", "&#931;");
        aMap.put("&sigmaf;", "&#962;");
        aMap.put("&sigma;", "&#963;");
        aMap.put("&Tau;", "&#932;");
        aMap.put("&tau;", "&#964;");
        aMap.put("&Upsilon;", "&#933;");
        aMap.put("&upsilon;", "&#965;");
        aMap.put("&Phi;", "&#934;");
        aMap.put("&phi;", "&#966;");
        aMap.put("&Chi;", "&#935;");
        aMap.put("&chi;", "&#967;");
        aMap.put("&Psi;", "&#936;");
        aMap.put("&psi;", "&#968;");
        aMap.put("&Omega;", "&#937;");
        aMap.put("&omega;", "&#969;");
        aMap.put("&thetasym;", "&#977;");
        aMap.put("&upsih;", "&#978;");
        aMap.put("&piv;", "&#982;");
        aMap.put("&forall;", "&#8704;");
        aMap.put("&part;", "&#8706;");
        aMap.put("&exist;", "&#8707;");
        aMap.put("&empty;", "&#8709;");
        aMap.put("&nabla;", "&#8711;");
        aMap.put("&isin;", "&#8712;");
        aMap.put("&notin;", "&#8713;");
        aMap.put("&ni;", "&#8715;");
        aMap.put("&prod;", "&#8719;");
        aMap.put("&sum;", "&#8721;");
        aMap.put("&minus;", "&#8722;");
        aMap.put("&lowast;", "&#8727;");
        aMap.put("&radic;", "&#8730;");
        aMap.put("&prop;", "&#8733;");
        aMap.put("&infin;", "&#8734;");
        aMap.put("&ang;", "&#8736;");
        aMap.put("&and;", "&#8743;");
        aMap.put("&or;", "&#8744;");
        aMap.put("&cap;", "&#8745;");
        aMap.put("&cup;", "&#8746;");
        aMap.put("&int;", "&#8747;");
        aMap.put("&there4;", "&#8756;");
        aMap.put("&sim;", "&#8764;");
        aMap.put("&cong;", "&#8773;");
        aMap.put("&asymp;", "&#8776;");
        aMap.put("&ne;", "&#8800;");
        aMap.put("&equiv;", "&#8801;");
        aMap.put("&le;", "&#8804;");
        aMap.put("&ge;", "&#8805;");
        aMap.put("&sub;", "&#8834;");
        aMap.put("&sup;", "&#8835;");
        aMap.put("&nsub;", "&#8836;");
        aMap.put("&sube;", "&#8838;");
        aMap.put("&supe;", "&#8839;");
        aMap.put("&oplus;", "&#8853;");
        aMap.put("&otimes;", "&#8855;");
        aMap.put("&perp;", "&#8869;");
        aMap.put("&sdot;", "&#8901;");
        aMap.put("&loz;", "&#9674;");
        aMap.put("&lceil;", "&#8968;");
        aMap.put("&rceil;", "&#8969;");
        aMap.put("&lfloor;", "&#8970;");
        aMap.put("&rfloor;", "&#8971;");
        aMap.put("&lang;", "&#9001;");
        aMap.put("&rang;", "&#9002;");
        aMap.put("&larr;", "&#8592;");
        aMap.put("&uarr;", "&#8593;");
        aMap.put("&rarr;", "&#8594;");
        aMap.put("&darr;", "&#8595;");
        aMap.put("&harr;", "&#8596;");
        aMap.put("&crarr;", "&#8629;");
        aMap.put("&lArr;", "&#8656;");
        aMap.put("&uArr;", "&#8657;");
        aMap.put("&rArr;", "&#8658;");
        aMap.put("&dArr;", "&#8659;");
        aMap.put("&hArr;", "&#8660;");
        aMap.put("&bull;", "&#8226;");
        aMap.put("&prime;", "&#8242;");
        aMap.put("&Prime;", "&#8243;");
        aMap.put("&oline;", "&#8254;");
        aMap.put("&frasl;", "&#8260;");
        aMap.put("&weierp;", "&#8472;");
        aMap.put("&image;", "&#8465;");
        aMap.put("&real;", "&#8476;");
        aMap.put("&trade;", "&#8482;");
        aMap.put("&euro;", "&#8364;");
        aMap.put("&alefsym;", "&#8501;");
        aMap.put("&spades;", "&#9824;");
        aMap.put("&clubs;", "&#9827;");
        aMap.put("&hearts;", "&#9829;");
        aMap.put("&diams;", "&#9830;");
        aMap.put("&OElig;", "&#338;");
        aMap.put("&oelig;", "&#339;");
        aMap.put("&Scaron;", "&#352;");
        aMap.put("&scaron;", "&#353;");
        aMap.put("&Yuml;", "&#376;");
        aMap.put("&fnof;", "&#402;");
        aMap.put("&ensp;", "&#8194;");
        aMap.put("&emsp;", "&#8195;");
        aMap.put("&thinsp;", "&#8201;");
        aMap.put("&zwnj;", "&#8204;");
        aMap.put("&zwj;", "&#8205;");
        aMap.put("&lrm;", "&#8206;");
        aMap.put("&rlm;", "&#8207;");
        aMap.put("&ndash;", "&#8211;");
        aMap.put("&mdash;", "&#8212;");
        aMap.put("&lsquo;", "&#8216;");
        aMap.put("&rsquo;", "&#8217;");
        aMap.put("&sbquo;", "&#8218;");
        aMap.put("&ldquo;", "&#8220;");
        aMap.put("&rdquo;", "&#8221;");
        aMap.put("&bdquo;", "&#8222;");
        aMap.put("&dagger;", "&#8224;");
        aMap.put("&Dagger;", "&#8225;");
        aMap.put("&hellip;", "&#8230;");
        aMap.put("&permil;", "&#8240;");
        aMap.put("&lsaquo;", "&#8249;");
        aMap.put("&rsaquo;", "&#8250;");
        aMap.put("&circ;", "&#710;");
        aMap.put("&tilde;", "&#732;");
        
        HTML_NAMED_ENTITIES = Collections.unmodifiableMap(aMap);
    }
	
	
	private static final String 	OUTPUT_FORMAT_RTF = "rtf";
	
	private static final String 	OUTPUT_FORMAT_PDF = "pdf";
	
	private static final String 	OUTPUT_FORMAT_XML = "xml";

	private static final String 	OUTPUT_FORMAT_HTML = "html";

	// file separator
	private static final String 	FILE_SEPARATOR = System.getProperty("file.separator");
	
	private ImportExportInterface 	importer;
	
	private ArrayList<Integer> 		patientsSelected;
	
	private CellConstraints 		cc;
	
	private JRadioButton 			allPatient;

	private JRadioButton 			eachPatient;
	
	private JCheckBox 				masterData;

	private JCheckBox 				consultations;

	private JCheckBox 				prescriptions;

	private JCheckBox 				activeProblems;

	private JCheckBox 				antecedents;

	private JCheckBox 				attachedFiles;
	
	private JCheckBox 				extendedMasterData;

	private JCheckBox 				invoices;

	private JCheckBox 				formEntries;

	private JCheckBox 				allergies;

	private JCheckBox 				chronicalTreatments;

	private JCheckBox 				letterTemplates;
	
	private JCheckBox				allOptions;
	
	private JRadioButton 			rtf;

	private JRadioButton 			pdf;

	private JRadioButton 			html;
	
	private JRadioButton			xml;
	
	private JButton 				openButton;

	private JButton 				saveButton;

//	private JButton 				xmlExportButton;

	private int 					patientDataExportoption;
	
	private File 					directory;
	
	private String					outputFormat;
	
	private File					startDirectory;

	private boolean 				stopExport;
	
	private PatientExportPanel			parentPanel;
	

	public ExportDialog(PatientExportPanel parentPanel, ArrayList<Integer> patients)
	{
		super(MainFrame.getInstance(), Translatrix.getTranslationString("exportPatientDialog.title"), CLOSE_BUTTON_MODE);
		setModalityType(ModalityType.DOCUMENT_MODAL);
		buildMainPanel();
		buildExtraButtons();
		// init selection check boxes and radio buttons
		masterData.setEnabled(false);
		allPatient.setSelected(true);
		pack();
		this.patientsSelected = new ArrayList<Integer>(patients);
		
		stopExport = false;
		this.parentPanel = parentPanel;
		this.importer = (ImportExportInterface) ManagerFactory.getRemote(ImportExportBean.class);
	}

	
	private void buildMainPanel()
	{
		cc = new CellConstraints();
		
		// execution panel
		JPanel executionPanel = new JPanel(new FormLayout("3px, pref, 3px, pref, 3px", "3px, pref, 3px"));
		executionPanel.setBorder(new TitledBorder(Translatrix.getTranslationString("exportPatientDialog.execution")));
		allPatient = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.execution.allPatient"));
		allPatient.addItemListener(this);
		eachPatient = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.execution.eachPatient"));
		eachPatient.addItemListener(this);
		ButtonGroup executionGroup = new ButtonGroup();
		executionGroup.add(allPatient);
		executionGroup.add(eachPatient);
		executionPanel.add(allPatient, cc.xy(2,2));
		executionPanel.add(eachPatient , cc.xy(4,2));
		executionPanel.setOpaque(false);
		
		// datatypes panel
		JPanel datatypesPanel = new JPanel(new FormLayout("3px, pref, 3px, pref, 3px", "3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px, 3px, pref, 3px"));
		datatypesPanel.setBorder(new TitledBorder(Translatrix.getTranslationString("exportPatientDialog.datatypes")));
		masterData = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.masterData"));
		masterData.setOpaque(false);
		masterData.addItemListener(this);
		datatypesPanel.add(masterData, cc.xy(2, 2));
		consultations = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.consultations"));
		consultations.addItemListener(this);
		consultations.setOpaque(false);
		datatypesPanel.add(consultations, cc.xy(2, 4));
		prescriptions = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.prescriptions"));
		prescriptions.addItemListener(this);
		prescriptions.setOpaque(false);
		datatypesPanel.add(prescriptions, cc.xy(2, 6));
		activeProblems = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.activeProblems"));
		activeProblems.addItemListener(this);
		activeProblems.setOpaque(false);
		datatypesPanel.add(activeProblems, cc.xy(2, 8));
		antecedents = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.antecedents"));
		antecedents.addItemListener(this);
		antecedents.setOpaque(false);
		datatypesPanel.add(antecedents, cc.xy(2, 10));
		attachedFiles = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.attachedFiles"));
		attachedFiles.addItemListener(this);
		attachedFiles.setOpaque(false);
		datatypesPanel.add(attachedFiles, cc.xy(2, 12));
		extendedMasterData = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.extendedMasterData"));
		extendedMasterData.addItemListener(this);
//		extendedMasterData.setEnabled(false);
		extendedMasterData.setOpaque(false);
		datatypesPanel.add(extendedMasterData, cc.xy(4, 2));
		invoices = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.invoices"));
		invoices.addItemListener(this);
		invoices.setOpaque(false);
		datatypesPanel.add(invoices, cc.xy(4, 4));
		formEntries = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.formEntries"));
		formEntries.addItemListener(this);
		formEntries.setOpaque(false);
		datatypesPanel.add(formEntries, cc.xy(4, 6));
		allergies = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.allergies"));
		allergies.addItemListener(this);
		allergies.setOpaque(false);
		datatypesPanel.add(allergies, cc.xy(4, 8));
		chronicalTreatments = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.chronicalTreatments"));
		chronicalTreatments.addItemListener(this);
		chronicalTreatments.setOpaque(false);
		datatypesPanel.add(chronicalTreatments, cc.xy(4, 10));
		letterTemplates = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.letterTemplates"));
		letterTemplates.addItemListener(this);
		letterTemplates.setOpaque(false);
		datatypesPanel.add(letterTemplates, cc.xy(4, 12));
		datatypesPanel.add(new JSeparator(), cc.xyw(2, 14, 3));
		allOptions = new JCheckBox(Translatrix.getTranslationString("exportPatientDialog.datatypes.allOptions"));
		allOptions.addItemListener(this);
		allOptions.setOpaque(false);
		datatypesPanel.add(allOptions, cc.xyw(2, 16, 3));
		datatypesPanel.setOpaque(false);
		allOptions.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) 
			{
				if(allOptions.isSelected())
				{
					//masterData.setSelected(true);
					consultations.setSelected(true);
					prescriptions.setSelected(true);
					activeProblems.setSelected(true);
					antecedents.setSelected(true);
					attachedFiles.setSelected(true);
					extendedMasterData.setSelected(true);
					if(invoices.isEnabled()) invoices.setSelected(true);
					formEntries.setSelected(true);
					allergies.setSelected(true);
					chronicalTreatments.setSelected(true);
					letterTemplates.setSelected(true);
				}else{
					//masterData.setSelected(false);
					consultations.setSelected(false);
					prescriptions.setSelected(false);
					activeProblems.setSelected(false);
					antecedents.setSelected(false);
					attachedFiles.setSelected(false);
					extendedMasterData.setSelected(false);
					if(invoices.isEnabled()) invoices.setSelected(false);
					formEntries.setSelected(false);
					allergies.setSelected(false);
					chronicalTreatments.setSelected(false);
					letterTemplates.setSelected(false);
				}
			}
		});
		
		// format panel
		JPanel formatsPanel = new JPanel(new FormLayout("3px, pref, 3px", "3px, pref, 3px, pref, 3px, pref, 3px, pref, 3px"));
		formatsPanel.setBorder(new TitledBorder(Translatrix.getTranslationString("exportPatientDialog.formats")));
		rtf = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.formats.rtf"));
		rtf.addItemListener(this);
		rtf.setOpaque(false);
		pdf = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.formats.pdf"));
		pdf.addItemListener(this);
		pdf.setOpaque(false);
		html = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.formats.html"));
		html.addItemListener(this);
		html.setOpaque(false);
		xml = new JRadioButton(Translatrix.getTranslationString("exportPatientDialog.formats.xml"));
		xml.addItemListener(this);
		xml.setOpaque(false);
		ButtonGroup formatsGroup = new ButtonGroup();
		formatsGroup.add(rtf);
		formatsGroup.add(pdf);
		formatsGroup.add(html);
		formatsGroup.add(xml);
		formatsPanel.add(rtf, cc.xy(2,2));
		formatsPanel.add(pdf, cc.xy(2,4));
		formatsPanel.add(html , cc.xy(2,6));
		formatsPanel.add(xml , cc.xy(2,8));
		formatsPanel.setOpaque(false);
		// init main panel
		mainPanel.setLayout(new BorderLayout());
		//mainPanel.add(executionPanel, BorderLayout.NORTH); // TODO not needed now
		mainPanel.add(datatypesPanel, BorderLayout.CENTER);
		mainPanel.add(formatsPanel, BorderLayout.SOUTH); 
		
	}
	

	private void buildExtraButtons()
	{
		openButton = new JButton(Translatrix.getTranslationString("exportPatientDialog.buttons.open"));
		openButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				openExport();
			}
		});
		addButton(openButton);
		
		saveButton = new JButton(Translatrix.getTranslationString("exportPatientDialog.buttons.save"));
		saveButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				saveExport();
			}
		});
		addButton(saveButton);
		
//		xmlExportButton = new JButton(Translatrix.getTranslationString("exportPatientDialog.buttons.xmlExport"));
//		xmlExportButton.addActionListener(new ActionListener()
//		{
//
//			public void actionPerformed(ActionEvent e)
//			{
//				xmlExport();
//			}
//		});
//		addButton(xmlExportButton);
		showExtraButtons();
	}
	
//	private void xmlExport()
//	{
//		patientDataExportoption = 0;
//		directory = null;
//		xmlExportButton.setEnabled(false);
//		okButton.setEnabled(false);
//		cancelButton.setEnabled(false);
//		
//		// execution - read execution mode
//		if(allPatient.isSelected())
//		{
//
//		} else if(eachPatient.isSelected())
//		{
//
//		}
//		
//		// datatypes - read options of patient data export and save as bitmask
//		getOptions();
//		
//		// formats - read the output format for the patient export data
//		getOutputFormat();
//		
//		// open file chooser to select output directory
//		JFileChooser fileChooser = new JFileChooser();
//		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//		
//		while(directory == null || !directory.isDirectory())
//		{
//			int result = fileChooser.showOpenDialog(ExportDialog.this);
//			
//			if(result == JFileChooser.APPROVE_OPTION)
//			{
//				directory = fileChooser.getSelectedFile();
//				// Warring no directory choose
//				if(!directory.isDirectory())
//				{
//					JPanel jp =  new JPanel();
//					jp.add(new JLabel(Translatrix.getTranslationString("exportPatientDialog.exportInfo.noExportDirectory")));
//					GECAMedBaseDialogImpl su = new GECAMedBaseDialogImpl(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), OK_BUTTON_MODE, jp);
//					su.setSize(300, 150);
//					su.showCenteredDialog();
//				}
//			}else{
//				// user cancel file chooser stop the export
//				xmlExportButton.setEnabled(true);
//				return;
//			} 
//		}
//		
//		// start export into output directory
//		Thread thread = new Thread(new Runnable() {
//			public void run()
//			{
//				boolean forceExport = false;
//				int patientCount = patients.size();
//				final JDialog progressBarDialog = new JDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.progressDialog.title"), true);
//			    JProgressBar progressBar = new JProgressBar(0, patientCount);
//			    progressBar.setStringPainted(true);
//			    progressBarDialog.add(BorderLayout.CENTER, progressBar);
//			    //progressBarDialog.add(BorderLayout.NORTH, new JLabel("Progress..."));
//			    progressBarDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
//			    //progressBarDialog.setUndecorated(true);
//			    progressBarDialog.setSize(300, 75);
//			    progressBarDialog.setLocationRelativeTo(ExportDialog.this);
//				
//				Thread t = new Thread(new Runnable() {
//				      public void run() {
//				    	  progressBarDialog.setVisible(true);
//				      }
//				    });
//				    t.start();
//				    Boolean applyToAll = false;
//				for (int i = 0; i < patients.size(); i++)
//				{
//					PatientAdminInterface manager = (PatientAdminInterface) ManagerFactory.getRemote(PatientAdminBean.class);
//					Patient gecamedPatient = null;
//					progressBar.setValue(i);
//					progressBar.setString(i + " " + Translatrix.getTranslationString("exportPatientDialog.progressDialog.barString") + " " + patientCount);
//
//					ExportDialog.this.setModalityType(ModalityType.APPLICATION_MODAL);
//
//					try {
//						gecamedPatient = manager.getPatient(patients.get(i).getId());
//					} catch (Exception e1) {
//						logger.log(Level.WARN, "Can't load Patient from Database. \n", e1);
//					}
//
//					
//					File xmlExportFile = null;
//					try {
//						if(applyToAll) forceExport = true;
//						xmlExportFile = XMLExporter.generateXMLForPatient(gecamedPatient, patientDataExportoption, directory, forceExport);
//						if(forceExport) forceExport = false;
//					} catch (PatientFileNotFoundException e) {
//						Set<String>  fileNames = e.getAllFileNames();
//						StringBuffer errorString = new StringBuffer(); 
//						errorString.append("<html>");
//						for (Iterator<String> iterator = fileNames.iterator(); iterator
//								.hasNext();) {
//							String fileName = (String) iterator.next();
//							errorString.append(e.getErrorForFile(fileName));
//							errorString.append(" | ");
//							errorString.append(fileName);
//							errorString.append("<br>");
//							logger.log(Level.WARN, e.getErrorForFile(fileName) + " | File: " + fileName + "\n", e);
//						}
//						
//						if(errorString.toString() != "<html>")
//						{
//							errorString.append("<br>");
//							errorString.append(Translatrix.getTranslationString("exportPatientDialog.exportInfo.fileNotFound"));
//							errorString.append("</html>");
//							ButtonOption result = GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), errorString.toString(), GECAMedBaseDialogImpl.YES_NO_BUTTON_MODE, null, true);
//							applyToAll = result.applyToAll;
//							if(result.buttonOption == GECAMedBaseDialogImpl.YES_OPTION)
//							{	
//								forceExport = true;
//								i--;
//							}
//						}
//						
//					} catch (IllegalArgumentException e) {
//						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailedNoPhysician"), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
//						logger.log(Level.WARN, "Can't export patient. The physician for an incident could not be found and the patient did not have a main physician! Patient: " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
//					} catch (Exception e) {
//						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailed"), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
//						logger.log(Level.WARN, "Can't export patient " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
//					}
//				}
//				 
//				xmlExportButton.setEnabled(true);
//				okButton.setEnabled(true);
//				cancelButton.setEnabled(true);
//				progressBarDialog.setVisible(false);
//				String[] para = {"" + patients.size()};
//				
//				GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportDone", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
//			}
//		});
//		thread.start();					
//	
//	}
	
	
	public void showExtraButtons()
	{
		if(
				// check execution
				(allPatient.isSelected() || eachPatient.isSelected())
				&&
				// check datatypes
				(masterData.isSelected() || consultations.isSelected() || prescriptions.isSelected() || activeProblems.isSelected() || antecedents.isSelected()
						|| extendedMasterData.isSelected() || invoices.isSelected() || formEntries.isSelected() || allergies.isSelected() || chronicalTreatments.isSelected()
						|| attachedFiles.isSelected() || letterTemplates.isSelected())
		)
		{
			// check formats
			if (rtf.isSelected() || pdf.isSelected() || html.isSelected() || xml.isSelected())
			{
				openButton.setEnabled(true);
				saveButton.setEnabled(true);
			} else {
				openButton.setEnabled(false);
				saveButton.setEnabled(false);
			}
		}
	}
	

	/* ItemListener for the check boxes and radio buttons of patient export data
	 * (non-Javadoc)
	 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
	 */
	public void itemStateChanged(ItemEvent e)
	{
		// check if Buttons enabled
		showExtraButtons();
		
		// check if action for  option action
		if(e.getItemSelectable() instanceof JCheckBox)
		{
			
			JCheckBox source = (JCheckBox)e.getItemSelectable();
			// Select/deselect the all-option-select-checkbox
			if(source != allOptions)
			{
				if(source.isSelected())
					setOptions(getOptions());
				else
					allOptions.setSelected(false);
			}
			// check if radio button enabled
//			if(source == masterData)
//			{
//				if(masterData.isSelected())
//					extendedMasterData.setEnabled(true);
//				else
//				{
//					extendedMasterData.setEnabled(false);
//					extendedMasterData.setSelected(false);
//				}
//			}
			
		}
		
		if(e.getItemSelectable() instanceof JRadioButton)
		{
			JRadioButton source = (JRadioButton)e.getItemSelectable();
			if(source == xml)
			{
				// enable the invoices JCheckBox
				invoices.setEnabled(true);
			}
			if(source == rtf || source == pdf || source == html)
			{
				// disenable the invoices JCheckBox
				invoices.setSelected(false);
				invoices.setEnabled(false);
			}
		}
	}

	public int getOptions() 
	{
		patientDataExportoption = 0;
		// datatypes - read options of patient data export and save as bitmask
		if(masterData.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_MASTER_DATA;
		} 
		if(consultations.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_CONSULTATIONS;
		} 
		if(prescriptions.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_PRESCRIPTIONS;
		} 
		if(activeProblems.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ACTIVE_PROBLEMS;
		} 
		if(antecedents.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ANTECEDENTS;
		} 
		if(extendedMasterData.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_EXTENDED_MASTER_DATA;
		} 
		if(invoices.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_INVOICES;
		} 
		if(formEntries.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_FORMS;
		} 
		if(allergies.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ALLERGIES;
		} 
		if(chronicalTreatments.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_CHRONICAL_TREATMENTS;
		}
		if(attachedFiles.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_FILE;
		}
		if(letterTemplates.isSelected())
		{
			patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_LETTERS;
		}
		return patientDataExportoption;
	}

	public void setOptions(int options)
	{
		int countOptions = 0, maxOptions = 12;
		
		if(options == 0)
		{
			setDefaultOptions();
			return;
		}
		// datatypes - set options of patient data export
		if((options & XMLExporter.INCLUDE_MASTER_DATA) > 0)
		{
			masterData.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_CONSULTATIONS) > 0)
		{
			consultations.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_PRESCRIPTIONS) > 0)
		{
			prescriptions.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_ACTIVE_PROBLEMS) > 0)
		{
			activeProblems.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_ANTECEDENTS) > 0)
		{
			antecedents.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_EXTENDED_MASTER_DATA) > 0)
		{
			extendedMasterData.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_INVOICES) > 0)
		{
			invoices.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_FORMS) > 0)
		{
			formEntries.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_ALLERGIES) > 0)
		{
			allergies.setSelected(true);
			countOptions++;
		} 
		if((options & XMLExporter.INCLUDE_CHRONICAL_TREATMENTS) > 0)
		{
			chronicalTreatments.setSelected(true);
			countOptions++;
		}
		if((options & XMLExporter.INCLUDE_FILE) > 0)
		{
			attachedFiles.setSelected(true);
			countOptions++;
		}
		if((options & XMLExporter.INCLUDE_LETTERS) > 0)
		{
			letterTemplates.setSelected(true);
			countOptions++;
		}
		if(countOptions == maxOptions) allOptions.setSelected(true);
		else allOptions.setSelected(false);
	}
	
	public void setDefaultOptions()
	{
		masterData.setSelected(true);
		activeProblems.setSelected(true);
		antecedents.setSelected(true);
		allergies.setSelected(true);
	}
	
	private void getOutputFormat()
	{
		if(rtf.isSelected())
		{
			outputFormat = OUTPUT_FORMAT_RTF;
		} else if(pdf.isSelected())
		{
			outputFormat = OUTPUT_FORMAT_PDF;
		} else if(html.isSelected())
		{
			outputFormat = OUTPUT_FORMAT_HTML;
		} else if(xml.isSelected())
		{
			outputFormat = OUTPUT_FORMAT_XML;
		}
	}
	
	/**
	 * Create the xml export file, transfer it in selected format (rtf, pdf, html), save the file in temp folder and open the
	 */
	private void openExport()
	{
		patientDataExportoption = 0;
		directory = null;
		openButton.setEnabled(false);
		saveButton.setEnabled(false);
		
		// execution - read execution mode
		if(allPatient.isSelected())
		{
			// TODO not needed now
		} else if(eachPatient.isSelected())
		{
			// TODO not needed now
		}
		
		// datatypes - read options of patient data export and save as bitmask
		getOptions();
		
		// formats - read the output format for the patient export data
		getOutputFormat();
		
		// start export into output directory
		Thread thread = new Thread(new Runnable() {
			public void run()
			{
				boolean forceExport = false;
				int patientCountToExport = patientsSelected.size();
				int patientCount = 0;
				final JDialog progressBarDialog = new JDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.progressDialog.title"), true);
			    progressBarDialog.getContentPane().setBackground(GECAMedColors.c_GECAMedBackground);
				JProgressBar progressBar = new JProgressBar(0, patientCountToExport);
			    JButton cancelProgressBarDialog = new JButton(Translatrix.getTranslationString("core.cancel"), GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL));
			    cancelProgressBarDialog.addActionListener(new ActionListener()
			    {	
					public void actionPerformed(ActionEvent e)
					{
						stopExport = true;
					}
				});
			    
			    progressBar.setStringPainted(true);
			    JPanel buttonPanel = new JPanel(new FlowLayout());
			    buttonPanel.add(cancelProgressBarDialog);
			    buttonPanel.setOpaque(false);
			    progressBarDialog.add(BorderLayout.CENTER, progressBar);
			    progressBarDialog.add(BorderLayout.SOUTH, buttonPanel);
			    progressBarDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
			    progressBarDialog.setSize(300, 120);
			    progressBarDialog.setLocationRelativeTo(ExportDialog.this);
			    
			    // set user directory
				directory = new File(System.getProperty("java.io.tmpdir"));
				File directoryXMLFiles = new File(System.getProperty("java.io.tmpdir") + FILE_SEPARATOR + "gecamed" + Long.toString(System.nanoTime()) + FILE_SEPARATOR);
				directoryXMLFiles.deleteOnExit();
				
			    // create directory if not exists
			    if(!directoryXMLFiles.exists()) directoryXMLFiles.mkdir();
				// run the open file process
			    Thread t = new Thread(new Runnable()
			    {
			    	public void run()
			    	{
			    		progressBarDialog.setVisible(true);
			    	}
			    });
				
			    t.start();
				Boolean applyToAll = false;
				Boolean applyToAllOpenFile = false;
				PatientAdminInterface manager = (PatientAdminInterface) ManagerFactory.getRemote(PatientAdminBean.class);
				Patient gecamedPatient = null;
				String patientIdentifier = "";
				
				for (int i = 0; i < patientCountToExport; i++)
				{
					if(stopExport) break;
					gecamedPatient = null;
					progressBar.setValue(i);
					progressBar.setString(i + " " + Translatrix.getTranslationString("exportPatientDialog.progressDialog.barString") + " " + patientCountToExport);

					ExportDialog.this.setModalityType(ModalityType.APPLICATION_MODAL);
					
					try {
						gecamedPatient = manager.getPatient(patientsSelected.get(i));
						patientIdentifier = gecamedPatient.getSocialSecurityNumber() + " " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName();
					} catch (Exception e1) {
						logger.log(Level.WARN, "Can't load Patient from Database. \n", e1);
					}

					File xmlExportFile = null;
					try {
						if(applyToAll) forceExport = true;
						xmlExportFile = XMLExporter.generateXMLForPatient(gecamedPatient, patientDataExportoption, directoryXMLFiles, forceExport);
						xmlExportFile.deleteOnExit();
						if(forceExport) forceExport = false;
					} catch (PatientFileNotFoundException e) {
						Set<String>  fileNames = e.getAllFileNames();
						StringBuffer errorString = new StringBuffer(); 
						errorString.append("<html>");
						for (Iterator<String> iterator = fileNames.iterator(); iterator
								.hasNext();) {
							String fileName = (String) iterator.next();
							errorString.append(e.getErrorForFile(fileName));
							errorString.append(" | ");
							errorString.append(fileName);
							errorString.append("<br>");
							logger.log(Level.WARN, e.getErrorForFile(fileName) + " | File: " + fileName + "\n", e);
						}
						
						if(errorString.toString() != "<html>")
						{
							errorString.append("<br>");
							String[] para = {patientIdentifier};
							errorString.append(Translatrix.getTranslationString("exportPatientDialog.exportInfo.fileNotFound", para));
							errorString.append("</html>");
							ButtonOption result = GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), errorString.toString(), GECAMedBaseDialogImpl.YES_NO_BUTTON_MODE, null, true);
							applyToAll = result.applyToAll;
							if(result.buttonOption == GECAMedBaseDialogImpl.YES_OPTION)
							{	
								forceExport = true;
								i--;
							}else
								xmlExportFile = null;
						}
						
					} catch (IllegalArgumentException e) {
						String[] para = {patientIdentifier};
						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailedNoPhysician", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
						logger.log(Level.WARN, "Can't export patient. The physician for an incident could not be found and the patient did not have a main physician! Patient: " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
					} catch (Exception e) {
						String[] para = {patientIdentifier};
						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailed", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
						logger.log(Level.WARN, "Can't export patient " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
					}
					
					if(xmlExportFile != null)
					{
						if(!xml.isSelected())
						{
							// Transfer xml data and xsl template to file format
							FileInputStream xmlData = null;
							try {
								xmlData = new FileInputStream(xmlExportFile);
							} catch (FileNotFoundException e) {
								logger.log(Level.WARN, "Can't create inputstream from export file: " + xmlExportFile.getName() + "\n");
								break;
							}
							
							String strXmlData = clearXMLDataFromHtml(xmlData);
							
							if(strXmlData == null)
							{
								break;
							}
							
							importer = (ImportExportInterface) ManagerFactory.getRemote(ImportExportBean.class);
							InputStream xslTemplate = null;
							String foTemplateName = "foExportPatient.xsl";
							byte[] filebytes = null;
							
							try {
								// Get the bytes of the template
								filebytes = importer.getTemplateBinary(foTemplateName);
								xslTemplate = new BufferedInputStream(new ByteArrayInputStream(filebytes)) ;
							} catch (Exception e) {
							    logger.log(Level.WARN, "Error loading template File " + foTemplateName + ".\n" + e.getMessage());  
							}
							
							try
							{
								if(xslTemplate == null)
									xslTemplate = new BufferedInputStream(ImporterClass.class.getResourceAsStream("resources/foExportPatient.xsl"));
							} catch (Exception e){
								logger.log(Level.WARN, "Error get internal template File " + foTemplateName + ".\n" + e.getMessage());
								break;
							}
							
							String strXslTemplate = addTranslationAndVariablesToXSLTemplate(xslTemplate);
							
							// get transformed byte array in output format
							TransFOmer transFOmer = TransFOmer.getInstance();
							
							byte[] byteArray = transFOmer.transFO(strXmlData, strXslTemplate, outputFormat);
							
							if(byteArray == null)
							{
								break;
							}
							
							// convert array of bytes into file
							String fileName = xmlExportFile.getName().replace(".xml", "");
							try {
								// save file
								FileOutputStream fileOuputStream = new FileOutputStream(directory + FILE_SEPARATOR + fileName + "." + outputFormat); 
								fileOuputStream.write(byteArray);
								fileOuputStream.close();								
							} catch (IOException e) {
								logger.log(Level.WARN, "Can't create export file: " + directory + FILE_SEPARATOR + fileName + "." + outputFormat + "\n");
							}
							// open file with default application
							File file = new File(directory + FILE_SEPARATOR + fileName + "." + outputFormat);
							file.deleteOnExit();
							Desktop desktop = Desktop.getDesktop(); 
							try {
								desktop.open(file);
								patientCount++;
								if (parentPanel != null) {
									parentPanel.removeSelectPatient(patientsSelected.get(i));									
								}
							} catch (IOException e) {
								logger.log(Level.WARN, "Can't open export file: " + directory + FILE_SEPARATOR + fileName + "." + outputFormat + "\n");
							}
							// delete xml file
							if(xmlExportFile.exists()) xmlExportFile.delete();
							// close file handels
							if (xmlData != null) {
								try {
									xmlData.close();
								} catch (IOException e) {
									Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xmlData input stream.", e);
								}
							}
							if (xslTemplate != null) {
								try {
									xslTemplate.close();
								} catch (IOException e) {
									Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xslTemplate input stream.", e);
								}
							}
						}else{
							Desktop desktop = Desktop.getDesktop(); 
							try {
								desktop.open(xmlExportFile);
								patientCount++;
								if (parentPanel != null) {
									parentPanel.removeSelectPatient(patientsSelected.get(i));
								}
							} catch (IOException e) {
								logger.log(Level.WARN, "Can't open export file: " + directory + FILE_SEPARATOR + xmlExportFile.getName() + "." + outputFormat + "\n", e);
							}
						}
						
						// open next patient
						if(!applyToAllOpenFile && patientCountToExport > 1)
						{
							int c = i + 1;
							String[] para = {"" + c,"" + patientCountToExport};
							ButtonOption result = GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.openExports", para), GECAMedBaseDialogImpl.YES_NO_BUTTON_MODE, null, true);
							applyToAllOpenFile = result.applyToAll;
							if(result.buttonOption == GECAMedBaseDialogImpl.NO_OPTION)
							{	
								break;
							}
						}
						
					}
				}
				
				openButton.setEnabled(true);
				saveButton.setEnabled(true);
				progressBarDialog.setVisible(false);
				String[] para = {"" + patientCount};
				
				GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.openDone", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
				stopExport = false;
				if (parentPanel != null) {
					patientsSelected = new ArrayList<Integer>(parentPanel.getSelectedPatients());
					if(patientsSelected.size() <= 0) 
						setVisible(false);					
				} else {
					setVisible(false);	
				}
			}
		});
		thread.start();
	}
	
	private void saveExport()
	{
		patientDataExportoption = 0;
		directory = null;
		openButton.setEnabled(false);
		saveButton.setEnabled(false);
		
		// execution - read execution mode
		if(allPatient.isSelected())
		{
			// TODO not needed now
		} else if(eachPatient.isSelected())
		{
			// TODO not needed now
		}
		
		// datatypes - read options of patient data export and save as bitmask
		getOptions();
		
		// formats - read the output format for the patient export data
		getOutputFormat();
		
		// open file chooser to select output directory
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		if(startDirectory != null) fileChooser.setCurrentDirectory(startDirectory);
		while(directory == null || !directory.isDirectory())
		{
			int result = fileChooser.showOpenDialog(ExportDialog.this);
			
			if(result == JFileChooser.APPROVE_OPTION)
			{
				directory = fileChooser.getSelectedFile();
				startDirectory = directory;
				// Warring no directory choose
				if(!directory.isDirectory())
				{
					JPanel jp =  new JPanel();
					jp.add(new JLabel(Translatrix.getTranslationString("exportPatientDialog.exportInfo.noExportDirectory")));
					GECAMedBaseDialogImpl su = new GECAMedBaseDialogImpl(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), OK_BUTTON_MODE, jp);
					su.setSize(300, 150);
					su.showCenteredDialog();
				}
			}else{
				// user cancel file chooser stop the export
				saveButton.setEnabled(true);
				return;
			} 
		}
		
		// start export into output directory
		Thread thread = new Thread(new Runnable() {
			public void run()
			{
				boolean forceExport = false;
				int patientCountToExport = patientsSelected.size();
				int patientCount = 0;
				
				final JDialog progressBarDialog = new JDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.progressDialog.title"), true);
			    progressBarDialog.getContentPane().setBackground(GECAMedColors.c_GECAMedBackground);
				JProgressBar progressBar = new JProgressBar(0, patientCountToExport);
			    JButton cancelProgressBarDialog = new JButton(Translatrix.getTranslationString("core.cancel"), GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL));
			    cancelProgressBarDialog.addActionListener(new ActionListener()
			    {	
					public void actionPerformed(ActionEvent e)
					{
						stopExport = true;
					}
				});
			    
			    progressBar.setStringPainted(true);
			    JPanel buttonPanel = new JPanel(new FlowLayout());
			    buttonPanel.add(cancelProgressBarDialog);
			    buttonPanel.setOpaque(false);
			    progressBarDialog.add(BorderLayout.CENTER, progressBar);
			    progressBarDialog.add(BorderLayout.SOUTH, buttonPanel);
			    progressBarDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
			    progressBarDialog.setSize(300, 120);
			    progressBarDialog.setLocationRelativeTo(ExportDialog.this);
				
				Thread t = new Thread(new Runnable()
				{
					public void run()
					{
						progressBarDialog.setVisible(true);
					}
				});
				
				t.start();
				Boolean applyToAll = false;
				PatientAdminInterface manager = (PatientAdminInterface) ManagerFactory.getRemote(PatientAdminBean.class);
				Patient gecamedPatient = null;
				String patientIdentifier = "";
				
				for (int i = 0; i < patientCountToExport; i++)
				{
					if(stopExport) break;
					gecamedPatient = null;
				    progressBar.setValue(i);
				    progressBar.setString(i + " " + Translatrix.getTranslationString("exportPatientDialog.progressDialog.barString") + " " + patientCountToExport);

				    ExportDialog.this.setModalityType(ModalityType.APPLICATION_MODAL);
				    
					try {
						gecamedPatient = manager.getPatient(patientsSelected.get(i));
						patientIdentifier = gecamedPatient.getSocialSecurityNumber() + " " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName();
					} catch (Exception e1) {
						logger.log(Level.WARN, "Can't load Patient from Database. \n", e1);
					}

					
					File xmlExportFile = null;
					try {
						if(applyToAll) forceExport = true;
						xmlExportFile = XMLExporter.generateXMLForPatient(gecamedPatient, patientDataExportoption, directory, forceExport);
						if(forceExport) forceExport = false;
					} catch (PatientFileNotFoundException e) {
						Set<String>  fileNames = e.getAllFileNames();
						StringBuffer errorString = new StringBuffer(); 
						errorString.append("<html>");
						for (Iterator<String> iterator = fileNames.iterator(); iterator
								.hasNext();) {
							String fileName = (String) iterator.next();
							errorString.append(e.getErrorForFile(fileName));
							errorString.append(" | ");
							errorString.append(fileName);
							errorString.append("<br>");
							logger.log(Level.WARN, e.getErrorForFile(fileName) + " | File: " + fileName + "\n", e);
						}
						
						if(errorString.toString() != "<html>")
						{
							errorString.append("<br>");
							String[] para = {patientIdentifier};
							errorString.append(Translatrix.getTranslationString("exportPatientDialog.exportInfo.fileNotFound", para));
							errorString.append("</html>");
							ButtonOption result = GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), errorString.toString(), GECAMedBaseDialogImpl.YES_NO_BUTTON_MODE, null, true);
							applyToAll = result.applyToAll;
							if(result.buttonOption == GECAMedBaseDialogImpl.YES_OPTION)
							{	
								forceExport = true;
								i--;
							}else
								xmlExportFile = null;
						}
						
					} catch (IllegalArgumentException e) {
						String[] para = {patientIdentifier};
						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailedNoPhysician", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
						logger.log(Level.WARN, "Can't export patient. The physician for an incident could not be found and the patient did not have a main physician! Patient: " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
					} catch (Exception e) {
						String[] para = {patientIdentifier};
						GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportFailed", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE);
						logger.log(Level.WARN, "Can't export patient " + gecamedPatient.getFirstName() + " " + gecamedPatient.getSurName() + " " + gecamedPatient.getSocialSecurityNumber() + "\n", e);
					}
					
					if(xmlExportFile != null)
					{
						if(!xml.isSelected())
						{
							// Transfer xml data and xsl template to file format
							FileInputStream xmlData = null;
							try {
								xmlData = new FileInputStream(xmlExportFile);
							} catch (FileNotFoundException e) {
								logger.log(Level.WARN, "Can't create inputstream from export file: " + xmlExportFile.getName() + "\n");
								break;
							}
							
							String strXmlData = clearXMLDataFromHtml(xmlData);
							
							if(strXmlData == null)
							{
								break;
							}
							
							importer = (ImportExportInterface) ManagerFactory.getRemote(ImportExportBean.class);
							InputStream xslTemplate = null;
							String foTemplateName = "foExportPatient.xsl";
							byte[] filebytes = null;
							
							try {
								// Get the bytes of the template
								filebytes = importer.getTemplateBinary(foTemplateName);
								xslTemplate = new BufferedInputStream(new ByteArrayInputStream(filebytes)) ;
							} catch (Exception e) {
							    logger.log(Level.WARN, "Error loading template File " + foTemplateName + ".\n" + e.getMessage());  
							}
							
							try
							{
								if(xslTemplate == null)
									xslTemplate = new BufferedInputStream(ImporterClass.class.getResourceAsStream("resources/foExportPatient.xsl"));
							} catch (Exception e){
								logger.log(Level.WARN, "Error get internal template File " + foTemplateName + ".\n" + e.getMessage());
								break;
							}
							
							String strXslTemplate = addTranslationAndVariablesToXSLTemplate(xslTemplate);
							
							// get transformed byte array in output format
							TransFOmer transFOmer = TransFOmer.getInstance();
							byte[] byteArray = transFOmer.transFO(strXmlData, strXslTemplate, outputFormat);
							
							if(byteArray == null)
								break;
							
							// convert array of bytes into file
							String fileName = xmlExportFile.getName().replace(".xml", "");
							try {
								FileOutputStream fileOuputStream = new FileOutputStream(directory + FILE_SEPARATOR + fileName + "." + outputFormat); 
								fileOuputStream.write(byteArray);
								fileOuputStream.close();
								patientCount++;
								setVisible(false);	
								if (parentPanel != null) {
									parentPanel.removeSelectPatient(patientsSelected.get(i));
								}
							} catch (IOException e) {
								logger.log(Level.WARN, "Can't create export file: " + directory + FILE_SEPARATOR + fileName + "." + outputFormat + "\n");
							}
							// delete xml file
							if(xmlExportFile.exists()) xmlExportFile.delete();
							// close file handels
							if (xmlData != null) {
								try {
									xmlData.close();
								} catch (IOException e) {
									Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xmlData input stream.", e);
								}
							}
							if (xslTemplate != null) {
								try {
									xslTemplate.close();
								} catch (IOException e) {
									Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xslTemplate input stream.", e);
								}
							}
						}else{
							patientCount++;
							if (parentPanel != null) {
								parentPanel.removeSelectPatient(patientsSelected.get(i));
							}
						}
					}
				}
				
				openButton.setEnabled(true);
				saveButton.setEnabled(true);
				progressBarDialog.setVisible(false);
				String[] para = {"" + patientCount};
				
				// show export done message and ask if files should be explored 
				ButtonOption result = GECAMedBaseDialogImpl.showMessageDialog(ExportDialog.this, Translatrix.getTranslationString("exportPatientDialog.exportInfo.title"), Translatrix.getTranslationString("exportPatientDialog.exportInfo.exportDone", para), GECAMedBaseDialogImpl.OK_BUTTON_MODE, null, true, Translatrix.getTranslationString("exportPatientDialog.exportInfo.exploreFiles"));
				
				stopExport = false;
				if (parentPanel != null) {
					patientsSelected = new ArrayList<Integer>(parentPanel.getSelectedPatients());
					if(patientsSelected.size() <= 0) setVisible(false);					
				} else {
					setVisible(false);
				}
				
				// explore export files
				if(result.applyToAll)
				{
					// open save directory
					Desktop desktop = Desktop.getDesktop(); 
					try {
						desktop.open(directory);
					} catch (IOException e) {
						logger.log(Level.WARN, "Can't explore directory: " + directory + "\n");
					}
				}
			}
		});
		thread.start();
	}
	
	public void setStartDirectory(File startDirectory)
	{
		this.startDirectory = startDirectory;
	}

	
	public File getStartDirectory()
	{
		return this.startDirectory;
	}
	
	private static String addTranslationAndVariablesToXSLTemplate(InputStream xslTemplate)
	{
		// insert the translations
		InputStreamReader is = new InputStreamReader(xslTemplate);
		StringBuilder sb = new StringBuilder();
		BufferedReader br = new BufferedReader(is);
		String read = null;
		
		try {
			read = br.readLine();
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		while(read != null)
		{
			// translation
			if(read.contains("[") && read.contains("]")) // akitv only if translatix tag is set
			{
				// TODO run over the hole line
				String trans = read.substring(read.indexOf("["), read.indexOf("]")+1);
				String transword = read.substring(read.indexOf("[")+1, read.indexOf("]"));
				if(Translatrix.hasTranslationFor(transword))
				{
					read = read.replace(trans, Translatrix.getTranslationString(transword));
				}
			}
			// variables
			if(read.contains("[$") && read.contains("]"))
			{
				// run over the hole line
				String varname = read.substring(read.indexOf("[$"), read.indexOf("]")+1);
				
				// set entrie settings
				PatientModuleSettings patientGlobalSettings = PatientManagerModule.getInstance().patientSettings;
				
				ConsultationEntryConfig cec = null;
				
				// [$physician]
				if(varname.equals("[$physician]"))
				{
					read = read.replace(varname, new UtilFormatter((AddressManagerInterface) ManagerFactory.getRemote(AddressManagerBean.class)).formatPhysicianName(MainFrame.getCurrentPhysician(),true));
				}
				// [$soap.s]
				if(varname.equals("[$soap.s]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.SOAP_S));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$soap.o]
				if(varname.equals("[$soap.o]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.SOAP_O));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$soap.a]
				if(varname.equals("[$soap.a]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.SOAP_A));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$soap.p]
				if(varname.equals("[$soap.p]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.SOAP_P));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$cons.1]
				if(varname.equals("[$cons.1]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.CONS_1));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$cons.2]
				if(varname.equals("[$cons.2]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.CONS_2));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// [$cons.3]
				if(varname.equals("[$cons.3]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.CONS_3));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				// 
				if(varname.equals("[$measurement]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.MEASUREMENT));
						read = read.replace(varname, cec.getAcronym());
					}
				}
				//
				if(varname.equals("[$sick_leave]"))
				{
					if(patientGlobalSettings != null)
					{
						cec = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(IncidentManager.SICK_LEAVE));
						read = read.replace(varname, cec.getAcronym());
					}
				}
			}
			sb.append(read);
		    try {
				read = br.readLine();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close InputStreamReader.", e);
			}
		}
		if (br != null) {
			try {
				br.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close BufferedReader.", e);
			}
		}
		return sb.toString();
	}
	
	private static String clearXMLDataFromHtml(FileInputStream xmlData)
	{
		// xmldata html clearing
		InputStreamReader is = null;
		try {
			is = new InputStreamReader(xmlData,"UTF-8");
		} catch (UnsupportedEncodingException e2) {
			Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to create InputStreamReader with UTF-8 encoding.", e2);
			return null;
		}
		
		StringBuilder sb = new StringBuilder();
		BufferedReader br = new BufferedReader(is);
		String read = null;
		
		try {
			read = br.readLine();
		} catch (IOException e1) {
			e1.printStackTrace();
			return null;
		}
		// read xmldata
		while(read != null)
		{	
			sb.append(read);
			sb.append("\n");
		    try {
				read = br.readLine();
			} catch (IOException e1) {
				e1.printStackTrace();
				return null;
			}
		}

		String strData = sb.toString();
		String strHelp = strData;
		
		/////// HTML Passing
		String strTemp = "";
		String strSave = "";
		String replaceChar = "";
		
		// pattern for replace html named entities
		Pattern pattern = Pattern.compile("&([a-zA-Z]|\\d)+;");
		
		while(strHelp.contains("<![CDATA["))
		{
			strSave = strHelp.substring(strHelp.indexOf("<![CDATA["), strHelp.indexOf("]]>") + 3);
			strTemp = strHelp.substring(strHelp.indexOf("<![CDATA["), strHelp.indexOf("]]>"));
			
			Matcher m = pattern.matcher(strTemp);
			StringBuilder b = new StringBuilder();
			int prevMatchIx = 0;
			// replace html named entities
			while (m.find())
			{
				b.append(strTemp.substring(prevMatchIx, m.start()));
				String matchingText = m.group();
				replaceChar = HTML_NAMED_ENTITIES.get(matchingText);
				b.append(replaceChar);
				prevMatchIx = m.end();
			}
			strTemp = b.toString()+ strTemp.substring(prevMatchIx);
			
			// replace <br>
			strTemp = strTemp.replaceAll("<br>", "\n");
			// replace html tags with \n
			strTemp = strTemp.replaceAll("<[^>]*>\n", "");
			// replace the rest of html tags
			strTemp = strTemp.replaceAll("<[^>]*>", "");
			strTemp = strTemp.trim();
			// replace 2 or more blanks
			strTemp = strTemp.replaceAll("\\ {2,}","");
			
			strHelp = strHelp.replace(strSave, strTemp);
		}
		
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close InputStreamReader.", e);
			}
		}
		
		if (br != null) {
			try {
				br.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close BufferedReader.", e);
			}
		}
		
		return strHelp;
	}
	
	
	public static File exportSinglePatient(Patient patient, String outputFormat, boolean open) throws Exception {
		File directory = new File(System.getProperty("java.io.tmpdir") + FILE_SEPARATOR + "gecamed" + Long.toString(System.nanoTime()) + FILE_SEPARATOR);
		directory.deleteOnExit();
		
		
		int patientDataExportoption = XMLExporter.INCLUDE_MASTER_DATA;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_CONSULTATIONS;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_PRESCRIPTIONS;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ACTIVE_PROBLEMS;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ANTECEDENTS;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_EXTENDED_MASTER_DATA;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_INVOICES;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_FORMS;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_ALLERGIES;
		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_CHRONICAL_TREATMENTS;
//		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_FILE;
//		patientDataExportoption = patientDataExportoption | XMLExporter.INCLUDE_LETTERS;
		
		File xmlExportFile;
		xmlExportFile = XMLExporter.generateXMLForPatient(patient, patientDataExportoption, directory, true);
		xmlExportFile.deleteOnExit();
		
		// convert array of bytes into file
		String fileName = xmlExportFile.getName().replace(".xml", "");
		File file = new File(directory + FILE_SEPARATOR + fileName + "." + outputFormat);
		file.deleteOnExit();
		
		// Transfer xml data and xsl template to file format
		FileInputStream xmlData = null;
		try {
			xmlData = new FileInputStream(xmlExportFile);
		} catch (FileNotFoundException e) {
			throw new Exception("Can't create inputstream from export file: " + xmlExportFile.getName(), e);
		}
		
		String strXmlData = clearXMLDataFromHtml(xmlData);
		
		if(strXmlData == null)
		{
			return null;
		}
		
		ImportExportInterface importer = (ImportExportInterface) ManagerFactory.getRemote(ImportExportBean.class);
		InputStream xslTemplate = null;
		String foTemplateName = "foExportPatient.xsl";
		byte[] filebytes = null;
		
		try {
			// Get the bytes of the template
			filebytes = importer.getTemplateBinary(foTemplateName);
			xslTemplate = new BufferedInputStream(new ByteArrayInputStream(filebytes)) ;
		} catch (Exception e) {
		    logger.log(Level.WARN, "Error loading template File " + foTemplateName + ".\n" + e.getMessage());  
		}
		
		try
		{
			if(xslTemplate == null)
				xslTemplate = new BufferedInputStream(ImporterClass.class.getResourceAsStream("resources/foExportPatient.xsl"));
		} catch (Exception e){
			throw new Exception("Error get internal template File " + foTemplateName + ".\n" + e.getMessage(), e);
		}
		
		String strXslTemplate = addTranslationAndVariablesToXSLTemplate(xslTemplate);
		
		// get transformed byte array in output format
		TransFOmer transFOmer = TransFOmer.getInstance();
		
		byte[] byteArray = transFOmer.transFO(strXmlData, strXslTemplate, outputFormat);
		
		if(byteArray == null)
		{
			return null;
		}
		
		try {
			// save file
			FileOutputStream fileOuputStream = new FileOutputStream(directory + FILE_SEPARATOR + fileName + "." + outputFormat); 
			fileOuputStream.write(byteArray);
			fileOuputStream.close();								
		} catch (IOException e) {
			throw new Exception("Can't create export file: " + directory + FILE_SEPARATOR + fileName + "." + outputFormat, e);
		}
		
		if (open) {
			// open file with default application
			Desktop desktop = Desktop.getDesktop(); 
			try {
				desktop.open(file);
			} catch (IOException e) {
				logger.log(Level.WARN, "Can't open export file: " + directory + FILE_SEPARATOR + fileName + "." + outputFormat + "\n");
			}
		}
		// delete xml file
		if(xmlExportFile.exists()) xmlExportFile.delete();
		// close file handels
		if (xmlData != null) {
			try {
				xmlData.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xmlData input stream.", e);
			}
		}
		if (xslTemplate != null) {
			try {
				xslTemplate.close();
			} catch (IOException e) {
				Logger.getLogger(XMLExporter.class.getSimpleName()).log(Level.WARN, "Unable to close xslTemplate input stream.", e);
			}
		}
		
		return file;
	}
	
}