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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.font.TextAttribute;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

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.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.controller.ControllerConfig;
import lu.tudor.santec.gecamed.core.gui.controller.document.DocumentController;
import lu.tudor.santec.gecamed.core.gui.listener.AEntryAction;
import lu.tudor.santec.gecamed.core.gui.listener.IEntryPrintRenderer;
import lu.tudor.santec.gecamed.core.gui.listener.IEntryTypeHandler;
import lu.tudor.santec.gecamed.core.gui.plugin.filehandler.FileOpener;
import lu.tudor.santec.gecamed.core.gui.utils.LineColorCellRenderer;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.esante.ejb.session.beans.CDAManagerBean;
import lu.tudor.santec.gecamed.esante.gui.IconNames;
import lu.tudor.santec.gecamed.esante.gui.actions.UploadToDspAction;
import lu.tudor.santec.gecamed.esante.gui.utils.ESanteGuiUtils;
import lu.tudor.santec.gecamed.esante.gui.webservice.DspPrivileges;
import lu.tudor.santec.gecamed.esante.gui.webservice.Security;
import lu.tudor.santec.gecamed.esante.gui.webservice.WebserviceConstants;
import lu.tudor.santec.gecamed.letter.ejb.entity.beans.Letter;
import lu.tudor.santec.gecamed.letter.ejb.session.beans.LetterBean;
import lu.tudor.santec.gecamed.letter.ejb.session.beans.LetterTemplateBean;
import lu.tudor.santec.gecamed.letter.ejb.session.interfaces.LetterInterface;
import lu.tudor.santec.gecamed.letter.ejb.session.interfaces.LetterTemplateInterface;
import lu.tudor.santec.gecamed.letter.gui.dialogs.ReplaceOrCopyLetterDialog;
import lu.tudor.santec.gecamed.letter.gui.letterlist.DescriptionDialog;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Incident;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.IncidentEntry;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.IncidentEntryType;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.ejb.session.beans.IncidentManagerBean;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.IncidentManager;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.history.contextmenu.ChangeIncidentAction;
import lu.tudor.santec.i18n.Translatrix;

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

import furbelow.AnimatedIcon;

/*
 * PART THAT SHOWS AND HANDLES LETTERS IN THE HISTORY TABLE
 */

public class LetterHandler implements IEntryTypeHandler {

    	/**
	 * static logger for this class
	 */
	private static Logger logger = Logger.getLogger(LetterHandler.class.getName());
    
	public static final String ENTRY_TYPE = "letter";

	public static final int LARGEPIX 	= 64;
	public static final int NORMALPIX 	= 32;
	public static final int MEDIPIX 	= 24;
	public static final int SMALLPIX 	= 18;
	public static final int MINIPIX 	= 16;
	
	private static final ImageIcon LETTER_STATUS_ICON = IconFetcher.getSmallIcon(LetterTemplateModule.class, "message_info.png");

	private LetterRenderer renderer = new LetterRenderer();

//	private AEntryAction modifyAction;

	private IncidentManager iManager;

	private LetterTemplateInterface letterTemplateManager;

//	private AEntryAction renameAction;

	private AEntryAction deleteAction;

	private LetterInterface letterManager;

	private AEntryAction changeDescriptionAction;

	private Vector<Action> actionList;

	private AEntryAction openAction;
	
	private AEntryAction changeIncidentAction;
	
	private UploadToDspAction uploadToDspAction;
	
	private UploadToDspAction updateDocumentAction;

	private static LetterHandler letterHandler;
	
	private ReplaceOrCopyLetterDialog modifyCopyDialog;
	
	private JPopupMenu popup;
	
	/**
	 * 
	 */
	public LetterHandler(){
		letterHandler	= this;
		popup			= new JPopupMenu();
		
		
		popup.setBackground(GECAMedColors.c_GECAMedBackground);
			
		initActions();
	}

	public Collection<Action> getActions(IncidentEntry entry) 
	{
//		return this.actionList;
		return null;
	}
	
	/**
	 * Indicates if the local Gecamed patient is currently linked to an electronic health record (dsp) 
	 * @return True, if the patient is linked to a dsp
	 */
	private boolean isPatientLinkedToDsp() {
		
		Patient patient = GECAMedModule.getCurrentPatient();
		return CDAManagerBean.getInstance().getLinkedDsp(patient.getId()) != null;
	}
	
