/*****************************************************************************
 *                                                                           *
 *  Copyright (c) 2010 by SANTEC/TUDOR www.santec.tudor.lu                   *
 *                                                                           *
 *                                                                           *
 *  This library is free software; you can redistribute it and/or modify it  *
 *  under the terms of the GNU Lesser General Public License as published    *
 *  by the Free Software Foundation; either version 2 of the License, or     *
 *  (at your option) any later version.                                      *
 *                                                                           *
 *  This software 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 along with this library; if not, write to the Free Software      *
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  *
 *                                                                           *
 *****************************************************************************/
package lu.tudor.santec.gecamed.prescription.gui.editor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.undo.UndoManager;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.GECAMedOptionPane;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.controller.document.DocumentController;
import lu.tudor.santec.gecamed.core.gui.utils.UndoTextArea;
import lu.tudor.santec.gecamed.core.gui.utils.WindowToolbox;
import lu.tudor.santec.gecamed.core.gui.widgets.ErrorDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.LimitTextField;
import lu.tudor.santec.gecamed.core.gui.widgets.ModuleHeader;
import lu.tudor.santec.gecamed.core.gui.widgets.NamedComponent;
import lu.tudor.santec.gecamed.core.gui.widgets.autocompletion.GECAMedAutoCompletionHandler;
import lu.tudor.santec.gecamed.core.gui.widgets.autocompletion.GECAMedAutoCompletionTextComponent;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.letter.ejb.entity.beans.LetterPlaceholder;
import lu.tudor.santec.gecamed.letter.gui.placeholders.BadVersionException;
import lu.tudor.santec.gecamed.letter.gui.placeholders.PlaceholdersConfig;
import lu.tudor.santec.gecamed.letter.gui.placeholders.WrongJavaVersionException;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrescriptionTemplate;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.PrescriptionType;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.drug.IDrug;
import lu.tudor.santec.gecamed.prescription.ejb.session.beans.PrescriptionManagerBean;
import lu.tudor.santec.gecamed.prescription.ejb.session.interfaces.PrescriptionManager;
import lu.tudor.santec.gecamed.prescription.gui.PrescriptionIcons;
import lu.tudor.santec.gecamed.prescription.gui.editor.filter.TemplateFulltextFilter;
import lu.tudor.santec.gecamed.prescription.gui.util.PrescriptionUtils;
import lu.tudor.santec.gecamed.prescription.gui.widgets.PosologyChooserDialog;
import lu.tudor.santec.gecamed.prescription.gui.widgets.drugbrowser.DrugBrowser;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.org.fife.ui.autocomplete.AutoCompletion;
import lu.tudor.santec.org.fife.ui.autocomplete.AutoCompletionTextComponent;
import lu.tudor.santec.org.fife.ui.autocomplete.BasicCompletion;
import lu.tudor.santec.org.fife.ui.autocomplete.Completion;
import lu.tudor.santec.org.fife.ui.autocomplete.CompletionProvider;
import lu.tudor.santec.org.fife.ui.autocomplete.DefaultCompletionProvider;
import lu.tudor.santec.org.fife.ui.autocomplete.MWCompletionProvider;
import lu.tudor.santec.widgets.gui.ButtonFactory;
import lu.tudor.santec.widgets.gui.table.TableColumnListener;
import lu.tudor.santec.widgets.gui.table.TableStyler;

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

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

/**
 * The panel show the prescription templates in a dialog.
 * It contains a prescription template editor to create, modify and delete prescriptions.
 * It is used by the prescription editor to add templates to the prescription.
 * 
 * @author martin.heinemann@tudor.lu
 * 05.12.2008
 * 10:04:24
 *
 *
 * @version
 * <br>$Log: PrescriptionTemplatePanel.java,v $
 * <br>Revision 1.25  2013-12-27 18:09:24  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.24  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.23  2013-05-21 13:03:31  troth
 * <br>Fixed Ticket #1174.
 * <br>
 * <br>Revision 1.22  2013-03-28 16:07:17  ferring
 * <br>Contact placeholder will not be shown as an option in the prescription autocompleter
 * <br>
 * <br>Revision 1.21  2013-03-27 14:16:53  ferring
 * <br>Auto completion added for letter placeholders in prescription
 * <br>
 * <br>Revision 1.20  2013-03-27 08:54:35  ferring
 * <br>placeholders added for prescription templates
 * <br>
 * <br>Revision 1.19  2013-03-22 10:29:07  ferring
 * <br>store position and size of the dialog by user
 * <br>
 * <br>Revision 1.18  2013-03-11 07:47:34  ferring
 * <br>GECAMedDialog saves the last location and size by default
 * <br>
 * <br>Revision 1.17  2012-06-11 16:08:42  troth
 * <br>fix Ticket #990 - Textfield allows more characters than the database column.
 * <br>
 * <br>Revision 1.16  2010-11-15 14:17:41  troth
 * <br>Complete - # 685: Prescription Template editor closes when calling Posology or CeFIP
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/685
 * <br>
 * <br>Revision 1.15  2010-10-20 12:10:00  troth
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.14  2010-10-14 09:26:38  troth
 * <br>fix bug - set minimum window values
 * <br>
 * <br>Revision 1.13  2010-10-11 13:57:21  troth
 * <br>Complete - # 552: Verschreibungs-Vorlagenfenster verdeckt Verschreibungstext
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/552
 * <br>
 * <br>Revision 1.12  2010-07-30 13:59:30  troth
 * <br>PrescriptionTemplate redesign of private flag, add Icons and add translations
 * <br>
 * <br>Revision 1.11  2010-07-22 09:49:39  troth
 * <br>add implementation - # 239: Prescription Templates linked to physician
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/239
 * <br>
 * <br>Revision 1.10  2010-07-01 15:46:59  troth
 * <br>Incomplete - # 206: Enlarge the warning message windows for drug prescription templates with warning
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/206
 * <br>
 * <br>Revision 1.9  2010-06-10 12:20:11  troth
 * <br>fix small bug - how set the save button aktiv
 * <br>
 * <br>Revision 1.8  2010-06-09 14:36:45  troth
 * <br>implement old feature - double click on prescription template put text directly in the prescription - add blank line after every template
 * <br>
 * <br>Revision 1.7  2010-06-09 14:15:55  troth
 * <br>implement old feature - double click on prescription template put text directly in the prescription
 * <br>
 * <br>Revision 1.6  2010-06-09 12:26:06  troth
 * <br>fix small bugs - dialog behavior of ok and canel button
 * <br>
 * <br>Revision 1.5  2010-06-08 14:31:57  troth
 * <br>rebuild of the PrescriptionTemplatePanel and the PrescriptionTemplateTabelModel
 * <br>
 * <br>Revision 1.4  2010-06-02 11:29:05  troth
 * <br>redesign of Prescription Template Editor - # 519: Speicherverhalten der Verschreibungstemplates
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/519
 * <br>
 * <br>Revision 1.3  2010-05-19 14:18:09  troth
 * <br>add form and dose to the drug text - Incomplete - # 508: CeFIP Liste: Benutzung von Name, Form und Dosis bei der Verschreibung
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/508
 * <br>
 * <br>Revision 1.2  2010-05-10 15:09:07  troth
 * <br>add template search function in template dialog
 * <br>
 * <br>Revision 1.1  2010-04-26 16:51:09  troth
 * <br>Redesign of the prescription view - all prescription class and new package
 * <br>
 * <br>Revision 1.12  2010-04-01 11:04:36  troth
 * <br>fixed bug open templateEditor with 0 templates
 * <br>
 * <br>Revision 1.11  2010-03-30 11:06:06  troth
 * <br>Redesign of the prescription view - PrescriptionTemplatePanelNew extends now from GECAMedBaseDialog
 * <br>
 * <br>Revision 1.10  2009-05-13 12:57:22  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.9  2009-04-15 13:30:41  heinemann
 * <br>added cefip and posology button to template editor
 * <br>
 * <br>Revision 1.8  2009-04-03 13:22:38  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.7  2009-03-24 11:10:09  heinemann
 * <br>Ticket #270 make shortcut column in presc templates resizable
 * <br>fixed.
 * <br>the width of the column is now saved in the user settings.
 * <br>
 * <br>Revision 1.6  2009-02-16 13:02:30  heinemann
 * <br>removed ok/cancel buttons of the dialog
 * <br>
 * <br>Revision 1.5  2009-02-09 15:07:41  heinemann
 * <br>user can delete prescription templates
 * <br>
 * <br>Revision 1.4  2009-02-09 11:21:23  heinemann
 * <br>fixed bug in date of represcribed prescription
 * <br>
 * <br>behaviiour of template selector changed: double click appends template content to the prescritpiont. Window stays visible until "close" button pressed
 * <br>
 * <br>Revision 1.3  2009-01-19 15:57:57  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.2  2008-12-17 15:23:06  heinemann
 * <br>initial commit after merging of branch new prescription
 * <br>
 * <br>Revision 1.1.2.1  2008-12-15 14:08:21  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1  2008-12-05 17:35:35  heinemann
 * <br>Rewrite of the prescription module, ... in progress
 * <br>
 *   
 */
