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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Vector;

import javax.naming.InitialContext;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.undo.UndoManager;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.log.Log;
import lu.tudor.santec.gecamed.core.ejb.entity.beans.log.LogType;
import lu.tudor.santec.gecamed.core.ejb.session.beans.LogManagerBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.LogManager;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.GECAMedTab;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.core.gui.utils.TableSorter;
import lu.tudor.santec.gecamed.core.gui.utils.UndoTextArea;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.usermanagement.gui.AdminModule;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.widgets.gui.ButtonFactory;

import org.antlr.analysis.DFA;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.toedter.calendar.JDateChooser;

/**
 * JPanel that shows all system internall log messages with 
 * the ability to filter and sort the messages by user, date etc..
 * 
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: LogManagementPanel.java,v $
 * <br>Revision 1.27  2013-12-27 18:09:27  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.26  2013-07-15 06:18:39  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.25  2013-02-22 08:46:50  kutscheid
 * <br>remove the tupel classes (please redeploy)
 * <br>
 * <br>Revision 1.24  2012-05-25 13:39:40  ferring
 * <br>corrected the width of the duration column
 * <br>
 * <br>Revision 1.23  2012-05-25 12:04:24  ferring
 * <br>Filters of logging overview updated
 * <br>
 * <br>Revision 1.22  2010-05-12 08:59:10  hermen
 * <br>small bugfixes
 * <br>
 * <br>Revision 1.21  2010-04-21 09:41:59  hermen
 * <br>small bugfixes
 * <br>
 * <br>Revision 1.20  2010-04-08 10:56:40  hermen
 * <br>enhanced logging
 * <br>
 * <br>Revision 1.19  2010-04-06 15:37:05  hermen
 * <br>changed column width
 * <br>
 * <br>Revision 1.18  2010-03-12 14:39:56  hermen
 * <br>cleanup of panel layouts and icons
 * <br>
 * <br>Revision 1.17  2010-03-12 14:17:42  hermen
 * <br>cleanup of panel layouts and icons
 * <br>
 * <br>Revision 1.16  2009-05-29 09:15:25  hermen
 * <br>added export to log view
 * <br>
 * <br>Revision 1.15  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.14  2008-04-07 13:10:36  hermen
 * <br>added Mainframe.addAdminTab to allow modules to add their own tabs to the admin module.
 * <br>
 * <br>Revision 1.13  2008-01-15 10:18:39  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 * <br>Revision 1.12  2007-11-20 08:58:54  hermen
 * <br>moved Managerfactory to core.utils and refactured code to use ManagerFactory instead of context.lookup
 * <br>
 * <br>Revision 1.11  2007/06/19 11:28:04  hermen
 * <br>added logging
 * <br>
 * <br>Revision 1.10  2007/03/02 08:28:38  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.8.2.2  2007/02/21 10:00:40  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.8.2.1  2006/12/06 08:45:29  heinemann
 * <br>protected -> public
 * <br>
 * <br>Revision 1.8  2006/12/01 14:54:25  heinemann
 * <br>column width (2) -> 115
 * <br>
 * <br>Revision 1.7  2006/11/22 13:01:28  heinemann
 * <br>you shouldn't do that, stefan ;-)
 * <br>
 * <br>Revision 1.6  2006/11/22 08:36:27  heinemann
 * <br>fixed problem with renderer and table sorting
 * <br>
 * <br>Revision 1.5  2006/11/07 08:12:16  heinemann
 * <br>great improvement of the search, yeah,
 * <br>feel free to search all over the world
 * <br>
 * <br>Revision 1.4  2006/10/25 11:17:44  heinemann
 * <br>improved logging
 * <br>
 * <br>Revision 1.3  2006/10/24 14:27:09  hermen
 * <br>set Hotkey to F5
 * <br>
 * <br>Revision 1.2  2006/10/24 12:47:30  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1  2006/10/24 09:24:54  heinemann
 * <br>New Methods, Beans, etc for the logging
 * <br>
 */
public class LogManagementPanel extends GECAMedTab implements ActionListener, PropertyChangeListener {

	private static final long serialVersionUID = 1L;
	
	private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
	
	private LogTableModel logTableModel;
	private JPanel filterPanel;
	private JComboBox typeBox;
	private JTextField hostField;
	private JTextField msgField;
	private JTextField operationField;
	private JTextField moduleField;
	private JTextField userField;
	private JDateChooser fromDateField;
	private JLabel filterLabel;
	private JFileChooser fileChooser = new JFileChooser();

	private static LogManagementPanel logManagementPanel;

	private static Logger logger = Logger.getLogger(LogManagementPanel.class.getName());
	
	private static CellConstraints cc = new CellConstraints();
	
	Vector<JTextField> textFields = new Vector<JTextField>();
	private UndoTextArea previewTextArea;
	private JPopupMenu previewPop;
	private JTable logTable;
	private JButton refreshButton;
	private JButton exportButton;
	private JDateChooser toDateField;