	@SuppressWarnings("unchecked")
	public JPopupMenu getPopup(IncidentEntry entry)
	{
		JMenuItem					item;
		Vector<String>				letterStates;
		Map<TextAttribute, Object>	attributes;
		AEntryAction				action;
//		JLabel						headline;
		
		
		popup.removeAll();
		for (Action a : actionList) 
		{
			if (a instanceof AEntryAction)
				((AEntryAction)a).setEntry(entry);
			
			item = new JMenuItem(a);
			item.setOpaque(false);
			popup.add(item);

		}
		// obtain user privileges from cache
		DspPrivileges privileges = Security.getCachedDspPrivileges(GECAMedModule.getCurrentPatient().getIdLuxembourg());
		
		// only add an upload option if the patient has been linked to a dsp and the user possesses sufficient permissions
		// However if the user is not logged into the eSanté DSP thoses permissions cannot be determined. 
		// Thus show the upload option also in this case
		if (isPatientLinkedToDsp() && ((privileges == null) || privileges.isUploadAllowed() || privileges.isPresencePasswordAllowed())) {

			if (entry.getCdaUniqueId() == null) {
				// this letter is not yet available in the eSanté DSP, thus add the upload item to the context menu
				this.uploadToDspAction.setEntry(entry);
				item = new JMenuItem(this.uploadToDspAction);
			} else {
				// add item for replacing the document
				this.updateDocumentAction.setUploadMode(WebserviceConstants.UPLOAD_REPLACE_DOCUMENT);
				this.updateDocumentAction.setEntry(entry);
				item = new JMenuItem(this.updateDocumentAction);
			}

			item.setOpaque(false);
			popup.add(item);
		}
				
		letterStates = LetterTemplateModule.getInstance().getLetterStatuses();
		if (letterStates != null && letterStates.size() > 0)
		{
			popup.addSeparator();

			JMenuItem headline = new JMenuItem(Translatrix.getTranslationString("LetterTemplateModule.menu.statusHeadline"));
			headline.setOpaque(false);
			headline.setEnabled(false);
			attributes	= (Map<TextAttribute, Object>) headline.getFont().getAttributes();
			attributes.put(TextAttribute.WEIGHT,		TextAttribute.WEIGHT_BOLD);
//			attributes.put(TextAttribute., value)
			headline.setFont(new Font(attributes));
			headline.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
			popup.add(headline);
			
			for (String state : letterStates)
			{
				action = createChangeLetterStateAction(entry, state);
				item = new JMenuItem(action);
				item.setOpaque(false);
				attributes = ((Map<TextAttribute, Object>) item.getFont().getAttributes());
				attributes.put(TextAttribute.WEIGHT,		TextAttribute.WEIGHT_REGULAR);
				attributes.put(TextAttribute.FOREGROUND,	Color.DARK_GRAY);
				attributes.put(TextAttribute.POSTURE,		TextAttribute.POSTURE_OBLIQUE);
				item.setFont(new Font(attributes));
				popup.add(item);
			}
		}
		
		return popup;
	}
	

	public TableCellRenderer getRenderer(String entryType) {
		/* ================================================== */
		return renderer;
		/* ================================================== */
	}

	public HashMap<Integer, Object> getSpecialEntries(String entryType,	Integer patientId) {
		/* ================================================== */
		return null;
		/* ================================================== */
	}

	
	/**
	 * Opens an incident entry type of the type letter  
	 */
	public boolean openEntry(final IncidentEntry entry) {
		/* ================================================== */
		this.openAction.setEntry(entry);
		this.openAction.actionPerformed(null);
		
		return true;
		/* ================================================== */
	}