public class PrescriptionTemplatePanel extends GECAMedBaseDialog implements DocumentListener, ActionListener, KeyListener /*, WindowListener */ {
	
	private static final long serialVersionUID = 1L;
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(PrescriptionTemplatePanel.class.getName());
	
	private AutoCompletion completion;
	
	private JTextField searchFieldPrescription;
	
	private JTable templateTable;
	
	private JScrollPane templateTableScrollPaine;
	
	private JTextField searchFieldShort;
	
	private JTextField searchFieldName;
	
	private JTextArea textArea;
	
	private JTextArea warningTextArea;
	
//	private JScrollPane textAreaScrollPaine;
	
	private JScrollPane warningTextAreaScrollPaine;
	
	private CellConstraints cc;
	
	private PrescriptionTemplateTableModel tableModel;
	
	private ObservableText textToUse = new ObservableText();
	
	private JButton addButton;
	
	private JButton saveButton;

	private JButton deleteButton;

	private JButton cefipButton;

	private JButton posologyButton;

	private static final String GENERIC_SETTING_COLWIDTH = "PRESC_TEMPLATE_COLWIDTH";
	
	private ModuleHeader titlePanel;
	
	private LimitTextField shortcutTextField;
	
	private LimitTextField nameTextField;
	
	private JPanel searchPanel;

	private JButton clearButton;

	private TemplateFulltextFilter templateTextShortFilter;
	
	private TemplateFulltextFilter templateTextNameFilter;
	
	private TemplateFulltextFilter templateTextPrescriptionFilter;
	
	private static PrescriptionTemplatePanel prescriptionTemplateDialog;
	
	private static List<PrescriptionTemplatePanel> templateDialogs = new ArrayList<PrescriptionTemplatePanel>();
	
	private PrescriptionTemplate currentTemplate;
	
	private boolean addTemplate = false;

	private int currentRow;

	protected boolean comeFromRowSelect = false;
	
	private Document currentPrescriptionDocument;
	
	private JToggleButton privateTemplate; // checkBox for the private flag

	private Integer physicianId;

	private GECAMedAutoCompletionTextComponent actc;
	
	private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\[[A-Z0-9_]+\\]");
	
	private static final int MIN_DIALOG_WIDTH = 740;
	
	private static final int MIN_DIALOG_HEIGHT = 360;
	
	public PrescriptionTemplatePanel() {
		super(Translatrix.getTranslationString("doseDialog.title"), true, true, false);
		setResizingOptions(RESIZING_ALL);
		this.enableCancelKeyMapping(true);
		//this.initButtonActions(false);
		this.initComponent();
		this.tableModel = new PrescriptionTemplateTableModel();
		this.initFilter();
		this.templateTable.setModel(this.tableModel);
		this.buildPanel();
		this.configurePanel();
		this.initListener();
//		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
//		this.addWindowListener(this);
		saveAndRestoreSizeAndLocation();
		prescriptionTemplateDialog = this;
	}
	