	/**
	 *
	 */
	public LogManagementPanel() {
		/* ====================================================== */

    	this.setIcon(IconFetcher.getIcon(GECAMedModule.class, GECAMedIconNames.LOG));

    	logManagementPanel = this;

    	buildPanel();

    	relocalize();
		/* ====================================================== */
	}



	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.core.gui.GECAMedTab#preparetoShowup()
	 */
	@Override
	public void preparetoShowup() {
		/* ============================================= */
		refreshList();
		/* ============================================= */
	}



	private void buildPanel() {
		/* ============================================= */
		// create a formlayout
		this.setLayout(new FormLayout(
						// cols
						"3dlu," +
						"fill:pref:grow," +
						"3dlu",
						// rows
						"3dlu," +
						"fill:pref," +
						"3dlu," +
						"fill:pref," +
						"1dlu," +
						"fill:pref:grow," +
						"3dlu"
			));
		CellConstraints cc = new CellConstraints();
		/* ------------------------------------------------------ */
		// tupels for the position of the components
		// the button panel
//		Tupel<Integer> buttonPos = new Tupel<Integer>(2, 4);
		// filter panel
		int[] filterPos = new int[] {2, 2};
		// the log table
		int[] tablePos = new int[] {2, 6};
		/* ------------------------------------------------------ */
		// add a Label to display some introduction text
		/* ------------------------------------------------------ */
		// create the table
		this.logTable = new JTable();
//		logTable.setColumnControlVisible(true);


		// a table model
		this.logTableModel = new LogTableModel();
		TableSorter sorter = new TableSorter(logTableModel);

		logTable.setModel(sorter);

		sorter.setTableHeader(logTable.getTableHeader());

		logTable.setShowVerticalLines(false);
		logTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		logTable.setDefaultRenderer(Object.class, new LogTableRenderer());
		logTable.setDefaultRenderer(Long.class, new LogTableRenderer());
		
		// configure the width
		logTable.getColumnModel().getColumn(0).setMinWidth(75);
		logTable.getColumnModel().getColumn(0).setMaxWidth(75);
		
//		logTable.getColumnModel().getColumn(1).setMinWidth(200);
		logTable.getColumnModel().getColumn(1).setMaxWidth(150);
		logTable.getColumnModel().getColumn(1).setWidth(150);
		logTable.getColumnModel().getColumn(1).setPreferredWidth(150);
		
//		logTable.getColumnModel().getColumn(2).setMinWidth(85);
		logTable.getColumnModel().getColumn(2).setMaxWidth(130);
		logTable.getColumnModel().getColumn(2).setWidth(100);
		logTable.getColumnModel().getColumn(2).setPreferredWidth(100);
		
//		logTable.getColumnModel().getColumn(3).setMinWidth(75);
//		logTable.getColumnModel().getColumn(3).setMaxWidth(75);
		logTable.getColumnModel().getColumn(3).setWidth(50);
		logTable.getColumnModel().getColumn(3).setPreferredWidth(50);
		
//		logTable.getColumnModel().getColumn(4).setMinWidth(120);
//		logTable.getColumnModel().getColumn(4).setMaxWidth(120);
		logTable.getColumnModel().getColumn(4).setWidth(75);
		logTable.getColumnModel().getColumn(4).setPreferredWidth(75);
		
		logTable.getColumnModel().getColumn(5).setMinWidth(300);
		logTable.getColumnModel().getColumn(5).setWidth(300);
		logTable.getColumnModel().getColumn(5).setPreferredWidth(300);
		
//		logTable.getColumnModel().getColumn(6).setMaxWidth(250);
		logTable.getColumnModel().getColumn(6).setWidth(100);
		logTable.getColumnModel().getColumn(6).setPreferredWidth(100);
		
//		logTable.getColumnModel().getColumn(7).setMaxWidth(100);
		logTable.getColumnModel().getColumn(7).setWidth(60);
		logTable.getColumnModel().getColumn(7).setPreferredWidth(60);
		
		logTable.getColumnModel().getColumn(8).setMaxWidth(80);
		logTable.getColumnModel().getColumn(8).setWidth(60);
		logTable.getColumnModel().getColumn(8).setPreferredWidth(60);
		
		logTable.getTableHeader().setReorderingAllowed(false);

		JScrollPane scroll = new JScrollPane(logTable);

		// add to the panel
		this.add(scroll, cc.xy(tablePos[0], tablePos[1]));
		/* ------------------------------------------------------ */
		this.setOpaque(false);
		
		
		/* ------------------------------------------------------ */
		/* ------------------------------------------------------ */
		
		
		// JLabel
		this.filterLabel = new JLabel();
		filterLabel.setIcon(GECAMedModule.getMediumIcon(GECAMedIconNames.FILTER));

		filterLabel.setVerticalTextPosition(JLabel.CENTER);
		filterLabel.setHorizontalTextPosition(JLabel.RIGHT);
		filterLabel.setBackground(Color.WHITE);
		filterLabel.setOpaque(false);



		// the button panel
		JPanel bb = new JPanel(new FormLayout("pref:grow, 3dlu, pref, 3dlu, pref","pref"));

		this.exportButton = ButtonFactory.createNarrowButton(GECAMedModule.getIcon(GECAMedIconNames.EXPORT));
		this.exportButton.setToolTipText(Translatrix.getTranslationString("admin.logmanagement.export"));
		this.exportButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				/* ====================================================== */
			    	exportCSV();
				/* ====================================================== */
			}
		});
		bb.add(exportButton, cc.xy(3,1));

		
		this.refreshButton = ButtonFactory.createNarrowButton(GECAMedModule.getIcon(GECAMedIconNames.RELOAD));
		this.refreshButton.setToolTipText(Translatrix.getTranslationString("admin.logmanagement.refresh"));
		this.refreshButton.addActionListener(new ActionListener() {
		    public void actionPerformed(ActionEvent e) {
			/* ====================================================== */
			// reload the list
			refreshList();
			/* ====================================================== */
		    }
		});
		bb.add(refreshButton, cc.xy(5,1));
		/* ------------------------------------------------------ */
		bb.setOpaque(false);

		/* ------------------------------------------------------ */
		// init filterPanel
		initFilterPanel();
		/* ------------------------------------------------------ */
		filterPanel.add(filterLabel, cc.xyw(2, 2, 4));
		filterPanel.add(bb, cc.xyw(14, 2,3));
		filterPanel.setOpaque(false);
		/* ------------------------------------------------------ */
		this.add(filterPanel, cc.xy(filterPos[0], filterPos[1]));

		/* ------------------------------------------------------- */
		// preview
		initPreview();
		// add mouselistener
		logTable.addMouseListener(new MouseAdapter() {

			/* (non-Javadoc)
			 * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
			 */
			@Override
			public void mousePressed(MouseEvent e) {
				/* ====================================================== */
				if (logTable.getSelectedColumn() == 5)
					showPreview(logTableModel.getLogByRow(logTable.getSelectedRow()), e);
				/* ====================================================== */
			}

		});
		/* ------------------------------------------------------- */

		/* ------------------------------------------------------ */
		// fill the combobox
		typeBox.addItem(new LogType(""));
		try {
			InitialContext ctx = new InitialContext();
			LogManager logManager = (LogManager) ManagerFactory.getRemote(LogManagerBean.class);

			for (LogType t : logManager.getLogTypes())
				typeBox.addItem(t);

			ctx.close();
		} catch (Exception e1) {
			/* ------------------------------------------------------ */
			logger.log(Level.WARN, "fetching logs failed", e1);
			/* ------------------------------------------------------ */
		}


		/* ============================================= */
	}

	private void initFilterPanel() {
		/* ====================================================== */
		/* ------------------------------------------------------ */
		// Filter panel
		filterPanel = new JPanel(new FormLayout(
					// cols
					"0px," +
					"fill:71px," +
					"2px," +
					"fill:94px," +
					"2px," +
					"fill:94px," +
					"2px," +
					"fill:83px," +
					"2px," +
					"fill:73px," +
					"2px," +
					"fill:118px," +
					"2px," +
					"fill:pref:grow," +
					"2px," +
					"fill:178px," +
					"5dlu",
					// rows
					"3dlu," +
					"fill:pref," +
					"1dlu," +
					"fill:pref," +
					"1dlu," +
					"fill:pref," +
					"1dlu"));

		/* ------------------------------------------------------ */
		// design
		filterPanel.setBackground(Color.WHITE);
		// border
		filterPanel.setBorder(new TitledBorder(""));

		/* ------------------------------------------------------ */
		/* ------------------------------------------------------ */


		// create the textfields for the filters
		this.typeBox = new JComboBox();
		typeBox.addActionListener(this);
		/* ------------------------------------------------------ */
		this.fromDateField = GECAMedGuiUtils.getDateChooser(false);
		fromDateField.addPropertyChangeListener(this);
		/* ------------------------------------------------------ */
		this.toDateField = GECAMedGuiUtils.getDateChooser(false);
		toDateField.addPropertyChangeListener(this);
		/* ------------------------------------------------------ */
		this.userField = new JTextField();
		userField.setName("o.userName");
		userField.addActionListener(this);
		textFields.add(userField);
		/* ------------------------------------------------------ */
		this.moduleField = new JTextField();
		moduleField.setName("o.module");
		moduleField.addActionListener(this);
		textFields.add(moduleField);
		/* ------------------------------------------------------ */
		this.operationField = new JTextField();
		operationField.setName("o.operation");
		operationField.addActionListener(this);
		textFields.add(operationField);
		/* ------------------------------------------------------ */
		this.msgField = new JTextField();
		msgField.setName("o.text");
		msgField.addActionListener(this);
		textFields.add(msgField);
		/* ------------------------------------------------------ */
		this.hostField = new JTextField();
		hostField.setName("o.host");
		hostField.addActionListener(this);
		textFields.add(hostField);
		/* ------------------------------------------------------ */
		filterPanel.add(typeBox,		cc.xy(2, 6));
		filterPanel.add(fromDateField,	cc.xy(4, 6));
		filterPanel.add(toDateField,	cc.xy(6, 6));
		filterPanel.add(userField,		cc.xy(8, 6));
		filterPanel.add(moduleField,	cc.xy(10, 6));
		filterPanel.add(operationField,	cc.xy(12, 6));
		filterPanel.add(msgField,		cc.xy(14, 6));
		filterPanel.add(hostField,		cc.xy(16, 6));
		
		// add the description to the filters
		addFilterDescription("admin.logmanagement.table.type",		 2);
		addFilterDescription("admin.logmanagement.fromDate",		 4);
		addFilterDescription("admin.logmanagement.toDate",			 6);
		addFilterDescription("admin.logmanagement.table.user",		 8);
		addFilterDescription("admin.logmanagement.table.module",	10);
		addFilterDescription("admin.logmanagement.table.operation",	12);
		addFilterDescription("admin.logmanagement.table.text",		14);
		addFilterDescription("admin.logmanagement.table.host",		16);
		
		/* ====================================================== */
	}
	
	
	private void addFilterDescription(String translationKey, int col)
	{
		JLabel description	= new JLabel(Translatrix.getTranslationString(translationKey));
		filterPanel.add(description,	cc.xy(col, 4));
	}
	
	
	private void exportCSV()
	{
		File f = showExportDialog("GECAMED_Log_export_"+df.format(new Date())+".csv");
		if (f != null)
		{
			try
			{
				lu.tudor.santec.gecamed.core.utils.ExportToCSV cvsExporter = new lu.tudor.santec.gecamed.core.utils.ExportToCSV(f);
				cvsExporter.println(this.logTableModel.getColumns());
				Vector<String[]> data = this.logTableModel.getData();
				for (String[] strings : data)
				{
					cvsExporter.println(strings);
				}
				cvsExporter.close();
			}
			catch (Exception e1)
			{
				e1.printStackTrace();
			}
		}
	}
	
	
	private File showExportDialog(String fileName)
	{
		fileChooser.setMultiSelectionEnabled(false);
		fileChooser.setSelectedFile(new File(fileName));
		
		if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
		{
			return fileChooser.getSelectedFile();
		}
		return null;
	}
	
	
	/**
	 * Refresh the list
	 */
	public void refreshList()
	{
		Thread t = new Thread()
		{
			public void run()
			{
				StringBuffer	filter		= new StringBuffer();
				boolean			isFirst		= true;
				Date			toDate		= null;
				Date			fromDate	= null;
				
				// check the type
				if (typeBox.getSelectedItem() != null 
						&& ((LogType) typeBox.getSelectedItem()).getId() != null)
				{
					filter.append(" WHERE o.typeId = " + ((LogType) typeBox.getSelectedItem()).getId());
					isFirst = false;
				}
				
				// check the text fields
				for (JTextField t : textFields)
				{
					if (!"".equals(t.getText()))
					{
						if (isFirst)
						{
							filter.append(" WHERE");
							isFirst = false;
						}
						else
							filter.append(" AND");
						
						filter.append(" UPPER(" + t.getName() + ") LIKE UPPER('%" + t.getText() + "%')");
					}
				}
				
				// check the dates
				if (fromDateField.getDate() != null)
				{
//					Date toDate = dateField.getDate().
					Calendar cal = new GregorianCalendar();
					cal.setTime(fromDateField.getDate());
					cal.set(Calendar.HOUR_OF_DAY, 0);
					cal.set(Calendar.MINUTE, 0);
					cal.set(Calendar.SECOND, 0);
					cal.set(Calendar.MILLISECOND, 0);
					
					fromDate = cal.getTime();
//					System.out.println("From: " + fromDate);
					if (toDateField.getDate() == null)
					{
						cal.roll(Calendar.DATE, true);
						toDate = cal.getTime();
//					    System.out.println("To: "+ toDate);
					}
				}
				if (fromDate != null)
				{
					if (isFirst)
						filter.append(" WHERE ");
					else
						filter.append(" AND");
					filter.append(" o.time >= :fromDate");
					isFirst = false;
				}
				
				if (toDateField.getDate() != null)
				{
					Calendar cal = new GregorianCalendar();
					cal.setTime(toDateField.getDate());
					cal.set(Calendar.HOUR_OF_DAY, 0);
					cal.set(Calendar.MINUTE, 0);
					cal.set(Calendar.SECOND, 0);
					cal.add(Calendar.DAY_OF_YEAR, 1);
					toDate = cal.getTime();
//					System.out.println("To: "+ toDate);
				}
				if (toDate != null)
				{
					if (isFirst)
						filter.append(" WHERE ");
					else
						filter.append(" AND");
					filter.append(" o.time < :toDate");
					isFirst = false;
				}
				
				MainFrame.getInstance().setWaitCursor(true);
				
				// get the data out of the DB
				try
				{
					LogManager logManager = (LogManager) ManagerFactory.getRemote(LogManagerBean.class);
					logTableModel.setData(logManager.getLogs(null, 5000, fromDate, toDate, filter.toString()));
				}
				catch (Exception e1)
				{
					logger.log(Level.WARN, "fetching logs failed", e1);
				}
				
				MainFrame.getInstance().setWaitCursor(false);
			}
		};
		t.start();
	}


	/**
	 * Returns the instance of the log panel
	 *
	 * @return
	 */
	public static LogManagementPanel getInstance() {
		/* ====================================================== */
		return logManagementPanel;
		/* ====================================================== */
	}




	/* ****************************************************************
	 * ****************************************************************
	 * Template preview
	 */
	/**
	 * The preview is a window containing a textcomponent displaying the
	 * content of this prescription template.
	 * It is opened with a single click on thetemplate in the JTable
	 * We will use a timer to delay to delay the window in order to
	 * click an other template, for usability reasons.
	 *
	 * Window closes by click, esc, enter, focus lost
	 * @param temp
	 */
	public void showPreview(Log log, MouseEvent e) {
		/* ====================================================== */
		if (previewPop != null && previewPop.isVisible()) {
			previewPop.setVisible(false);
			e.consume();
			return;
		}

		if (log == null)
			return;
		/* ------------------------------------------------------ */

//		if (Prescription Type.MEDICINE.equals(
//				EditorModel.getStringForTypeId(temp.getPrescriptionTypeId()))) {
//					/* ------------------------------------------------------ */
//					// Construct the drugs with the posology
//					if (temp.getTemplateDrugs() != null) {
//						/* ------------------------------------------------------ */
//						StringBuffer sBuff = new StringBuffer();
//						for(TemplateDrug d : temp.getTemplateDrugs()) {
//							sBuff.append(d.getName());
//							sBuff.append("\n");
//							sBuff.append((d.getPosology() != null && !"".equals(d.getPosology())
//											? d.getPosology()+"\n\n" : "\n\n"));
//						}
//						this.previewTextArea.setText(sBuff.toString());
//						/* ------------------------------------------------------ */
//					}
//					/* ------------------------------------------------------ */
//				}
//		else
			this.previewTextArea.setText(log.getText());
		previewPop.show(this.logTable, e.getX(), e.getY());//this.previewTextArea.getWidth()+15, 1);

		/* ====================================================== */
	}

	public void hidePreview() {
		/* ====================================================== */
		previewPop.setVisible(false);
		/* ====================================================== */
	}


	/**
	 * Init the template preview
	 */
	private void initPreview() {
		/* ====================================================== */
		this.previewTextArea = new UndoTextArea(new UndoManager());
		this.previewTextArea.setLineWrap(true);
		this.previewTextArea.setWrapStyleWord(true);
//		this.textTextArea.getDocument().addDocumentListener(this);

		this.previewTextArea.setEditable(false);
		this.previewTextArea.setFocusable(false);

		/* ------------------------------------------------------ */
		JScrollPane tScroll = new JScrollPane(previewTextArea);
		tScroll.setVerticalScrollBarPolicy(
				ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		/* ------------------------------------------------------ */

		this.previewPop = new JPopupMenu();

		previewPop.setLayout(new BorderLayout());

		previewPop.add(tScroll);
		previewPop.setPreferredSize(new Dimension(400, 300));

		previewPop.add(new JLabel("QuickPreview "), BorderLayout.NORTH);
		previewPop.setBorder(new LineBorder(Color.BLACK));


		previewPop.addKeyListener(new KeyAdapter() {

			/* (non-Javadoc)
			 * @see java.awt.event.KeyAdapter#keyPressed(java.awt.event.KeyEvent)
			 */
			@Override
			public void keyPressed(KeyEvent e) {
				/* ============================================= */
				previewPop.setVisible(false);
				e.consume();
				/* ============================================= */
			}

		});

		previewTextArea.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				/* ============================================= */
				previewPop.setVisible(false);
				e.consume();
				/* ============================================= */
			}
		});
		previewTextArea.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				/* ============================================= */
				previewPop.setVisible(false);
				e.consume();
				/* ============================================= */
			}
		});

		previewPop.pack();
		/* ====================================================== */
	}








	/* *************************************************************************** */
	/*                   The table model for the LogTable                          */
	/* --------------------------------------------------------------------------- */


	/**
	 * @author martin.heinemann@tudor.lu
	 *
	 *
	 * @version
	 * <br>$Log: LogManagementPanel.java,v $
	 * <br>Revision 1.27  2013-12-27 18:09:27  donak
	 * <br>Cleanup of imports
	 * <br>
	 * <br>Revision 1.26  2013-07-15 06:18:39  ferring
	 * <br>logging changed
	 * <br>
	 * <br>Revision 1.25  2013-02-22 08:46:50  kutscheid
	 * <br>remove the tupel classes (please redeploy)
	 * <br>
	 * <br>Revision 1.24  2012-05-25 13:39:40  ferring
	 * <br>corrected the width of the duration column
	 * <br>
	 * <br>Revision 1.23  2012-05-25 12:04:24  ferring
	 * <br>Filters of logging overview updated
	 * <br>
	 * <br>Revision 1.22  2010-05-12 08:59:10  hermen
	 * <br>small bugfixes
	 * <br>
	 * <br>Revision 1.21  2010-04-21 09:41:59  hermen
	 * <br>small bugfixes
	 * <br>
	 * <br>Revision 1.20  2010-04-08 10:56:40  hermen
	 * <br>enhanced logging
	 * <br>
	 * <br>Revision 1.19  2010-04-06 15:37:05  hermen
	 * <br>changed column width
	 * <br>
	 * <br>Revision 1.18  2010-03-12 14:39:56  hermen
	 * <br>cleanup of panel layouts and icons
	 * <br>
	 * <br>Revision 1.17  2010-03-12 14:17:42  hermen
	 * <br>cleanup of panel layouts and icons
	 * <br>
	 * <br>Revision 1.16  2009-05-29 09:15:25  hermen
	 * <br>added export to log view
	 * <br>
	 * <br>Revision 1.15  2008-09-25 09:43:10  heinemann
	 * <br>fixed copyrights
	 * <br>
	 * <br>Revision 1.14  2008-04-07 13:10:36  hermen
	 * <br>added Mainframe.addAdminTab to allow modules to add their own tabs to the admin module.
	 * <br>
	 * <br>Revision 1.13  2008-01-15 10:18:39  hermen
	 * <br>updated Javadoc and refactured code
	 * <br>
	 * <br>Revision 1.12  2007-11-20 08:58:54  hermen
	 * <br>moved Managerfactory to core.utils and refactured code to use ManagerFactory instead of context.lookup
	 * <br>
	 * <br>Revision 1.11  2007/06/19 11:28:04  hermen
	 * <br>added logging
	 * <br>
	 * <br>Revision 1.10  2007/03/02 08:28:38  hermen
	 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
	 * <br>
	 * <br>Revision 1.8.2.2  2007/02/21 10:00:40  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.8.2.1  2006/12/06 08:45:29  heinemann
	 * <br>protected -> public
	 * <br>
	 * <br>Revision 1.8  2006/12/01 14:54:25  heinemann
	 * <br>column width (2) -> 115
	 * <br>
	 * <br>Revision 1.7  2006/11/22 13:01:28  heinemann
	 * <br>you shouldn't do that, stefan ;-)
	 * <br>
	 * <br>Revision 1.6  2006/11/22 08:36:27  heinemann
	 * <br>fixed problem with renderer and table sorting
	 * <br>
	 * <br>Revision 1.5  2006/11/07 08:12:16  heinemann
	 * <br>great improvement of the search, yeah,
	 * <br>feel free to search all over the world
	 * <br>
	 * <br>Revision 1.4  2006/10/25 11:17:44  heinemann
	 * <br>improved logging
	 * <br>
	 * <br>Revision 1.3  2006/10/24 14:27:09  hermen
	 * <br>set Hotkey to F5
	 * <br>
	 * <br>Revision 1.2  2006/10/24 12:47:30  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.1  2006/10/24 09:24:54  heinemann
	 * <br>New Methods, Beans, etc for the logging
	 * <br>
	 */
	class LogTableModel extends AbstractTableModel {
	    
		private static final long serialVersionUID = 1L;

		private String[] columns = {
			Translatrix.getTranslationString("admin.logmanagement.table.type"),
			Translatrix.getTranslationString("admin.logmanagement.table.date"),
			Translatrix.getTranslationString("admin.logmanagement.table.user"),
			Translatrix.getTranslationString("admin.logmanagement.table.module"),
			Translatrix.getTranslationString("admin.logmanagement.table.operation"),
			Translatrix.getTranslationString("admin.logmanagement.table.text"),
			Translatrix.getTranslationString("admin.logmanagement.table.host"),
			Translatrix.getTranslationString("admin.logmanagement.table.site"),
			Translatrix.getTranslationString("admin.logmanagement.table.duration")
		};
		
		private Class<?>[] columnClasses = {
			String.class,
			String.class,
			String.class,
			String.class,
			String.class,
			String.class,
			String.class,
			String.class,
			Long.class
		};

		/* ********************************************************************** */
		/*                Class Members                                           */

		private ArrayList<Log> logList;

		/*                 End of Class Members                                   */
		/* ********************************************************************** */

		/**
		 * default constructor
		 */
		public LogTableModel() {
			/* ====================================================== */
			// init the list
			logList = new ArrayList<Log>();
			/* ====================================================== */
		}

		public Vector<String[]> getData() {
		    Vector<String[]> data = new Vector<String[]>();
		    for (Log log : logList) {
			data.add(log.toStringArr());
		    }
		    return data;
		}

		public Object[] getColumns() {
		    return columns;
		}

		/**
		 * Set the data for the table model
		 *
		 * @param logs
		 */
		public void setData(List<Log> logs) {
			/* ====================================================== */
			this.logList = new ArrayList<Log>(logs);
			fireTableDataChanged();
			/* ====================================================== */
		}


		/* *********************************************************************** */

		/* (non-Javadoc)
		 * @see javax.swing.table.AbstractTableModel#getColumnName(int)
		 */
		@Override
		public String getColumnName(int column) {
			/* ============================================= */
			return columns[column];
			/* ============================================= */
		}
		
		@Override
		public Class<?> getColumnClass(int column) {
			/* ============================================= */
			return columnClasses[column];
			/* ============================================= */
		}

		public int getColumnCount() {
			/* ============================================= */
			return columns.length;
			/* ============================================= */
		}

		public int getRowCount() {
			/* ============================================= */
			return logList.size();
			/* ============================================= */
		}

		public Object getValueAt(int rowIndex, int columnIndex) {
			/* ============================================= */
			try {
				Log log = logList.get(rowIndex);
				switch (columnIndex) {
					case 0 : return log.getTypeId();
					case 1 : return log.getTime();
					case 2 : return log.getUserName();
					case 3 : return log.getModule();
					case 4 : return log.getOperation();
					case 5 : return log.getText();
					case 6 : return log.getHost();
					case 7 : return log.getSite();
					case 8 : return log.getDuration();

					default : return null;
				}
			} catch (Exception e) {
				return null;
			}
			/* ============================================= */
		}


		public Log getLogByRow(int row) {
			/* ================================================== */
			if (row > -1 && row < getRowCount())
				return logList.get(row);
			else
				return null;
			/* ================================================== */
		}

	}

	/**
	 * Set the translation strings
	 */
	public void relocalize() {
		/* ====================================================== */
		this.setTitle(Translatrix.getTranslationString("admin.logmanagement"));
		this.filterLabel.setText(Translatrix.getTranslationString("admin.logmanagement.filter"));
		/* ====================================================== */
	}



	/**
	 * Table renderer for the log table
	 *
	 * @author martin.heinemann@tudor.lu
	 *
	 *
	 * @version
	 * <br>$Log: LogManagementPanel.java,v $
	 * <br>Revision 1.27  2013-12-27 18:09:27  donak
	 * <br>Cleanup of imports
	 * <br>
	 * <br>Revision 1.26  2013-07-15 06:18:39  ferring
	 * <br>logging changed
	 * <br>
	 * <br>Revision 1.25  2013-02-22 08:46:50  kutscheid
	 * <br>remove the tupel classes (please redeploy)
	 * <br>
	 * <br>Revision 1.24  2012-05-25 13:39:40  ferring
	 * <br>corrected the width of the duration column
	 * <br>
	 * <br>Revision 1.23  2012-05-25 12:04:24  ferring
	 * <br>Filters of logging overview updated
	 * <br>
	 * <br>Revision 1.22  2010-05-12 08:59:10  hermen
	 * <br>small bugfixes
	 * <br>
	 * <br>Revision 1.21  2010-04-21 09:41:59  hermen
	 * <br>small bugfixes
	 * <br>
	 * <br>Revision 1.20  2010-04-08 10:56:40  hermen
	 * <br>enhanced logging
	 * <br>
	 * <br>Revision 1.19  2010-04-06 15:37:05  hermen
	 * <br>changed column width
	 * <br>
	 * <br>Revision 1.18  2010-03-12 14:39:56  hermen
	 * <br>cleanup of panel layouts and icons
	 * <br>
	 * <br>Revision 1.17  2010-03-12 14:17:42  hermen
	 * <br>cleanup of panel layouts and icons
	 * <br>
	 * <br>Revision 1.16  2009-05-29 09:15:25  hermen
	 * <br>added export to log view
	 * <br>
	 * <br>Revision 1.15  2008-09-25 09:43:10  heinemann
	 * <br>fixed copyrights
	 * <br>
	 * <br>Revision 1.14  2008-04-07 13:10:36  hermen
	 * <br>added Mainframe.addAdminTab to allow modules to add their own tabs to the admin module.
	 * <br>
	 * <br>Revision 1.13  2008-01-15 10:18:39  hermen
	 * <br>updated Javadoc and refactured code
	 * <br>
	 * <br>Revision 1.12  2007-11-20 08:58:54  hermen
	 * <br>moved Managerfactory to core.utils and refactured code to use ManagerFactory instead of context.lookup
	 * <br>
	 * <br>Revision 1.11  2007/06/19 11:28:04  hermen
	 * <br>added logging
	 * <br>
	 * <br>Revision 1.10  2007/03/02 08:28:38  hermen
	 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
	 * <br>
	 * <br>Revision 1.8.2.2  2007/02/21 10:00:40  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.8.2.1  2006/12/06 08:45:29  heinemann
	 * <br>protected -> public
	 * <br>
	 * <br>Revision 1.8  2006/12/01 14:54:25  heinemann
	 * <br>column width (2) -> 115
	 * <br>
	 * <br>Revision 1.7  2006/11/22 13:01:28  heinemann
	 * <br>you shouldn't do that, stefan ;-)
	 * <br>
	 * <br>Revision 1.6  2006/11/22 08:36:27  heinemann
	 * <br>fixed problem with renderer and table sorting
	 * <br>
	 * <br>Revision 1.5  2006/11/07 08:12:16  heinemann
	 * <br>great improvement of the search, yeah,
	 * <br>feel free to search all over the world
	 * <br>
	 * <br>Revision 1.4  2006/10/25 11:17:44  heinemann
	 * <br>improved logging
	 * <br>
	 * <br>Revision 1.3  2006/10/24 14:27:09  hermen
	 * <br>set Hotkey to F5
	 * <br>
	 * <br>Revision 1.2  2006/10/24 12:47:30  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.1  2006/10/24 09:24:54  heinemann
	 * <br>New Methods, Beans, etc for the logging
	 * <br>
	 */
	class LogTableRenderer extends DefaultTableCellRenderer {

		private static final long serialVersionUID = 1L;
		private DateFormat formater;

		private Color systemColor = new Color(255, 244, 202);
		private Color errorColor = new Color(255, 221, 221);
		private Color adminColor = new Color(221, 255, 221);
		private Color userColor = new Color(221, 221, 255);


		public LogTableRenderer()  {
			/* ====================================================== */
			this.formater = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
//			this.setOpaque(false);

			this.setHorizontalAlignment(JLabel.LEFT);
			/* ====================================================== */
		}

		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
			/* ====================================================== */

//			 set the background
			int type = -1;
			try {
				type = (Integer) table.getModel().getValueAt(row, 0);
			} catch (Exception e) {
			}
			switch (type) {
				case LogType.SYSTEM : {
					this.setBackground(systemColor);
					break;
				}
				case LogType.ERROR : {
					this.setBackground(errorColor);
					break;
				}
				case LogType.ADMIN : {
					this.setBackground(adminColor);
					break;
				}
				case LogType.USER : {
					this.setBackground(userColor);
					break;
				}
				default : {
					this.setBackground(Color.WHITE);
					break;
				}
			}

			if (value == null) {
				this.setText("");
				super.getTableCellRendererComponent(table,
						value, isSelected, hasFocus, row, column);
				return this;
			}

			this.setIcon(null);
			/* ------------------------------------------------------ */
			switch (column) {
				case 0 : {
					// icon + type name
					Integer v = (Integer) value;
					if (v.equals(LogType.ADMIN)) {
						this.setIcon(AdminModule.getSmallIcon(AdminModule.ICON_ADMIN));
						this.setText("Admin");
						this.setVerticalTextPosition(JLabel.CENTER);
					} else
						if (v.equals(LogType.ERROR)) {
							this.setIcon(AdminModule.getSmallIcon(AdminModule.ICON_ERROR));
							this.setText("Error");
							this.setVerticalTextPosition(JLabel.CENTER);
						}
						else
							if (v.equals(LogType.USER)) {
								this.setIcon(null);
								this.setText("User");
								this.setVerticalTextPosition(JLabel.CENTER);
							}
							else
								if (v.equals(LogType.SYSTEM)) {
									this.setIcon(AdminModule.getSmallIcon(AdminModule.ICON_SYSTEM));
									this.setText("System");
									this.setVerticalTextPosition(JLabel.CENTER);
								}
					super.getTableCellRendererComponent(table,
							this.getText(), isSelected, hasFocus, row, column);
					break;
				}
				/* ------------------------------------------------------ */
				case 1 : {
					// date
					super.getTableCellRendererComponent(table,
							formater.format((Date)value), isSelected, hasFocus, row, column);
					break;
				}
				case 5 : 
				case 6 : 
				case 7 : {
					// message
				    	super.getTableCellRendererComponent(table,
						value, isSelected, hasFocus, row, column);
				    	try {
				    	    this.setToolTipText((String) value);					    
					} catch (Exception e) {}
					break;
				}
				default : super.getTableCellRendererComponent(table,
								value, isSelected, hasFocus, row, column);
			}


			return this;
			/* ====================================================== */
		}
	}

	public void actionPerformed(ActionEvent e) {
		/* ============================================= */
		refreshList();
		/* ============================================= */
	}



	public void propertyChange(PropertyChangeEvent evt) {
		/* ============================================= */
		refreshList();
		/* ============================================= */
	}



	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.core.gui.GECAMedTab#enablePanel(boolean)
	 */
	@Override
	public void enablePanel(boolean enable) {
	   /* if (! enable)
		disableTab();
	    else*/
		enableTab();
	}
	
	


}