	/**
	 *  Renderer for the History Table
	 * @author herve.weitz@tudor.lu
	 * 03.07.2008
	 * 11:24:42
	 *
	 *
	 * @version
	 * <br>$Log: LetterHandler.java,v $
	 * <br>Revision 1.46  2014-02-13 15:35:06  donak
	 * <br>Fixed bug in routine detecting if the user is already logged into a patient dap but needs a presence password for uploading a document
	 * <br>Fixed isUploadAllowed() routine and also its usage. This routine now indicates if the user is allowed to upload a document with his current permissions. If you want to determine if the user might be allowed to upload a document by providing a presence password, please use isPresencePasswordAllowed()
	 * <br>
	 * <br>Revision 1.45  2014-01-31 16:29:43  donak
	 * <br>Added error dialog when document cannot be uploaded due to invalid access privileges
	 * <br>Fixed bug that prevented saml assertions from being renewed after they exceeded in cache
	 * <br>Fixed bug that prevented documents from being uploaded (gecamed id has not been written to template due to renaming of placeholder)
	 * <br>SMART UPLOAD (TM) feature: Upload option is added to context menu dependent on dsp access permissions and upload success probability calculations
	 * <br>Upload support for images added
	 * <br>
	 * <br>Revision 1.44  2014-01-30 18:14:12  donak
	 * <br>upload option will only be offered, if the user possesses the appropriate mandate and access rights to the dsp.
	 * <br>
	 * <br>Revision 1.43  2013-12-20 15:56:20  ferring
	 * <br>Letters are replaced and copied correctly again
	 * <br>
	 * <br>Revision 1.42  2013-11-15 16:11:15  donak
	 * <br>made upload to eSanté DSP menu item transparent
	 * <br>
	 * <br>Revision 1.41  2013-11-15 15:44:32  donak
	 * <br>Suppressed upload to eSanté DSP option for letters that have already been uploaded
	 * <br>Added workaround for the filename-bug of incident entries of type letter (filename and original filename are swapped) which came into affect when converting to pdf/a
	 * <br>
	 * <br>Revision 1.40  2013-11-12 12:48:22  donak
	 * <br>Document upload:
	 * <br>* conversion to pdf/a using open office has been moved to the server. OpenOffice 4 has to be located in the jboss work directory. ATTENTION: it still has to be evaluated if the license agreement dialog occurs when instance is started the first time on the server.
	 * <br>* If document contains a description, the first forty characters of the description followed by three dots will be used as title instead of the filename
	 * <br>* Upload of incident type letters has been fixed
	 * <br>* upload for docx files has been added
	 * <br>
	 * <br>Upload parameters:
	 * <br>* database does now support storage of user dependent properties
	 * <br>* The system will automatically remember the last chosen values for confidentiality, facility type, and speciality and propose them as default when the next document will be uploaded.
	 * <br>
	 * <br>Inactivity Monitor:
	 * <br>* the event mouse wheel scrolling is now taken into account for resetting the logoff timer
	 * <br>* the logoff delay is now stored in the database. If the database does not contain this parameter, it will be created
	 * <br>
	 * <br>General:
	 * <br>* Optimized incident entry bean handling. Caching will now avoid copying the binary content and the generated pdf content of an incident entry as these elements should only be loaded when needed. Now it should be save to re-implement a proper getBinaryContent() handling.
	 * <br>
	 * <br>Revision 1.39  2013-10-29 10:04:08  donak
	 * <br>Fixed: Unlinked patient records possessed the possibility to upload documents to the DSP, which is impossible
	 * <br>Fixed: User will now be informed if client time is out of sync with the server and thus the saml assertion is denied
	 * <br>
	 * <br>Revision 1.38  2013-10-23 09:36:06  donak
	 * <br>Undo conversion deactivation
	 * <br>
	 * <br>Revision 1.36  2013-10-21 10:58:28  donak
	 * <br>Fixed receive file content bug
	 * <br>Fixed bug about not displaying progress indicator (animated gif) when context is not on JTable
	 * <br>Fixed upload menu item for letters where item text was not language dependent (also removed ProvideDocumentAction as it was redundant)
	 * <br>
	 * <br>Revision 1.35  2013-10-17 14:54:30  donak
	 * <br>Corrected upload handler for letters
	 * <br>Defined incident entry dependent presets for upload metadata
	 * <br>Bug fixing and documentation
	 * <br>
	 * <br>Revision 1.34  2013-07-15 06:18:39  ferring
	 * <br>logging changed
	 * <br>
	 * <br>Revision 1.33  2013-06-10 08:22:14  ferring
	 * <br>eSante POC
	 * <br>
	 * <br>Revision 1.32  2013-04-30 14:35:19  ferring
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.31  2013-04-30 14:33:35  ferring
	 * <br>Letters where lost, when opening another patient or closing current patient and then closing the letter.
	 * <br>
	 * <br>Revision 1.30  2013-04-30 11:48:15  ferring
	 * <br>letters aren't overwritten anymore
	 * <br>
	 * <br>Revision 1.29  2013-04-30 11:31:05  ferring
	 * <br>letters aren't overwritten anymore
	 * <br>
	 * <br>Revision 1.28  2013-02-13 14:01:58  ferring
	 * <br>history will not always be reloaded completely
	 * <br>
	 * <br>Revision 1.27  2013-02-08 15:27:17  ferring
	 * <br>Option added for files and letters to attach them to another incident
	 * <br>
	 * <br>Revision 1.26  2013-02-05 13:15:18  ferring
	 * <br>letter status added
	 * <br>
	 * <br>Revision 1.25  2012-12-14 09:48:21  ferring
	 * <br>Interface IController replaced by abstract class DocumentController
	 * <br>Function added to update placeholders in letter template
	 * <br>
	 * <br>Revision 1.24  2012-12-05 14:01:46  ferring
	 * <br>rename option removed in right click menu on letter history entry
	 * <br>
	 * <br>Revision 1.23  2012-12-05 13:51:58  ferring
	 * <br>unneeded code removed
	 * <br>
	 * <br>Revision 1.22  2012-11-26 13:23:12  ferring
	 * <br>Open and modify letter changed to one action. User will be asked, after closing the document, what to do
	 * <br>
	 * <br>Revision 1.21  2012-11-26 07:56:14  ferring
	 * <br>New placeholders are introduced to the letter module
	 * <br>The replacement algorithm in Word- and WriterCotnroller has been changed
	 * <br>Multicontacts are prepared, but not yet implemented
	 * <br>
	 * <br>Revision 1.20  2011-08-17 08:41:16  ferring
	 * <br>Office controller moved to core as they are not only used by the letter module anymore.
	 * <br>
	 * <br>Revision 1.19  2010-09-23 12:22:03  hermen
	 * <br>now sets current user as creator of incident entry instead of current phy, which was wrong!!!
	 * <br>
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/643
	 * <br>
	 * <br>Revision 1.18  2009-12-16 11:12:15  hermen
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.17  2009-05-06 15:58:51  heinemann
	 * <br>added method to generate printable output of the incident entrys
	 * <br>
	 * <br>Revision 1.16  2009-02-25 13:26:09  hermen
	 * <br>added siteID to incidents and invoices
	 * <br>
	 * <br>Revision 1.15  2008-12-16 10:35:43  hermen
	 * <br>added fixJarUrl for Webstart icon url bug
	 * <br>
	 * <br>Revision 1.14  2008-12-10 15:17:02  hermen
	 * <br>added bugfix for java5 webstart resource loading
	 * <br>
	 * <br>Revision 1.13  2008-09-25 09:43:06  heinemann
	 * <br>fixed copyrights
	 * <br>
	 * <br>Revision 1.12  2008-09-03 10:24:14  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.11  2008-07-10 10:21:26  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.10  2008-07-03 11:59:57  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 *   
	 */
	class LetterRenderer extends LineColorCellRenderer 
	{
		private static final long serialVersionUID = 1L;