	/**
	 * @param the parent of the dialog
	 * @return the text witch will be append to the prescription
	 */
	public String showDialog(Window parent, Document currentPrescriptionDocument) {
		
		this.setTitle(Translatrix.getTranslationString("prescription.name.templates") + " - " 
					+ Translatrix.getTranslationString("prescription.name." + this.tableModel.getType()));
		
		this.textToUse.clear();
		this.currentPrescriptionDocument = currentPrescriptionDocument;
		
		if((tableModel.getRowCount() == 0)) {
			this.setTemplate(new PrescriptionTemplate(), false);
			addTemplate = true;
		}else{
			tableModel.update();
			tableModel.fireTableDataChanged();
		}
		comeFromRowSelect = false;
		
		
		setPanelModifyenableTextArea(true);
		if(!(tableModel.getRowCount() == 0)) templateTable.setRowSelectionInterval(0, 0);
		// reload the templates of all types
		for (PrescriptionType type : PrescriptionUtils.getPrescriptionTypes())
			reloadTemplates(type.getName(), this);
//		initDialogSize();
		setMinimumSize(new Dimension(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT));
		//MainFrame.showDialogCentered(this);
		this.setVisible(true);
		if (! textToUse.toString().equals("")) {
			return textToUse.toString();
		}
		return null;
	}
	

//	/**
//	 * set the dialogsize in relation to the screensize
//	 */
//	private void initDialogSize() {
//		// load dialog position and dimension on local client
//		int locX;
//		int locY;
//		
//		try {
//			locX = Integer.parseInt(MainFrame.getMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_X));
//			locY = Integer.parseInt(MainFrame.getMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_Y));
//        } catch (Exception e1) {
//        	locX = 0;
//        	locY = 0;
//        }
//        
//		if (locX < 0 || locX > 2000) locX = 0;
//		if (locY < 0 || locY > 2000) locY = 0;
//		
//		this.setLocation(locX, locY);
//		
//		int width;
//		int height;
//		
//		try {
//			width = Integer.parseInt(MainFrame.getMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_WIDTH));
//			height = Integer.parseInt(MainFrame.getMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_HEIGHT));
//		} catch (Exception e1) {
//			width = MIN_DIALOG_WIDTH;
//			height = MIN_DIALOG_HEIGHT;
//		}
//		
//		if (width < MIN_DIALOG_WIDTH || width > 3000) width = MIN_DIALOG_WIDTH;
//		if (height < MIN_DIALOG_HEIGHT || height > 2000) height = MIN_DIALOG_HEIGHT;
//		
//		this.setSize(width,height);
//	}
	
	
	/**
	 * init all Components of the panel
	 */
	private void initComponent() {
		this.addButton		= ButtonFactory.createEffectButton(GECAMedModule.getScaledIcon(GECAMedIconNames.ADD,32));
		this.saveButton		= ButtonFactory.createEffectButton(GECAMedModule.getIcon(GECAMedIconNames.SAVE));
		this.deleteButton	= ButtonFactory.createEffectButton(GECAMedModule.getIcon(GECAMedIconNames.CLOSE));
		this.cefipButton	= ButtonFactory.createEffectButton(PrescriptionIcons.getScaledIcon(PrescriptionIcons.CEFIP_ICON,32));
		this.posologyButton	= ButtonFactory.createEffectButton(PrescriptionIcons.getIcon(PrescriptionIcons.PRESCRIPTION_MODULE));
		
		this.deleteButton  .setToolTipText(Translatrix.getTranslationString("prescription.buttons.deleteTemplate"));
		this.saveButton    .setToolTipText(Translatrix.getTranslationString("prescription.buttons.saveastemplate"));
		this.addButton     .setToolTipText(Translatrix.getTranslationString("prescription.buttons.newTemplate"));
		this.cefipButton   .setToolTipText(Translatrix.getTranslationString("prescription.buttons.cefip"));
		this.posologyButton.setToolTipText(Translatrix.getTranslationString("prescription.buttons.posology"));
		
		// the table for the template list
		this.templateTable = new JTable();
		this.templateTableScrollPaine = new JScrollPane(this.templateTable);
		this.templateTable.setDefaultRenderer(Object.class, new TemplateRenderer());
		
		// the text area
		this.textArea = new UndoTextArea(new UndoManager());
		this.completion	= new AutoCompletion(createPlaceholderCompletions());
		this.completion.install(this.textArea);

		this.textArea.setLineWrap(true);
		this.textArea.setWrapStyleWord(true);
		this.textArea.addKeyListener(this);
		
		actc = new GECAMedAutoCompletionTextComponent (textArea, GECAMedAutoCompletionHandler.PRESCRIPTION_CONTEXT);
		actc.setSearchMode(MWCompletionProvider.SEARCH_MODE_BOTH);
		
//		this.textAreaScrollPaine = new JScrollPane(this.textArea);

		// warning text area
		this.warningTextArea = new JTextArea();
		this.warningTextArea.setLineWrap(true);
		this.warningTextArea.setWrapStyleWord(true);
		this.warningTextAreaScrollPaine = new JScrollPane(this.warningTextArea);
		this.warningTextArea.setToolTipText(Translatrix.getTranslationString("template.desc.warning"));
		
		// template private switch
		this.privateTemplate = new JToggleButton(Translatrix.getTranslationString("template.desc.privateflag"), PrescriptionIcons.getIcon(PrescriptionIcons.PUBLIC_ICON), false);
	}
	
	
	private CompletionProvider createPlaceholderCompletions()
	{
		List<LetterPlaceholder> placeholders	= GECAMedLists.getListReference(LetterPlaceholder.class);
		DefaultCompletionProvider	provider	= new DefaultCompletionProvider();
		Completion	completion;
		
		
		for (LetterPlaceholder p : placeholders)
		{
			if (p != null && p.getName() != null)
			{
				if (!p.getName().startsWith("[CON")) // don't use the contacts, as there will no contact be given
				{
					completion	= new BasicCompletion(provider, p.getName().substring(1));
					provider.addCompletion(completion);
				}
			}
		}
		
		return provider;
	}


