package lu.tudor.santec.gecamed.formeditor.gui.controller;

import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.XSLTemplate;
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.controller.document.UnsupportedFileTypeException;
import lu.tudor.santec.gecamed.core.gui.widgets.xslt.ChooseXslDialog;
import lu.tudor.santec.gecamed.formeditor.gui.FormEditorModule;
import lu.tudor.santec.gecamed.formeditor.gui.FormPrinter;
import lu.tudor.santec.gecamed.formeditor.gui.controller.converter.FormDataConverter;
import lu.tudor.santec.gecamed.formeditor.gui.model.FormModel;
import lu.tudor.santec.gecamed.formeditor.gui.view.FormTab;
import lu.tudor.santec.gecamed.formeditor.gui.view.dialog.ChangeCreationDateDialog;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.i18n.Translatrix;

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

public class FormPopupController implements MouseListener 
{
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(FormPopupController.class.getName());
	
	public static final int PRINT_AS_IREPORT 	= 0;
	public static final int PRINT_VIA_XSL		= 1;
	
	
	private JPopupMenu 	popupMenu;
	private FormModel 	formModel;
	private FormTab 	tab;
	
	private JMenuItem 	closeMenuItem;
	private JMenuItem 	closeAllMenuItem;
	private JMenuItem 	printIReportMenuItem;
	private JMenuItem	printHtmlMenuItem;
	private JMenuItem	editHtmlMenuItem;
	private JMenuItem 	changeCreationDateMenuItem;
	private JMenuItem 	deleteMenuItem;
	
	private ChangeCreationDateDialog ccdDialog;
	
	public FormPopupController (FormTab tab, FormModel viewModel) 
	{
		this.popupMenu 	= new JPopupMenu();;
		this.tab 		= tab;
		this.formModel 	= viewModel;
		
		/* ********** create the close button ********** */ 
		closeMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.form.close"),
				GECAMedModule.getMiniIcon(GECAMedIconNames.CLOSE));
		
		closeMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				FormPopupController.this.tab.closeForm(formModel);
				FormPopupController.this.popupMenu.setVisible(false);
			}
		});
		addMenuItem(closeMenuItem);
		/* **************************************** */
		
		
		/* ********** create the closeAll button ********** */ 
		closeAllMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.form.closeAll"),
				GECAMedModule.getMiniIcon(GECAMedIconNames.CLOSE));
		
		closeAllMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				FormPopupController.this.tab.closeAllForms();
			}
		});
		addMenuItem(closeAllMenuItem);
		/* **************************************** */
		
		
		/* ********** create the delete button ********** */ 
		deleteMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.form.delete"),
				GECAMedModule.getMiniIcon(GECAMedIconNames.CANCEL));
		
		deleteMenuItem.addActionListener(new ActionListener() 
		{	
			public void actionPerformed(ActionEvent e) 
			{
				FormPopupController.this.tab.delete(formModel);
			}
		});
		
		addMenuItem(deleteMenuItem);
		/* **************************************** */
		
		popupMenu.addSeparator();
		
		/* ********** create the print button ********** */
		printIReportMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.formtab.rightclickmenu.printIReport"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.PRINT));
		
		printIReportMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				print(PRINT_AS_IREPORT);
			}
		});
		addMenuItem(printIReportMenuItem);
		/* **************************************** */

		
		/* ********** create the print button ********** */
		printHtmlMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.formtab.rightclickmenu.printXsl"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.PRINT));
		
		printHtmlMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				print(PRINT_VIA_XSL);
			}
		});
		addMenuItem(printHtmlMenuItem);
		/* **************************************** */

		
		/* ********** create the print button ********** */
		editHtmlMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.formtab.rightclickmenu.editXsl"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.EDIT));
		
		editHtmlMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				edit();
			}
		});
		addMenuItem(editHtmlMenuItem);
		/* **************************************** */

		popupMenu.addSeparator();
		
		/* **********  create the change creation date button  ********** */
		changeCreationDateMenuItem = new JMenuItem(
				Translatrix.getTranslationString("formeditor.change_creation_date_title"),
				FormEditorModule.getMiniIcon("date.png"));
		changeCreationDateMenuItem.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				ChangeCreationDateDialog dialog = getChangeCreationDateDialog();
				dialog.openChangeCreationDialog(formModel);
			}
		});
		addMenuItem(changeCreationDateMenuItem);
		/* **************************************** */
		
		
		/* ********** define popup-menu ********** */
		this.popupMenu.setBackground(GECAMedColors.c_GECAMedBackground);
		this.popupMenu.setBorderPainted(true);
		/* **************************************** */
	}
	
	private void addMenuItem (JMenuItem item)
	{
		item.setContentAreaFilled(false);
		item.setBorderPainted(false);
		item.setOpaque(false);
		
		this.popupMenu.add(item);
	}
	
	private void showPopup (MouseEvent e)
	{
		Physician 	currentPhysician 		= MainFrame.getCurrentPhysician();
		List<?> 	editableTemplates 		= formModel.getTemplate().getEditableTemplates(currentPhysician);
		List<?> 	printableTemplates 		= formModel.getTemplate().getPrintableTemplates(currentPhysician);
		boolean 	handlerSet 				= FormDataConverter.getHandlerOption() != FormDataConverter.NO_HANDLER_OPTION;
		boolean 	modified 				= formModel.isModified();
		boolean 	editableTemplatesExist 	= editableTemplates != null && !editableTemplates.isEmpty();
		boolean 	printableTemplatesExist = printableTemplates != null && !printableTemplates.isEmpty();
		String 		printWithXslToolTip 	= null;
		String 		editWithXslToolTip 		= null;
		String 		iReportToolTip 			= null;
		
		deleteMenuItem.setEnabled(formModel.getForm().getIncidentEntry() != null);
		
		// I know, Nico wouldn't have done it that way ...
		if (modified)
			editWithXslToolTip = printWithXslToolTip = iReportToolTip = 
					Translatrix.getTranslationString("formeditor.formtab.rightclickmenu.saveFormBeforePrintingToolTip");
		else if (!handlerSet)
			editWithXslToolTip = printWithXslToolTip = 
					Translatrix.getTranslationString("formeditor.formtab.rightclickmenu.noHandlerSet");
		else 
		{
			if (!printableTemplatesExist)
				printWithXslToolTip = Translatrix.getTranslationString(
						"formeditor.formtab.rightclickmenu.noXslAvailableToolTip");
			
			if (!editableTemplatesExist)
				editWithXslToolTip = Translatrix.getTranslationString(
						"formeditor.formtab.rightclickmenu.noXslAvailableToolTip");
		}
		
		printIReportMenuItem.setEnabled( !modified);
		printHtmlMenuItem.setEnabled(	(!modified) && handlerSet && printableTemplatesExist);
		editHtmlMenuItem.setEnabled(	(!modified) && handlerSet && editableTemplatesExist );
		
		editHtmlMenuItem.setToolTipText(editWithXslToolTip);
		printHtmlMenuItem.setToolTipText(printWithXslToolTip);
		printIReportMenuItem.setToolTipText(iReportToolTip);
		
		popupMenu.show((Component)e.getSource(), e.getX(), e.getY());
	}
	
	/**
	 * If clicked on the tab with mouse-button 3, open the popup-menu
	 */
	public void mouseClicked(MouseEvent e) 
	{
		if (e.isPopupTrigger()) 
			showPopup(e);
	}
	
	public void mouseReleased(MouseEvent e) 
	{
		if (e.isPopupTrigger()) 
			showPopup(e);
	}
	
	/**
	 * If mouse pressed on the tab, set the form as selected
	 */
	public void mousePressed(MouseEvent e) 
	{
		tab.openForm(formModel);
		if (e.isPopupTrigger()) 
			showPopup(e);
	}
	
	public void mouseExited(MouseEvent e) { }
	public void mouseEntered(MouseEvent e) { }
	
	
	private ChangeCreationDateDialog getChangeCreationDateDialog () 
	{
		if (ccdDialog == null)
			ccdDialog = new ChangeCreationDateDialog(formModel.getPanel().getParent());
		
		return ccdDialog;
	}
	
	private void print (int printOption)
	{
		FormDataConverter converter;
		XSLTemplate xslTemplate;
		
		switch (printOption)
		{
		case PRINT_AS_IREPORT:
			
			FormPrinter printer = new FormPrinter(formModel);
			printer.print();
			break;

		case PRINT_VIA_XSL:
			
			xslTemplate = ChooseXslDialog.getXslTemplate(FormDataConverter.TYPE_PRINT, formModel.getTemplate());
			
			if (xslTemplate == null)
				return;
			
			try 
			{
				if (xslTemplate.getFileNameExtension() != null
						&& xslTemplate.getFileNameExtension().toLowerCase().equals("pdf"))
					 converter = FormDataConverter.createHandler(formModel, FormDataConverter.DESKTOP_HANDLER_OPTION);
				else converter = FormDataConverter.createHandler(formModel);
				
				converter.print(xslTemplate);
			}
			catch (UnsupportedFileTypeException ufte)
			{
				try 
				{
					if (FormDataConverter.getHandlerOption() == FormDataConverter.DESKTOP_HANDLER_OPTION
							|| !Desktop.getDesktop().isSupported(Desktop.Action.PRINT))
						throw ufte;
					else 
					{
						converter = FormDataConverter.createHandler(formModel, FormDataConverter.DESKTOP_HANDLER_OPTION);
						converter.print(xslTemplate);
					}
				}
				catch (Exception e)
				{
					logger.log(Level.ERROR, e.getMessage(), e);
					logger.log(Level.ERROR, "  Caused by: "+ufte.getMessage(), ufte);
				}
			}
			break;
		}
	}
	
	private void edit ()
	{
		FormDataConverter 	converter = null;
		XSLTemplate 		xslTemplate = ChooseXslDialog.getXslTemplate(
				FormDataConverter.TYPE_EDIT, formModel.getTemplate());
		
		if (xslTemplate == null)
			return;
		
		try 
		{
			if (xslTemplate.getFileNameExtension() != null
					&& xslTemplate.getFileNameExtension().toLowerCase().equals("pdf"))
			{
				/* you cannot edit a PDF and it would not make any sense to edit or open it in Word or OOWriter. 
				 * So open it, using the desktop API.
				 */
				converter = FormDataConverter.createHandler(formModel, FormDataConverter.DESKTOP_HANDLER_OPTION);
				converter.open(xslTemplate);
			}
			else 
			{
				converter = FormDataConverter.createHandler(formModel);
				converter.edit(xslTemplate);
			}
		}
		catch (Exception e)
		{
			if (converter == null)
				converter = FormDataConverter.createHandler(formModel);
			
			try 
			{
				converter.open(xslTemplate);
				logger.log(Level.WARN, 
						"Not able to edit the file " + 
						xslTemplate.getName() + 
						". Trying to open it.n" + 
						e.getMessage());
			}
			catch (Exception e2)
			{
				logger.log(Level.ERROR, "Failed to edit and to open the file.\n" + e2.getMessage(), e2);
				logger.log(Level.ERROR, "  Caused by: " + e.getMessage(), e);
			}
		}
//		}
//		catch (UnsupportedFileTypeException ufte)
//		{
//			if (FormHtmlConverter.getHandlerOption() == FormHtmlConverter.DESKTOP_HANDLER_OPTION
//					|| (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)
//					&& !Desktop.getDesktop().isSupported(Desktop.Action.EDIT)))
//				throw ufte;
//			else 
//			{
//				converter = FormHtmlConverter.createHandler(formModel, FormHtmlConverter.DESKTOP_HANDLER_OPTION);
//				try 
//				{
//					converter.edit(xslTemplate);
//				}
//				catch (Exception ioe)
//				{
//					try 
//					{
//						converter.open(xslTemplate);
//					}
//					catch (Exception e)
//					{
//						logger.log(Level.ERROR, "Failed to edit and to open the file.\n"+e.getMessage(), e);
//						logger.log(Level.ERROR, "  Caused by: "+ufte.getMessage(), ufte);
//					}
//				}
//			}
//		}
	}
}