		private final static int fontSize = 9;
		
		private JLabel letterLabel;
		private JLabel uploadedIconLabel;
		private JPanel cellPanel;

		private ImageIcon eSanteIcon;
		private AnimatedIcon uploadingIcon;
		private ImageIcon letterIcon ;
		
		public LetterRenderer() {
			this.letterLabel = new JLabel();
			this.letterLabel.setOpaque(false);
			this.uploadedIconLabel = new JLabel();
			this.uploadedIconLabel.setOpaque(false);
			this.cellPanel = new JPanel(new BorderLayout());
			this.cellPanel.setOpaque(true);
			this.cellPanel.add(letterLabel, BorderLayout.WEST);
			this.cellPanel.add(uploadedIconLabel, BorderLayout.EAST);
			this.letterIcon = IconFetcher.getIcon(lu.tudor.santec.gecamed.letter.gui.IconNames.class, lu.tudor.santec.gecamed.letter.gui.IconNames.LETTER);

			// DO NOT use IconFetcher for this at this location. Otherwise animation will fail!
			this.uploadingIcon = new AnimatedIcon(new ImageIcon(IconNames.class.getResource("resources/icons/" + IconNames.LOADING_ANIMATED)));
			this.eSanteIcon = ESanteGuiUtils.getESanteIcon(64);
		}