	/**
	 * build the GUI of the panel
	 */
	private void buildPanel() {
		
		this.titlePanel = new ModuleHeader(GECAMedColors.c_GECAMedBackground);
		
		this.titlePanel.addButton(this.posologyButton);
		this.titlePanel.addButton(this.cefipButton);
		this.titlePanel.addButton(this.deleteButton);
		this.titlePanel.addButton(this.addButton);
		this.titlePanel.addButton(this.saveButton);
		
		JPanel parentPanel = new JPanel(new FormLayout("3dlu,fill:pref:grow,3dlu",
										"3dlu,fill:pref,3dlu,fill:pref:grow,3dlu"));
		parentPanel.setBackground(GECAMedColors.c_GECAMedBackground);
		this.cc = new CellConstraints();
				
		// a panel for the search field and the add button
		
		this.searchFieldShort 			= new JTextField();
		this.searchFieldName 			= new JTextField();
		this.searchFieldPrescription 	= new JTextField();
		this.searchPanel 				= new JPanel();
		this.clearButton				= ButtonFactory.createEffectButton(GECAMedModule.getMediumIcon(GECAMedModule.EDIT_CLEAR_LTR));
		
		FormLayout f = new FormLayout(// cols
									  "0dlu," +
									  "fill:pref," + //clearbutton
									  "2dlu," +
									  "fill:70dlu," + //short searchfield
									  "3dlu," +
									  "fill:70dlu," + //name searchfield
									  "5dlu," +
									  "fill:90dlu," + //prescription searchfield
									  "0dlu",
									  // rows
									  "0dlu," +
									  //"center:15dlu," +
									  "fill:pref," +
									  "0dlu");
		
		this.searchPanel.setLayout(f);
		this.searchPanel.setBackground(GECAMedColors.c_GECAMedBackground);
		
		JPanel jp = new JPanel (new FormLayout("pref:grow", "pref, pref"));
		jp.setOpaque(false);
		
		jp.add(new JLabel(Translatrix.getTranslationString("template.field.shortcut")+":"),	cc.xy(1, 1));
		jp.add(this.searchFieldShort,														cc.xy(1, 2));
		this.searchPanel.add(jp,		cc.xy(4,  2));
		
		jp = new JPanel (new FormLayout("pref:grow", "pref, pref"));
		jp.setOpaque(false);
		jp.add(new JLabel(Translatrix.getTranslationString("template.field.name")+":"),		cc.xy(1, 1));
		jp.add(this.searchFieldName,										 				cc.xy(1, 2));
		this.searchPanel.add(jp,		cc.xy(6,  2));
		
		jp = new JPanel (new FormLayout("pref:grow", "pref, pref"));
		jp.setOpaque(false);
		jp.add(new JLabel(Translatrix.getTranslationString("prescription.name")+":"),		cc.xy(1, 1));
		jp.add(this.searchFieldPrescription, 						   				 		cc.xy(1, 2));
		this.searchPanel.add(jp,		cc.xy(8,  2));
		
		this.searchPanel.add(clearButton,cc.xy(2, 2));
		
		searchPanel.setOpaque(false);
		
		this.titlePanel.setHeaderComponent(searchPanel);
		
		this.searchFieldName.requestFocus(true);
		this.searchFieldName.requestFocus();
		
		
		// assemble
		JPanel mainPanel = new JPanel(new FormLayout(
										// cols
										"fill:160dlu,5dlu,fill:50dlu:grow", 
										// rows
										"3dlu,fill:50dlu:grow,3dlu"));
		
		// the left panel
		templateTableScrollPaine.getViewport().setBackground(Color.WHITE);
		templateTableScrollPaine.setBackground(Color.WHITE);
		
		JPanel leftPanel = new JPanel(new BorderLayout());
		leftPanel.add(this.templateTableScrollPaine, BorderLayout.CENTER);
		
		// the header and save button
		this.shortcutTextField = new LimitTextField(30);
		this.nameTextField = new LimitTextField(250);
		
		// rightPanel
		JPanel rightPanel = new JPanel(new FormLayout(
				// col
				"fill:40dlu:grow,3dlu,fill:40dlu:grow", 
				// row
				"fill:pref,3dlu," +			// Shortcut, Shortcut text field | Name, Name text field
				"fill:50dlu:grow(0.7),3dlu," +	// Prescription, Prescription text field
				"fill:25dlu:grow(0.3),3dlu," +		// Hint, Hint text field
				"fill:25dlu"));				// private switch
		
		// Shortcut, Shortcut textfield
		rightPanel.add(new NamedComponent(Translatrix.getTranslationString("template.table.shortcut"),
				this.shortcutTextField, true, JLabel.HORIZONTAL), cc.xyw(1, 1, 1));
		// Name, Name textfield
		rightPanel.add(new NamedComponent(Translatrix.getTranslationString("template.table.name"),
				this.nameTextField, true, JLabel.HORIZONTAL), cc.xyw(3, 1, 1));
		
		// Prescription, Prescription text field
//		rightPanel.add(new NamedComponent(Translatrix.getTranslationString("prescription.name"),
//				this.textAreaScrollPaine), cc.xyw(1, 3, 3));
		
		rightPanel.add(new NamedComponent(Translatrix.getTranslationString("prescription.name"),
				this.actc), cc.xyw(1, 3, 3));
		
		// Hint, hint text field
		rightPanel.add(new NamedComponent(Translatrix.getTranslationString("prescription.name.warning"),
				this.warningTextAreaScrollPaine), cc.xyw(1, 5, 3));
		
		// private switch
		this.privateTemplate.setOpaque(false);
		rightPanel.add(this.privateTemplate, cc.xyw(1, 7, 3));
		
		
		mainPanel.setOpaque( false);
		leftPanel.setOpaque( false);
		rightPanel.setOpaque(false);
		
		mainPanel.add(leftPanel,  cc.xy(1, 2));
		mainPanel.add(rightPanel, cc.xy(3, 2));
		mainPanel.setBorder(BorderFactory.createTitledBorder(""));
		
		parentPanel.add(titlePanel, cc.xy(2, 2));
		parentPanel.add(mainPanel, cc.xy(2, 4));
		
		this.add(parentPanel);
	}
	
	
	/**
	 * init all Listeners for the searchfields
	 */
	private void initListener() {
		MouseListener searchFieldListener = new MouseListener() {
			
			public void mouseReleased(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {
				clearSearchFields();
			}
			public void mouseExited(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseClicked(MouseEvent e) {}
		};
		
		this.searchFieldShort.addMouseListener(searchFieldListener);
		this.searchFieldName.addMouseListener(searchFieldListener);
		this.searchFieldPrescription.addMouseListener(searchFieldListener);
		
		this.searchFieldShort.getDocument().addDocumentListener(this);
		this.searchFieldName.getDocument().addDocumentListener(this);
		this.searchFieldPrescription.getDocument().addDocumentListener(this);
		
		this.clearButton.addActionListener(this);
		
		MouseListener tableMouseListener = new MouseListener() {
			
			public void mouseReleased(MouseEvent e) {}
			
			public void mousePressed(MouseEvent e) {}
			
			public void mouseExited(MouseEvent e) {}
			
			public void mouseEntered(MouseEvent e) {}
			
			public void mouseClicked(MouseEvent e) {
				
				// to put a prescription template directly in the prescription text per double click
				if(e.getClickCount() >= 2)
				{
					String ptext = null;
					String text = getTextForPrescription();

					if (text == null || "".equals(text.trim()))
						return;

					try {
						
						ptext = currentPrescriptionDocument.getText(0, currentPrescriptionDocument.getLength());
					} catch (BadLocationException ex) {
//						ex.printStackTrace();
						logger.log(Level.ERROR, ex.getMessage(), ex);
					}
					
					if (ptext == null || "".equals(ptext.trim()))
						ptext = ptext + text;
					else
						ptext = ptext + "\n\n" +text;
					try {
						currentPrescriptionDocument.remove(0,currentPrescriptionDocument.getLength());
						currentPrescriptionDocument.insertString(
								0,
								ptext, 
								new SimpleAttributeSet());
					} catch (BadLocationException ex) {
//						ex.printStackTrace();
						logger.log(Level.ERROR, ex.getMessage(), ex);
					}
					
				}
			}
		};
		
		this.templateTable.addMouseListener(tableMouseListener);
		
		// listener for the private switch
		ItemListener privateTemplateListener = new ItemListener() {
			public void itemStateChanged( ItemEvent e ) {
				setPanelModifyenableTextArea(true);
				if(privateTemplate.isSelected()) {
					privateTemplate.setIcon(PrescriptionIcons.getIcon(PrescriptionIcons.PRIVATE_ICON));
					Physician physician = GECAMedModule.getCurrentPhysician();
					if(physician != null && physician.isPersistent()) {
						physicianId = physician.getId();
						return;
					}
				}else privateTemplate.setIcon(PrescriptionIcons.getIcon(PrescriptionIcons.PUBLIC_ICON));
				physicianId = null;
			}
		};
		this.privateTemplate.addItemListener( privateTemplateListener );
	}
	
	/**
	 * init all filters for the searchfields
	 */
	public void initFilter()
	{
		// create the filter
		this.templateTextShortFilter = new TemplateFulltextFilter();
		this.templateTextNameFilter = new TemplateFulltextFilter();
		this.templateTextPrescriptionFilter = new TemplateFulltextFilter();
		
		// install the filters
		this.tableModel.installFilter(templateTextShortFilter, 0);
		this.tableModel.installFilter(templateTextNameFilter, 1);
		this.tableModel.installFilter(templateTextPrescriptionFilter, 2);
	}
	
	// searchfields listener and action of clear button
	/* (non-Javadoc)
	 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
	 */
	public void changedUpdate(DocumentEvent e) {
		this.triggerTextEvent();
	}
	public void insertUpdate(DocumentEvent e) {
		this.triggerTextEvent();
	}
	public void removeUpdate(DocumentEvent e) {
		this.triggerTextEvent();
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		// clear all searchfields
		if (this.clearButton.equals(e.getSource()))
			clearSearchFields();
	}
	
	/**
	 * clear all searchfields
	 */
	public void clearSearchFields()
	{
		this.searchFieldShort.setText("");
		this.searchFieldName.setText("");
		this.searchFieldPrescription.setText("");
		this.tableModel.resetFiltering();
		this.tableModel.fireTableDataChanged();
	}
	
	
	/**
	 * handle the events of the searchfields.
	 * set the searchfilters on/off and update the textfields and the tablecolumns 
	 */
	private void triggerTextEvent() {
		
		// search over short of template
		if (this.searchFieldShort.getText() != null && !"".equals(this.searchFieldShort.getText().trim())) {
			showSaveDialog(false);
			this.templateTextShortFilter.setFilter(this.searchFieldShort.getText());
			this.tableModel.setFilteringEnabled(true, 0);
		} else {
			this.tableModel.setFilteringEnabled(false, 0);
		}
		
		// search over name of template
		if (this.searchFieldName.getText() != null && !"".equals(this.searchFieldName.getText().trim())) {
			showSaveDialog(false);
			this.templateTextNameFilter.setFilter(this.searchFieldName.getText());
			this.tableModel.setFilteringEnabled(true, 1);
		} else {
			this.tableModel.setFilteringEnabled(false, 1);
		}
		
		// search over prescription of template
		if (this.searchFieldPrescription.getText() != null && !"".equals(this.searchFieldPrescription.getText().trim())) {
			showSaveDialog(false);
			this.templateTextPrescriptionFilter.setFilter(this.searchFieldPrescription.getText());
			this.tableModel.setFilteringEnabled(true, 2);
		} else {
			this.tableModel.setFilteringEnabled(false, 2);
		}
		
		// reset all filters
		if ("".equals(this.searchFieldShort.getText().trim()) &&
				"".equals(this.searchFieldName.getText().trim()) &&
				"".equals(this.searchFieldPrescription.getText().trim())){
					this.tableModel.resetFiltering();
				}
		// update table with out losing focus of searchfield
		tableModel.update();
		tableModel.fireTableDataChanged();
		
		if((tableModel.getRowCount() < 0)) {
			this.shortcutTextField.setText("");
			this.nameTextField.setText("");
			this.textArea.setText("");
			this.warningTextArea.setText("");
		}
		
	}
	
	public void setPreferredColumnWidths(double[] percentages) {
		Dimension tableDim = templateTable.getPreferredSize();
		
		double total = 0;
		for (int i = 0; i < templateTable.getColumnModel().getColumnCount(); i++)
			total += percentages[i];

		for (int i = 0; i < templateTable.getColumnModel().getColumnCount(); i++) {
			TableColumn column = templateTable.getColumnModel().getColumn(i);
			column.setPreferredWidth((int) ((tableDim.width+300) * (percentages[i] / total)));
		}
	}
	
	
	/**
	 * makes nicer and adds action listeners
	 */
	private void configurePanel() {
		this.templateTable.getTableHeader().setReorderingAllowed(false);
		this.templateTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		try {
			double ratio = Double.parseDouble((MainFrame.getInstance().userSettings.readGenericSetting(GENERIC_SETTING_COLWIDTH)));
			TableStyler.setPreferredColumnWidths(templateTable, new double[] {ratio, (double)1-ratio});
		} catch (Exception e) {
			TableStyler.setPreferredColumnWidths(templateTable, new double[] {0.6, 0.8, 0.2, 0.0});
		}
		this.templateTable.removeColumn(this.templateTable.getColumnModel().getColumn(3));
		
		this.templateTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				
				if(e.getValueIsAdjusting()) return;
				
				if(!comeFromRowSelect ) {
				int row = tableModel.filteredToModel(templateTable.getSelectedRow());
				
				if (row == -1)
				{
					if(!setTemplate(new PrescriptionTemplate(),false)) {
						comeFromRowSelect = true;
						if(currentRow > 0) templateTable.setRowSelectionInterval(currentRow, currentRow);
						return;
					}
				}else{
					PrescriptionTemplate template = tableModel.getTemplate(row);
					if(!setTemplate(template,false)) {
						comeFromRowSelect = true;
						if(currentRow > 0) templateTable.setRowSelectionInterval(currentRow, currentRow);
						return;
					}
					addTemplate = false;
				}
				}else{ 
					comeFromRowSelect = false;
				}
			}
		});
		
		
		new TableColumnListener(this.templateTable) {

			/* (non-Javadoc)
			 * @see lu.tudor.santec.widgets.gui.table.TableColumnListener#columnsChanged(java.lang.Integer[])
			 */
			@Override
			public void columnsChanged(Integer[] columnMargins) {
				if (columnMargins == null || columnMargins.length < 1)
					return;
				
				// get the width of the first column and save the ratio in the settings
				double ratio = (double) columnMargins[0] / (double) templateTable.getWidth();
				MainFrame.getInstance().userSettings.addGenericSetting(GENERIC_SETTING_COLWIDTH, ""+ratio);
			}
		};
		
		// cancel button of dialog
		this.cancelButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				
				if(showSaveDialog(false)) setVisible(false);
			}
		});

		// ok button of dialog
		this.okButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if(showSaveDialog(false)) {
					textToUse.setText(getTextForPrescription());
					setVisible(false);
					
					// show warning message
					if (warningTextArea.getText() != null && !warningTextArea.getText().equals("")) {
						
						JTextArea msgBox = new JTextArea(warningTextArea.getText());
						msgBox.setEditable(false);
						//msgBox.setOpaque(false);
						msgBox.setForeground(Color.RED);
						msgBox.setFont(new Font("Arial",Font.BOLD,16));
						msgBox.setLineWrap(true);
						msgBox.setWrapStyleWord(true);
						msgBox.setRows(6);
						msgBox.setColumns(26);
						JScrollPane scrollMsgBox = new JScrollPane(msgBox);
						//scrollMsgBox.setBorder(BorderFactory.createLineBorder(Color.BLACK,0));
						
						// open message dialog with the msg
						GECAMedOptionPane.showMessageDialog(PrescriptionTemplatePanel.this.getParent(),
								scrollMsgBox,
								Translatrix.getTranslationString("prescription.name.warning"),
								GECAMedOptionPane.WARNING_MESSAGE);
					}
					setVisible(false);
				}
			}
		});
		
		// the template editor add button
		this.addButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				
				if(!setTemplate(new PrescriptionTemplate(), false)) return;
				
				// clear searchfields
				clearSearchFields();
				addTemplate = true;
			}
		});


		// the template editor save button
		this.saveButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				saveTemplate();
			}
		});
		
		
		// the template editor delete button
		this.deleteButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				showSaveDialog(false);
				deleteTemplate();
				if(!(tableModel.getRowCount() == 0)) templateTable.setRowSelectionInterval(0, 0);
				
			}
		});

		// the template editor cefip button
		this.cefipButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				String txt = null;
					DrugBrowser db = DrugBrowser.getInstance();
					
					IDrug drug = db.showDialog(WindowToolbox.getOwnerFrame((Component) e.getSource()), "");
					if (drug != null)
						txt = drug.getName() + ", " + drug.getApplicationForm() + ", " + drug.getDose() + " ";
					if (txt != null) {
						append(txt);
					}	
			}
		});

		// the template editor posology button
		this.posologyButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				String txt = null;
				PosologyChooserDialog pc = PosologyChooserDialog.getInstance();
				txt = pc.showDialog(WindowToolbox.getOwnerFrame((Component) e.getSource()));
				if (txt != null) {
					append(txt);
				}
			}
		});
		
		/* ------------------------------------------------------- */
		DocumentListener docListener = new DocumentListener() {

			public void changedUpdate(DocumentEvent e) {
				setPanelModifyenableTextArea(true);
			}

			public void insertUpdate(DocumentEvent e) {
				setPanelModifyenableTextArea(true);
			}

			public void removeUpdate(DocumentEvent e) {
				setPanelModifyenableTextArea(true);
			}
		};
		
		this.shortcutTextField.getDocument().addDocumentListener(docListener);
		this.nameTextField.getDocument().addDocumentListener(docListener);
		
		this.textArea.getDocument().addDocumentListener(docListener);
		this.warningTextArea.getDocument().addDocumentListener(docListener);
	}
	
	
	/**
	 * show a savedialog if a template is not save
	 * @param goformsave
	 * @return false if rollback else true
	 */
	private boolean showSaveDialog(boolean goformsave) {
		
		if(tableModel.isModified() && !goformsave)
		{
			// show save dialog		
			int result = GECAMedOptionPane.showConfirmDialog(
				this.getParent(),
				Translatrix.getTranslationString("template.saveDialog.text"),
				Translatrix.getTranslationString("template.saveDialog.title"),
				GECAMedOptionPane.YES_NO_CANCEL_OPTION);
					
			if(result == GECAMedOptionPane.YES_OPTION) {
				boolean save = this.saveTemplate();
				if(save) tableModel.setModified(false);
				return save;
			}
					
			if(result == GECAMedOptionPane.NO_OPTION) {
				tableModel.setModified(false);
				setPanelModifyenableTextArea(false);
				return true;
			}
					
			if(result == GECAMedOptionPane.CANCEL_OPTION || result == GECAMedOptionPane.CLOSED_OPTION) {
				return false;
			}
		}
		
		return true;
	}
	
	private boolean setTemplate(PrescriptionTemplate template, boolean gofromsave) {
		
		if(!showSaveDialog(gofromsave))
			return false;
		
		this.currentTemplate = template;
		
		int row = tableModel.filteredToModel(templateTable.getSelectedRow());
		if (row == -1) row = 0;
		
		this.currentRow = row;
		
		this.shortcutTextField.setText(this.currentTemplate.getShortcut());
		this.nameTextField.setText(this.currentTemplate.getDescription());
		this.textArea.setText(this.currentTemplate.getTextContent());
		this.warningTextArea.setText(this.currentTemplate.getWarningMsg());
		this.physicianId = this.currentTemplate.getPhysicianId();
		if(physicianId != null)
		{
			this.privateTemplate.setSelected(true);
			privateTemplate.setIcon(PrescriptionIcons.getIcon(PrescriptionIcons.PRIVATE_ICON));
		}else{
			this.privateTemplate.setSelected(false);
			privateTemplate.setIcon(PrescriptionIcons.getIcon(PrescriptionIcons.PUBLIC_ICON));
		}
		this.setPanelModifyenableTextArea(false);
			
		return true;
	}
	
	private PrescriptionTemplate getTemplate() {
		
		String shortcutText = this.shortcutTextField.getText();
		String nameText = this.nameTextField.getText();
		
		String prescriptionText = this.textArea.getText();
		String warningText = this.warningTextArea.getText();
		Integer physicianId = this.physicianId;
		
		PrescriptionType type = PrescriptionUtils.getTypeForString(this.tableModel.getType());
				
		if(this.currentTemplate == null) this.currentTemplate = new PrescriptionTemplate();
		else {
			this.currentTemplate.setPrescriptionTypeId(type.getId());
			this.currentTemplate.setShortcut(shortcutText);
			this.currentTemplate.setDescription(nameText);
			this.currentTemplate.setTextContent(prescriptionText);
			this.currentTemplate.setWarningMsg(warningText);
			this.currentTemplate.setPhysicianId(physicianId);
		}
		return this.currentTemplate;
	}
	
	/**
	 * colored the textfields and the panelhead if text are modified
	 * @param b if b is true text is modify
	 */
	public void setPanelModifyenableTextArea(boolean modify) {
		if (modify) {
			if(this.shortcutTextField.getText().equals("") &&
					this.nameTextField.getText().equals("") &&
					this.textArea.getText().equals("") &&
					this.warningTextArea.getText().equals(""))
			{
				this.saveButton.setEnabled(false);
				this.titlePanel.setColor(GECAMedColors.c_GECAMedBackground);
				this.tableModel.setModified(false);
			}else{
				this.saveButton.setEnabled(true);
				this.titlePanel.setColor(GECAMedColors.c_ModifiedTitleBackground);
				this.tableModel.setModified(true);
			}
		} else {
			this.saveButton.setEnabled(false);
			this.titlePanel.setColor(GECAMedColors.c_GECAMedBackground);
			this.tableModel.setModified(false);
		}	
	}
	
	/**
	 * append text to the template prescription textarea
	 * 
	 * @param text to append
	 */
	public void append(String text) {
		this.textArea.append(text);
	}
	
	
	/**
	 * save the template
	 * Saves the modified template that is currently selected
	 * in the templateTable
	 */
	public boolean saveTemplate() {
		String shortcutText = this.shortcutTextField.getText();
		String nameText = this.nameTextField.getText();
		//int physicianId = this.physicianId;
		
		// check if shortcutText or nameText are set
		if(shortcutText.equals("") && nameText.equals("")) {
			GECAMedOptionPane.showMessageDialog(this.getParent(),
					Translatrix.getTranslationString("prescription.dialogs.saveTemplateAlert.text"),
					Translatrix.getTranslationString("prescription.dialogs.saveTemplateAlert.title"),
					GECAMedOptionPane.INFORMATION_MESSAGE);
			return false;
		}
		
		if(tableModel.getRowCount() < 1) addTemplate = true;
		
		PrescriptionTemplate savedTemplate;
		
		try {
			// save template in database
			savedTemplate = this.getManager().saveTemplate(this.getTemplate());
			if(savedTemplate.isPersistent()) {
				// save template in datamodel
				if(addTemplate) {
					this.tableModel.addRow(savedTemplate);
					addTemplate = false;
				}else{
					this.tableModel.setRow(savedTemplate, this.currentRow);
				}
			}
		} catch (Exception ex) {
//			ex.printStackTrace();
			logger.log(Level.ERROR, ex.getMessage(), ex);
		}
				
		setPanelModifyenableTextArea(false);
		reloadTemplateDialogs(this);
		if(!(tableModel.getRowCount() == 0)) templateTable.setRowSelectionInterval(currentRow, currentRow);
		this.tableModel.fireTableRowsUpdated(currentRow, currentRow);
		tableModel.update();
		updateTable();
		return true;
	}
	
	/**
	 * update the table 
	 */
	public void updateTable() {
		this.templateTable.revalidate();
	}
	
	private void reloadTemplateDialogs(PrescriptionTemplatePanel exeptThisOne) {
		
		for (PrescriptionTemplatePanel pn : templateDialogs) {
			if (!pn.equals(exeptThisOne))
				reloadTemplates(exeptThisOne.getTableModel().getType(), pn);		
		
		}
	}
	
	
	/**
	 * Loads the list of templates for the type and user
	 * 
	 * @param type
	 * @param panel
	 */
	private void reloadTemplates(String type, PrescriptionTemplatePanel panel) {
						
		Physician physician  = GECAMedModule.getCurrentPhysician();
		int phyId = 0;
		if(physician != null && physician.isPersistent())
			phyId = physician.getId();
		
		try {
			List<PrescriptionTemplate> list = this.getManager().getTemplates(type, phyId);
			
			panel.getTableModel().setData(type, list);
			panel.getTableModel().fireTableDataChanged();
		} catch (Exception e) {
//			e.printStackTrace();
			logger.log(Level.ERROR, e.getMessage(), e);
		}
	}
	
	
	/**
	 * Deletes the selected template
	 */
	public void deleteTemplate() {
		
		
		// check if shortcutText or nameText are set
		int row = templateTable.getSelectedRow();
		
		if(row == -1)
		{
			GECAMedOptionPane.showMessageDialog(this.getParent(),
					Translatrix.getTranslationString("prescription.dialogs.deleteTemplateAlert.text"),
					Translatrix.getTranslationString("prescription.dialogs.deleteTemplateAlert.title"),
					GECAMedOptionPane.INFORMATION_MESSAGE);
			return;
		}
		
		PrescriptionTemplate template = this.tableModel.getTemplate(this.tableModel.filteredToModel(currentRow));

		if (template == null) {
			return;
		}
		
		// ask for sure
		int result = GECAMedOptionPane.showConfirmDialog(
				this.getParent(),
				Translatrix.getTranslationString("prescription.dialogs.deleteTemplateDialog.text"),
				Translatrix.getTranslationString("prescription.dialogs.deleteTemplateDialog.title"),
				GECAMedOptionPane.OK_CANCEL_OPTION);
		
		if (result != GECAMedOptionPane.OK_OPTION)
			return;
		
		try {
			if (template.isPersistent()) {
				this.getManager().deleteTemplates(Collections.nCopies(1, template));
				// replace the template in the model
				this.tableModel.removeTemplate(template);
			}		
		} catch (Exception ex) {
//			ex.printStackTrace();
			logger.log(Level.ERROR, ex.getMessage(), ex);
		}
		
		tableModel.fireTableDataChanged();
	}

	/**
	 * get a reference to the prescription manager session bean
	 *
	 * @return PrescriptionManager
	 */
	private PrescriptionManager getManager() {
		return (PrescriptionManager)
			ManagerFactory.getRemote(PrescriptionManagerBean.class);
	}
	
	/**
	 * get the model of the PrescriptionTemplate table
	 * @return PrescriptionTemplateTableModel the model of the table
	 */
	public PrescriptionTemplateTableModel getTableModel() {
		return this.tableModel;
	}
	
	/**
	 * get a instance of the PrescriptionTemplatePanel
	 * @return the PrescriptionTemplatePanel
	 */
	public static PrescriptionTemplatePanel getInstance(){
		if (prescriptionTemplateDialog == null) {
			new PrescriptionTemplatePanel();
		}
		return prescriptionTemplateDialog;
	}
	
	
	private String getTextForPrescription ()
	{
		String				text	= textArea.getText();
		int					index	= 0;
		List<String>		keys	= new LinkedList<String>();
		Matcher				matcher	= PLACEHOLDER_PATTERN.matcher(text);
		Map<String, String>	placeholders;
		
		
		while (matcher.find(index))
		{
			keys.add(matcher.group());
			index	= matcher.end();
		}
		
		if (keys.isEmpty())
			return text;
		
		try
		{
			placeholders	= PlaceholdersConfig.getPlaceholdersMap(null, keys, DocumentController.PH_VERSION_NEW);
			for (String key : placeholders.keySet())
			{
				text	= text.replace(key, placeholders.get(key));
			}
		}
		catch (WrongJavaVersionException e)
		{
			logger.log(Level.ERROR, e.getMessage());
			ErrorDialog.showErrorDialog(MainFrame.getInstance(), e);
		}
		catch (BadVersionException e)
		{
			logger.log(Level.WARN, "Wrong placholder version set.", e);
		}
		
		return text;
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.WindowListener#windowActivated(java.awt.event.WindowEvent)
	 */
//	public void windowActivated(WindowEvent e) {}
//	public void windowClosed(WindowEvent e) {}
//	public void windowClosing(WindowEvent e) {
//		this.onCloseWindow();
//	}
//	public void windowDeactivated(WindowEvent e) {}
//	public void windowDeiconified(WindowEvent e) {}
//	public void windowIconified(WindowEvent e) {}
//	public void windowOpened(WindowEvent e) {}
//	
//	public void onCloseWindow()
//	{
//		if(this.showSaveDialog(false)) this.dispose();
//		// save dialog position and dimension on local client
//		MainFrame.setMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_X, this.getX()+"");
//		MainFrame.setMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_Y, this.getY()+"");
//		MainFrame.setMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_WIDTH, this.getWidth()+"");
//		MainFrame.setMachineSetting(PRESCRIPTION_TEMPLATE_DIALOG_HEIGHT, this.getHeight()+"");
//	}
	
	class TemplateRenderer extends DefaultTableCellRenderer {

		private static final long serialVersionUID = 1L;

		/* (non-Javadoc)
		 * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
		 */
		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			// get modified information for the row and paint the background yellow if
			// modified
			Component c =  super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
					row, column);
			if (isSelected) {
				   super.setForeground(table.getSelectionForeground());
				   super.setBackground(table.getSelectionBackground());
				}
				else {
				    super.setForeground(table.getForeground());
				    super.setBackground(table.getBackground());
				}
			return c;
		}
	}
	
	
	/**
	 * @author martin.heinemann@tudor.lu
	 * 09.02.2009
	 * 11:02:58
	 *
	 *
	 * @version
	 * <br>$Log: PrescriptionTemplatePanel.java,v $
	 * <br>Revision 1.25  2013-12-27 18:09:24  donak
	 * <br>Cleanup of imports
	 * <br>
	 * <br>Revision 1.24  2013-07-15 06:18:35  ferring
	 * <br>logging changed
	 * <br>
	 * <br>Revision 1.23  2013-05-21 13:03:31  troth
	 * <br>Fixed Ticket #1174.
	 * <br>
	 * <br>Revision 1.22  2013-03-28 16:07:17  ferring
	 * <br>Contact placeholder will not be shown as an option in the prescription autocompleter
	 * <br>
	 * <br>Revision 1.21  2013-03-27 14:16:53  ferring
	 * <br>Auto completion added for letter placeholders in prescription
	 * <br>
	 * <br>Revision 1.20  2013-03-27 08:54:35  ferring
	 * <br>placeholders added for prescription templates
	 * <br>
	 * <br>Revision 1.19  2013-03-22 10:29:07  ferring
	 * <br>store position and size of the dialog by user
	 * <br>
	 * <br>Revision 1.18  2013-03-11 07:47:34  ferring
	 * <br>GECAMedDialog saves the last location and size by default
	 * <br>
	 * <br>Revision 1.17  2012-06-11 16:08:42  troth
	 * <br>fix Ticket #990 - Textfield allows more characters than the database column.
	 * <br>
	 * <br>Revision 1.16  2010-11-15 14:17:41  troth
	 * <br>Complete - # 685: Prescription Template editor closes when calling Posology or CeFIP
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/685
	 * <br>
	 * <br>Revision 1.15  2010-10-20 12:10:00  troth
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.14  2010-10-14 09:26:38  troth
	 * <br>fix bug - set minimum window values
	 * <br>
	 * <br>Revision 1.13  2010-10-11 13:57:21  troth
	 * <br>Complete - # 552: Verschreibungs-Vorlagenfenster verdeckt Verschreibungstext
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/552
	 * <br>
	 * <br>Revision 1.12  2010-07-30 13:59:30  troth
	 * <br>PrescriptionTemplate redesign of private flag, add Icons and add translations
	 * <br>
	 * <br>Revision 1.11  2010-07-22 09:49:39  troth
	 * <br>add implementation - # 239: Prescription Templates linked to physician
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/239
	 * <br>
	 * <br>Revision 1.10  2010-07-01 15:46:59  troth
	 * <br>Incomplete - # 206: Enlarge the warning message windows for drug prescription templates with warning
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/206
	 * <br>
	 * <br>Revision 1.9  2010-06-10 12:20:11  troth
	 * <br>fix small bug - how set the save button aktiv
	 * <br>
	 * <br>Revision 1.8  2010-06-09 14:36:45  troth
	 * <br>implement old feature - double click on prescription template put text directly in the prescription - add blank line after every template
	 * <br>
	 * <br>Revision 1.7  2010-06-09 14:15:55  troth
	 * <br>implement old feature - double click on prescription template put text directly in the prescription
	 * <br>
	 * <br>Revision 1.6  2010-06-09 12:26:06  troth
	 * <br>fix small bugs - dialog behavior of ok and canel button
	 * <br>
	 * <br>Revision 1.5  2010-06-08 14:31:57  troth
	 * <br>rebuild of the PrescriptionTemplatePanel and the PrescriptionTemplateTabelModel
	 * <br>
	 * <br>Revision 1.4  2010-06-02 11:29:05  troth
	 * <br>redesign of Prescription Template Editor - # 519: Speicherverhalten der Verschreibungstemplates
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/519
	 * <br>
	 * <br>Revision 1.3  2010-05-19 14:18:09  troth
	 * <br>add form and dose to the drug text - Incomplete - # 508: CeFIP Liste: Benutzung von Name, Form und Dosis bei der Verschreibung
	 * <br>http://santec.tudor.lu/trac/gecamed/ticket/508
	 * <br>
	 * <br>Revision 1.2  2010-05-10 15:09:07  troth
	 * <br>add template search function in template dialog
	 * <br>
	 * <br>Revision 1.1  2010-04-26 16:51:09  troth
	 * <br>Redesign of the prescription view - all prescription class and new package
	 * <br>
	 * <br>Revision 1.12  2010-04-01 11:04:36  troth
	 * <br>fixed bug open templateEditor with 0 templates
	 * <br>
	 * <br>Revision 1.11  2010-03-30 11:06:06  troth
	 * <br>Redesign of the prescription view - PrescriptionTemplatePanelNew extends now from GECAMedBaseDialog
	 * <br>
	 * <br>Revision 1.10  2009-05-13 12:57:22  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.9  2009-04-15 13:30:41  heinemann
	 * <br>added cefip and posology button to template editor
	 * <br>
	 * <br>Revision 1.8  2009-04-03 13:22:38  heinemann
	 * <br>*** empty log message ***
	 * <br>
	 * <br>Revision 1.7  2009-03-24 11:10:09  heinemann
	 * <br>Ticket #270 make shortcut column in presc templates resizable
	 * <br>fixed.
	 * <br>the width of the column is now saved in the user settings.
	 * <br>
	 * <br>Revision 1.6  2009-02-16 13:02:30  heinemann
	 * <br>removed ok/cancel buttons of the dialog
	 * <br>
	 * <br>Revision 1.5  2009-02-09 15:07:41  heinemann
	 * <br>user can delete prescription templates
	 * <br>
	 * <br>Revision 1.4  2009-02-09 11:21:23  heinemann
	 * <br>fixed bug in date of represcribed prescription
	 * <br>
	 * <br>behaviiour of template selector changed: double click appends template content to the prescritpiont. Window stays visible until "close" button pressed
	 * <br>
	 *   
	 */
	public class ObservableText extends Observable {
		
		private String text = "";
		
		public ObservableText() {}
		
		/**
		 * Clears the string. Observers are not notified
		 */
		public void clear() {
			this.text = "";
		}
		
		public String toString() {
			return this.text;	
		}
		
		public void setText(String txt) {
			this.text = txt;
			this.setChanged();
			
			notifyObservers();
		}
	}


	public void keyTyped(KeyEvent e) {}
	public void keyPressed(KeyEvent e) {}

	public void keyReleased(KeyEvent e)
	{
		if (e.getKeyChar() == '[')
			completion.doCompletion();
	}
}