		@Override
		public Component getTableCellRendererComponent(JTable p_Table,
				Object value, boolean p_IsSelected, boolean hasFocus,
				int p_Row, int p_Column) {
			/* ================================================== */
			if (value instanceof IncidentEntry) {
				/* ------------------------------------------------------- */
				IncidentEntry entry = (IncidentEntry) value;
//				ie = iManager.getIncidentEntry(ie.getId());
				
				if (p_Column == 2) {
					/* ------------------------------------------------------- */
					return super.getTableCellRendererComponent(p_Table, "L",
							p_IsSelected, hasFocus, p_Row, p_Column);
					/* ------------------------------------------------------- */
				} else if (p_Column == 3) {
					/* ------------------------------------------------------- */
					// assemble the representation of the letter details
					StringBuffer buff = new StringBuffer(
							"<html><span style=\"font-family:Arial;font-size:"
									+ fontSize + "px;\">");
					this.letterLabel.setIcon(this.letterIcon);
					// add the letter text
					if (entry.getTextContent() != null){
						buff.append(entry.getTextContent().replaceAll("\n", "<br>"));
					}
					

					
					// show the status, if available
					if (entry.getStatus() != null && entry.getStatus().trim().length() > 0)
						buff.append("   ").append(Translatrix.getTranslationString("LetterTemplateModule.history.status", 
								new String[] { entry.getStatus() }));
					
//					if (ie.getFileName() != null)
//						buff.append(ie.getFileName() + "</td></tr></table>");
					
					// and finish the html content
					buff.append("</span></html>");
					
					setSize(p_Table.getColumnModel().getColumn(p_Column).getWidth(),
							getPreferredSize().height);

					if (p_Table.getRowHeight(p_Row) < getPreferredSize().height) {
						p_Table.setRowHeight(p_Row, getPreferredSize().height);
					}
					if (entry.getCdaUniqueId() == null) {
						// document hat not been uploaded to DSP - display no icon at all
						this.uploadedIconLabel.setIcon(null);
					} else if (entry.getCdaUniqueId().equals(IconNames.UPLOAD_INDICATOR_STRING)) {
						// if the document is currently in the upload process, display an animated gif to indicate activity
						this.uploadedIconLabel.setIcon(this.uploadingIcon);
					} else{
						// if the document has already been uploaded to the dsp indicate this by a "my dsp" icon
						this.uploadedIconLabel.setIcon(this.eSanteIcon);	
					}
					
					// render the cell
					super.getTableCellRendererComponent(p_Table, buff.toString(), p_IsSelected, hasFocus, p_Row, p_Column);
					// and add it to the table
					this.cellPanel.add(this, BorderLayout.CENTER);
					// set the alignment
					this.setHorizontalAlignment(JLabel.LEFT);
					// and also the background color
					this.cellPanel.setBackground(this.getBackground());

					return this.cellPanel;
				}
			}
			return super.getTableCellRendererComponent(p_Table, value, p_IsSelected, hasFocus, p_Row, p_Column);
		}
	}
	
	public static String getIconPath (String p_IconName) 
	{
	String 		l_IconPath;
	URL 		l_Location;

	l_IconPath = "resources/icons/" + p_IconName;
	l_Location = LetterHandler.class.getResource(l_IconPath);
	
//	// fixes java5 webstart resource loading bug
//	if (l_Location.toString().indexOf(".jar") < 0) {
//        	String jarFile = LetterHandler.class.getProtectionDomain().getCodeSource().getLocation().toString();
//        	String path = l_Location.toString().replaceAll("jar:", "");
//        	String validPath = "jar:" + jarFile + "!/" + path;
////        	System.out.println("newPath:" + validPath);
//        	return validPath;
//	}
	
	return IconFetcher.fixJarURL(l_Location).toString();
	}
	
	public static LetterHandler getInstance(){
		return letterHandler;
	}
	
	
	
	/* ***********************************************************************
	 * Actions
	 */
	
	private void initActions() {
		/* ================================================== */
		this.iManager 	           = (IncidentManager)         ManagerFactory.getRemote(IncidentManagerBean.class);
		this.letterTemplateManager = (LetterTemplateInterface) ManagerFactory.getRemote(LetterTemplateBean.class);
		this.letterManager 		   = (LetterInterface)         ManagerFactory.getRemote(LetterBean.class);
		/* ------------------------------------------------------- */
		initOpenAction();
//		initModifyAction();
//		initRenameAction();
		initDeleteAction();
		initChangeDescriptionAction();
		this.changeIncidentAction = ChangeIncidentAction.getInstance();
		/* ------------------------------------------------------- */
		this.actionList = new Vector<Action>();
		/* ------------------------------------------------------- */
		this.actionList.add(openAction);
//		this.actionList.add(modifyAction);
//		this.actionList.add(renameAction);
		this.actionList.add(deleteAction);
		this.actionList.add(changeDescriptionAction);
		this.actionList.add(changeIncidentAction);
		this.uploadToDspAction = new UploadToDspAction();
		this.updateDocumentAction = new UploadToDspAction(Translatrix.getTranslationString("esante.actions.updateDocument"));
		/* ================================================== */	
	}
	
	
	/**
	 * 
	 */
	private void initOpenAction() 
	{
		this.openAction = new AEntryAction(Translatrix
				.getTranslationString("LetterTemplateModule.menu.open"), 
				GECAMedModule.getSmallIcon(GECAMedIconNames.OPEN)) 
		{
			private static final long serialVersionUID = 1L;
			
			public void actionPerformed(ActionEvent e) 
			{
				new OpenThread(entry2work, 
						GECAMedModule.getCurrentPatient().getId(), 
						GECAMedModule.getCurrentPhysician().getId()).start();
			}
		};
	}
	
	
	private void initChangeDescriptionAction() {
		/* ================================================== */
		this.changeDescriptionAction = new AEntryAction(
				Translatrix.getTranslationString("LetterTemplateModule.menu.changedescription"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.RENAME)) 
		{

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				IncidentEntry currentEntry	= entry2work;
				
				
				String description = currentEntry.getTextContent();
				DescriptionDialog dialog = new DescriptionDialog(description);
				
				if (dialog.hasChanged()) {
					/* ------------------------------------------------------- */
					currentEntry = iManager.getIncidentEntry(currentEntry.getId());
					currentEntry.setTextContent(dialog.getTDescription().getText());
					
					iManager.saveEntry(currentEntry, IncidentManagerBean.LETTER);
					PatientManagerModule.getInstance().getPatientPanel().reloadHistory();
					/* ------------------------------------------------------- */
				}
				/* ====================================================== */
			}
			
		};
		/* ================================================== */
	}
	
	
	private AEntryAction createChangeLetterStateAction (IncidentEntry entry, final String state)
	{
		AEntryAction action = new AEntryAction(
				(state.equals(entry.getStatus()) ? "<html><b>" : "<html>") + state,
				LETTER_STATUS_ICON)
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed(ActionEvent e)
			{
				IncidentEntry currentEntry	= entry2work;
				
				
				currentEntry.setStatus(state);
				currentEntry	= ((IncidentManager)ManagerFactory.getRemote(IncidentManagerBean.class))
						.saveEntry(currentEntry, ENTRY_TYPE);
//				PatientManagerModule.getInstance().getPatientPanel().reloadHistory();
				PatientManagerModule.getInstance().getPatientPanel().repaint();
			}
		};
		action.setEntry(entry);
		
		return action;
	}
	
	
	/**
	 * 
	 */
	private void initDeleteAction() {
		/* ================================================== */
		this.deleteAction = new AEntryAction(Translatrix
				.getTranslationString("LetterTemplateModule.menu.delete"), 
				GECAMedModule.getSmallIcon(GECAMedIconNames.REMOVE)) {

			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
				IncidentEntry currentEntry	= entry2work;
				
				
				if (JOptionPane.showConfirmDialog(MainFrame.getInstance(),
						Translatrix.getTranslationString("LetterTemplateModule.dialog.confirm.deleteletter")) == JOptionPane.YES_OPTION) {
					/* ------------------------------------------------------- */
					letterManager.removeLetterbyIncidentId(currentEntry.getId());
					
					iManager.removeIncidentEntry(currentEntry);
					
					PatientManagerModule.getInstance().getPatientPanel().reloadHistory();
//					try {
//						/* --------------------------------------------- */
//						LetterPanel.getInstance().getCbModel().queryLetterTypes();
//						/* --------------------------------------------- */
//					} catch (Exception ex) {
//						/* --------------------------------------------- */
//						ex.printStackTrace();
//						/* --------------------------------------------- */
//					}
				}
				/* ====================================================== */
			}
			
		};
		/* ================================================== */
	}
	
	
	public IEntryPrintRenderer getPrintRenderer(String entryType) {
		/* ====================================================== */
		// TODO Auto-generated method stub
		return null;
		/* ====================================================== */
	}
	
	
	
	private class OpenThread extends Thread
	{
		/* ======================================== */
		// 		MEMBERS
		/* ======================================== */
		
		private	IncidentEntry			currentEntry;
		
		private	DocumentController		controller;
		
		private	Integer					entryPatientId;
		
		private	Integer					entryPhysicianId;
		
		
		
		/* ======================================== */
		// 		CONSTRUCTORS
		/* ======================================== */
		
		public OpenThread (IncidentEntry currentEntry, Integer entryPatientId, Integer entryPhysicianId)
		{
			this.currentEntry		= currentEntry;
			this.entryPatientId		= entryPatientId;
			this.entryPhysicianId	= entryPhysicianId;
			this.controller			= LetterTemplateModule.getController();
		}
		
		
		
		/* ======================================== */
		// 		CLASS BODY
		/* ======================================== */
		
		@Override
		public void run()
		{
			byte[]				filebytes;
			Integer				option;
			File				document;
			IncidentEntry		ie;
			IncidentEntryType	entryType;
			Incident			incident;
			LetterInterface		letterManager;
			Letter				letter;
			ArrayList<Letter>	oldLetter;
			
			
			if (controller == null) {
			    logger.info("ControllerConfig.getController() returns NULL....stopping here");
			    return;
			}
			
			try 
			{
				MainFrame.getInstance().setWaitCursor(true);
				filebytes = letterTemplateManager.getFile(
						currentEntry.getOriginalFilename(),  
						entryPatientId);
				controller.setDocument(filebytes);
				controller.open(DocumentController.TYPE_OPEN_LETTER);
				MainFrame.getInstance().setWaitCursor(false);
				controller.waitForUserInput();
				
				if (controller.getState().isSaved()) 
				{
					if (modifyCopyDialog == null)
						modifyCopyDialog	= new ReplaceOrCopyLetterDialog();
					
					option = Integer.valueOf(0);
					synchronized (option)
					{
						// wait here if a 2nd letter is closed, before the dialog was closed
						option	= Integer.valueOf(modifyCopyDialog.showDialog(currentEntry.getFileName()));
					}
					
					if (option.intValue() == ReplaceOrCopyLetterDialog.CREATE_NEW 
							|| option.intValue() == ReplaceOrCopyLetterDialog.REPLACE)
					{
						/* ------------------------------------------------------- */
						// Getting document from the client
						/* ------------------------------------------------------- */
						document = controller.getDocumentbyFile();
						/* ------------------------------------------------------- */
						// Saving the file on the server
						/* ------------------------------------------------------- */
						currentEntry.setBinaryContent(controller.getDocument());
						currentEntry.setOriginalFilename(document.getName());
						
//						generatedFilename = letterTemplateManager.saveFile(
//								controller.getDocument(),
//								document.getName(),
//								entryPatientId);
//						
//						if (generatedFilename == null || generatedFilename.trim().length() == 0)
//						{
//							// TODO: add user information
//							logger.warn("Couldn't save file for incident entry " + currentEntry.getId());
//							return;
//						}
						
						/* ------------------------------------------------------- */
						// Delete the local file
						/* ------------------------------------------------------- */
						if (ControllerConfig.deleteDocuments()) 
						{
							// Delete the local document
							controller.deleteDocument();
						}
						
						if (option.intValue() == ReplaceOrCopyLetterDialog.CREATE_NEW)
						{
							/* ------------------------------------------------------- */
							// CREATE A NEW FILE & INCIDENT ENTRY
							/* ------------------------------------------------------- */
							// Creating the incident for the patient
							/* ------------------------------------------------------- */
							ie = new IncidentEntry();

							entryType = new IncidentEntryType();
							entryType.setName(IncidentManager.LETTER);
							/* ------------------------------------------------------- */
							// Attaching the Type of the file to the
							// incident
							/* ------------------------------------------------------- */
							ie.setEntryType(entryType);
							ie.setBinaryContent(FileOpener.loadBinary(currentEntry));
							ie.setOriginalFilename(currentEntry.getOriginalFilename());
							/* ------------------------------------------------------- */
							// Create a new incident if the current is
							// not present.
							/* ------------------------------------------------------- */
							incident = new Incident(
								entryPatientId,
								entryPhysicianId);
							incident.setSiteId(MainFrame.getCurrentSiteId());
							Incident newI = iManager.saveIncident(incident);
							ie.setIncident(newI);
							/* ------------------------------------------------------- */
							// Set created, createdby, modified,
							// modifiedby
							/* ------------------------------------------------------- */
							ie.setCreated(new Date());
							ie.setCreatedBy(GECAMedModule.getCurrentUser().getId());
							ie.setModified(new Date());
							ie.setModifiedBy(GECAMedModule.getCurrentUser().getId());

							ie.setTextContent(currentEntry.getTextContent());
							/* ------------------------------------------------------- */
							// Set the file name
							/* ------------------------------------------------------- */
							ie.setFileName(currentEntry.getFileName());
							/* ------------------------------------------------------- */
							// save
							/* ------------------------------------------------------- */
							ie.setStatus(currentEntry.getStatus());
							ie = iManager.saveEntry(ie, IncidentManager.LETTER);
							/* ------------------------------------------------------- */
							// Saving letter corresponding to the
							// incident entry
							/* ------------------------------------------------------- */
							letterManager = (LetterInterface) ManagerFactory
									.getRemote(LetterBean.class);
							/* ------------------------------------------------------- */
							letter = new Letter();
							letter.setIncidentEntryID(ie.getId());
							/* ------------------------------------------------------- */
							oldLetter =  (ArrayList<Letter>) 
									letterManager.getLetterByIncidentEntry(currentEntry.getId());
							/* ------------------------------------------------------- */
							letter.setType(oldLetter.get(0).getType());
							letter.setMimetype(oldLetter.get(0).getMimetype());

							letterManager.addLetter(letter);
							/* ------------------------------------------------------- */
						}
						else if (option.intValue() == ReplaceOrCopyLetterDialog.REPLACE)
						{
							/* ------------------------------------------------------- */
							// MODIFY
							/* ------------------------------------------------------- */
							currentEntry.setModified(new Date());
							currentEntry.setModifiedBy(GECAMedModule.getCurrentUser().getId());
							/* ------------------------------------------------------- */
							// save
							/* ------------------------------------------------------- */
//							currentEntry.setOriginalFilename(generatedFilename);
							iManager.saveEntry(currentEntry, IncidentManager.LETTER);
						}
						// else: option == ReplaceOrCopyLetterDialog.DISCARD
						
						PatientManagerModule.getInstance().getPatientPanel().reloadHistory();
					}
				}
			} catch (Exception e) {
				/* ------------------------------------------------------- */
				MainFrame.getInstance().setWaitCursor(false);
				logger.log(Level.WARN, e.getMessage());
				JOptionPane.showMessageDialog(
						LetterTemplateModule.getInstance().getContentPane(),
						Translatrix.getTranslationString("LetterTemplateModule.dialog.error.open"),
						Translatrix.getTranslationString("LetterTemplateModule.dialog.error.title"),
						JOptionPane.ERROR_MESSAGE);
				/* ------------------------------------------------------- */
			}
		}
	}
	
	
//	private Action createChangeLetterStateAction (final IncidentEntry entry, final String state)
//	{
//		Action a = new AbstractAction((state.equals(entry.getCode()) ? "<html><b>" : "<html>") + state)
//		{
//			private static final long	serialVersionUID	= 1L;
//
//			public void actionPerformed(ActionEvent e)
//			{
//				entry.setCode(state);
//				((IncidentManager)ManagerFactory.getRemote(IncidentManagerBean.class)).saveEntry(
//						entry, entry.getEntryType().getName());
//			}
//		};
//		
//		return a;
//	}
}
