/*****************************************************************************
 *                                                                           *
 *  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.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
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.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
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.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.AutoCompletion;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
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.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.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Incident;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.PatientPanel;
import lu.tudor.santec.gecamed.patient.gui.incident.AccidentPanel;
import lu.tudor.santec.gecamed.patient.gui.incident.AccidentRelationDialog;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.Prescription;
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.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.gecamed.usermanagement.gui.settings.UserSettingsPlugin;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.org.fife.ui.autocomplete.AutoCompletionTextComponent;
import lu.tudor.santec.org.fife.ui.autocomplete.MWCompletionProvider;
import lu.tudor.santec.widgets.gui.ButtonFactory;
import lu.tudor.santec.widgets.gui.form.FormPanel;
import bizcal.util.DateUtil;

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


/**
 * The panel to show the prescriptions of a patient in the visit and medical history.
 * It contains a prescription editor to create, modify and delete prescriptions.
 * It is used by the in incident, history panel and as prescription dialog.
 * 
 * @author Thorsten Roth thorsten.roth(at)tudor.lu
 *
 * @version
 * <br>$Log: PrescriptionDataPanel.java,v $
 * <br>Revision 1.39  2013-11-08 08:41:27  ferring
 * <br>dead code outcommented
 * <br>
 * <br>Revision 1.38  2013-05-21 11:48:08  troth
 * <br>Ticket #1191 fixed
 * <br>
 * <br>Revision 1.37  2012-12-18 15:47:08  troth
 * <br>Fix Ticket #1120.
 * <br>
 * <br>Revision 1.36  2012-10-08 14:06:36  troth
 * <br>Fix Ticket #530.
 * <br>
 * <br>Revision 1.35  2012-07-26 14:26:11  troth
 * <br>fix Ticket #1012.
 * <br>
 * <br>Revision 1.34  2012-07-24 10:06:26  troth
 * <br>fix Ticket #1012 now the text is insert on the text cursor position of the textfield.
 * <br>
 * <br>Revision 1.33  2012-07-23 12:09:41  troth
 * <br>fix Ticket #1011 and #1012
 * <br>
 * <br>Revision 1.32  2011-08-17 08:42:45  ferring
 * <br>Scrolling bug of autocompleter fixed
 * <br>
 * <br>Revision 1.31  2011-05-11 12:30:14  ferring
 * <br>Scrollbar of prescription text area is now shown the whole time
 * <br>
 * <br>Revision 1.30  2011-04-26 08:33:56  ferring
 * <br>AutoCompletion changed to GECAMedAutoCompletion
 * <br>
 * <br>Revision 1.29  2011-04-14 06:22:30  ferring
 * <br>auto completion used for prescription
 * <br>
 * <br>Revision 1.28  2011-03-30 09:48:16  ferring
 * <br>auto completion added for prescription panel
 * <br>
 * <br>Revision 1.27  2010-11-15 10:26:38  troth
 * <br>add new user option 'open new prescription after saving/printing'
 * <br>
 * <br>Revision 1.26  2010-11-10 10:47:33  troth
 * <br>Small bug fix in login dialog some objects was not init
 * <br>
 * <br>Revision 1.25  2010-10-11 08:47:38  troth
 * <br>add revised UndoTextArea/UndoTextField to the text fields in consultations view
 * <br>
 * <br>Revision 1.24  2010-10-08 08:21:05  troth
 * <br>Bugfix - implement enable- disable- switch for the action listener of the physician box to causes no endless loop by the function setCurrentPhysician
 * <br>
 * <br>Revision 1.23  2010-10-06 09:24:39  troth
 * <br>Complete - # 549: Undo Funktion f�r ge�nderten Verschreibungstext
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/549
 * <br>
 * <br>Revision 1.22  2010-10-05 13:42:43  troth
 * <br>Complete - # 560: Arztwechsel im Verschreibungs-Dialogfenster erm�glichen
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/560
 * <br>
 * <br>Revision 1.21  2010-09-07 12:46:23  troth
 * <br>Incomplete - # 629: Automatisches �berschreiben von Unfall-Nummer/Datum durch Dialog-verschreibung
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/629
 * <br>
 * <br>Revision 1.20  2010-09-06 14:29:22  troth
 * <br>Incomplete - # 625: Unfalldatum nicht angezeigt in Dialog-Verschreibungsfenster
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/625
 * <br>
 * <br>Revision 1.19  2010-09-01 12:05:31  troth
 * <br>Bugfix - get incident from incident model not from incident control for prescription in the setPrescription function.
 * <br>
 * <br>Revision 1.18  2010-08-31 13:35:56  troth
 * <br>Incomplete - # 495: Mehrere Unstimmigkeiten mit Unfallnummer (auch #529)
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/495
 * <br>and Tickets 529, 613
 * <br>and new/redesign of AccidentPanel
 * <br>
 * <br>Revision 1.17  2010-08-17 12:32:33  troth
 * <br>add  accident button in prescription dialog to show accident dialog to choose a accident of a patient
 * <br>
 * <br>Revision 1.16  2010-08-16 14:32:04  troth
 * <br>Incomplete - # 599: Keep prescription history stable when consultation tabs are clicked
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/599
 * <br>
 * <br>Revision 1.15  2010-07-28 12:39:52  troth
 * <br>fix bug now line of the open prescription entry in the history table of every open prescriptionpanel is colored not only the current.
 * <br>
 * <br>Revision 1.14  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.13  2010-07-20 14:18:49  troth
 * <br>add function for colored the line of the open prescription entry in the history table
 * <br>
 * <br>Revision 1.12  2010-07-05 08:23:24  troth
 * <br>Small bug fix - # 550: Save Prescription by printing
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/550
 * <br>
 * <br>Revision 1.11  2010-06-17 09:59:33  troth
 * <br>small bug fix - # 533: Drucken sollte erst nach Abspeichern einer Verschreibung m�glich sein
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/533
 * <br>
 * <br>Revision 1.10  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.9  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.8  2010-05-27 13:59:12  troth
 * <br>update print button function
 * <br>
 * <br>Revision 1.7  2010-05-27 12:22:13  troth
 * <br>Incomplete - # 516: Erzeugen leerer Verschreibungen mit der Druck-Funktion
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/516
 * <br>Incomplete - # 517: Falsche Aktion im Speicher-Dialog f�r Verschreibungen beim Schliessen des Dialog-Fensters
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/517
 * <br>
 * <br>Revision 1.6  2010-05-26 16:33:34  troth
 * <br>bugfix - change the way to get a new and create a incident. rename the method getRecentIncident() in class PatientPanel to getCurrentIncident()
 * <br>
 * <br>Revision 1.5  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.4  2010-05-18 13:20:35  troth
 * <br>fix save function of represcribe - Incomplete - # 504: Kein direktes Abspeichern nach Neuverschreibung m�glich
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/504
 * <br>
 * <br>Revision 1.3  2010-05-17 15:24:34  troth
 * <br>Incomplete - # 491: Inkonsistenter Zustand nach L�schen einer verschreibung
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/491
 * <br>
 * <br>Revision 1.2  2010-05-07 08:59:35  troth
 * <br>edit call of function getRecentIncident() because the function getRecentIncident() move from class PrescriptionDataModel to PatientPanel
 * <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>
 */
public class PrescriptionDataPanel extends JPanel implements ActionListener, PrescriptionDataListener {
	
	private static final long serialVersionUID = 1L;

	private JButton resizeButton;

	private JButton printButton;

	private JButton addButton;

	private JButton saveButton;

	private JDateChooser dateChooser;

	private JDateChooser expiryDateChooser;

	private AccidentPanel accidentPanel;
	
	private UndoTextArea textArea;
	
	private CellConstraints cc;
	
	private boolean isPanel;
	
	private boolean windowMode = false;

	private ModuleHeader headerPanel;

	private JPanel leftPanel;

	private JPanel rightPanel;
	
	private JPanel actionButtonPanel;

	private FormPanel sideBarButtonBar;

	private JPanel datePanel;
	
	private PrescriptionDataModel prescriptionDataModel;

	private PatientPanel patientPanel;
	
	private PrescriptionTemplatePanel templateDialog;
	
	private ActionListener templateButtonListener;

	private Document currentPrescriptionDocument;

	private PrescriptionHistoryView prescriptionHistoryView;
	
	private AdjustmentListener scrollPaneListener;

	private JPanel physicianPanel;
	
	private JComboBox<Physician> physicianBox;
	
	private DefaultComboBoxModel<Physician> physicianComboBoxModel;
	
	private Border selectedBorder = BorderFactory.createLineBorder(Color.BLUE, 2);

	// Template Button CMD
	private static final String CMD_CEFIP = "cefip";
	
	private static final String CMD_POSOLOGY = "posology";
	
	private static List<PrescriptionTemplatePanel> templateDialogs = new ArrayList<PrescriptionTemplatePanel>();
	
	private static HashMap<String, Icon> actionIconMap = new HashMap<String, Icon>();
	
	private Boolean listenerActive = true;
	
	// init the icon mapping for the types
	static {
		/* ------------------------------------------------------- */
		actionIconMap.put(PrescriptionType.MEDICINE, 		PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_DRUG));
		actionIconMap.put(PrescriptionType.BIOLOGY,  		PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_BIO));
		actionIconMap.put(PrescriptionType.RADIOGRAPHY, 	PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_RADIO));
		actionIconMap.put(PrescriptionType.CERIFICATS, 		PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_CERT));
		actionIconMap.put(PrescriptionType.PHYSIOTHERAPY, 	PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_PHYSIO));
		actionIconMap.put(PrescriptionType.NURSING, 	  	PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_NURSE));
		actionIconMap.put(PrescriptionType.TRANSFERALS, 	PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRSC_TRANS));
		/* ------------------------------------------------------- */
	}
	
	
	/**
	 * @param isPanel if true PrescriptionDataPanel is panel else the panel is in a dialog
	 * @param prescriptionDataModel the prescriptionDataModel
	 * @param patientPanel the patientpanel
	 */
	public PrescriptionDataPanel(boolean isPanel, PrescriptionDataModel prescriptionDataModel, PatientPanel patientPanel) {
		this.isPanel = isPanel;
				
		this.prescriptionDataModel = prescriptionDataModel;
		this.currentPrescriptionDocument = this.prescriptionDataModel.getCurrentPrescriptionDocument();
		
		this.patientPanel = patientPanel;
		
		// init prescription template editor dialog
		this.templateDialog = PrescriptionTemplatePanel.getInstance();
		templateDialogs.add(templateDialog);
		
		// reload the templates of all types
		for (PrescriptionType type : PrescriptionUtils.getPrescriptionTypes())
			reloadTemplates(type.getName(), this.templateDialog);
		
		initComponents();
		buildPanel();		
		prescriptionDataModel.addModelListener(this);
	}

	
	/**
	 * init components
	 */
	private void initComponents() {
		// elements of the importantPanel on top
		this.resizeButton   = ButtonFactory.createEffectButton(PrescriptionIcons.getScaledIcon(PrescriptionIcons.RESIZE_WINDOW,32)); 
		this.printButton	= ButtonFactory.createEffectButton(PrescriptionIcons.getIcon(PrescriptionIcons.PRINT));
		this.printButton.setEnabled(false);
		//this.closeButton	= ButtonFactory.createEffectButton(GECAMedModule.getIcon(GECAMedIconNames.CLOSE));
		this.addButton		= ButtonFactory.createEffectButton(GECAMedModule.getScaledIcon(GECAMedIconNames.ADD,32));
		this.saveButton 	= ButtonFactory.createEffectButton(GECAMedModule.getIcon(GECAMedIconNames.SAVE));
		this.saveButton.setEnabled(false);
		
		/* ------------------------------------------------------- */
		this.resizeButton.setToolTipText(Translatrix.getTranslationString("prescription.name.resize"));
		this.printButton.setToolTipText(Translatrix.getTranslationString("prescription.buttons.print"));
		//this.closeButton.setToolTipText(Translatrix.getTranslationString("prescription.buttons.close"));
		this.addButton.setToolTipText(Translatrix.getTranslationString("prescription.buttons.addPrescription"));
		this.saveButton.setToolTipText(Translatrix.getTranslationString("prescription.core.save"));
		
		/* ------------------------------------------------------- */
		this.resizeButton.addActionListener(this);
		this.printButton.addActionListener(this);
		//this.closeButton.addActionListener(this);
		this.addButton.addActionListener(this);
		this.saveButton.addActionListener(this);
		
		/* ------------------------------------------------------- */
		// the action button panel
		/* ------------------------------------------------------- */
		this.actionButtonPanel = new JPanel(new GridLayout(0, 2, 15, 15));
		this.actionButtonPanel.setOpaque(false);
		
		/* ------------------------------------------------------- */
		// the date chooser components
		/* ------------------------------------------------------- */
		this.dateChooser = GECAMedGuiUtils.getDateChooser(false);
		this.expiryDateChooser = GECAMedGuiUtils.getDateChooser(false);
		
		// dateChooser Listener 
		this.dateChooser.getCalendarButton().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				prescriptionDataModel.prescriptionChanged(true);
			}
		});
		// expiryDateChooser Listener
		this.expiryDateChooser.getCalendarButton().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				prescriptionDataModel.prescriptionChanged(true);
			}
		});
		
		/* ------------------------------------------------------- */
		// the accident components
		/* ------------------------------------------------------- */
		this.accidentPanel = new AccidentPanel();
		
		// add ActionListener to DateChooser Button of accidentPanel
		this.accidentPanel.getAccidentDateChooser().getCalendarButton().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				prescriptionDataModel.prescriptionChanged(prescriptionDataModel.getCurrentPrescriptionDocument().getLength() > 0);
			}
		});
		
		// add ActionListener to accidentSelectionButton of accidentPanel
		this.accidentPanel.getAccidentSelectionButton().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				prescriptionDataModel.prescriptionChanged(prescriptionDataModel.getCurrentPrescriptionDocument().getLength() > 0);
				showAccidentDialog();
			}
		});
		
		// add KeyListener to accident number field of accidentPanel
		this.accidentPanel.getAccidentNumberTextField().addKeyListener(new KeyListener() {
			
			public void keyTyped(KeyEvent e) {}
			public void keyReleased(KeyEvent e) {
				prescriptionDataModel.prescriptionChanged(prescriptionDataModel.getCurrentPrescriptionDocument().getLength() > 0);	
			}
			public void keyPressed(KeyEvent e) {}
		});
		// add MouseListener to accidentCheckBox of accidentPanel
		this.accidentPanel.getAccidentCheckBox().addMouseListener(new MouseListener() {
			
			public void mouseReleased(MouseEvent e) {
				prescriptionDataModel.prescriptionChanged(prescriptionDataModel.getCurrentPrescriptionDocument().getLength() > 0);
			}
			public void mousePressed(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseClicked(MouseEvent e) {}
		});
		
		this.cc = new CellConstraints();
	}
	
	
	/**
	 * build the gui of the panel 
	 */
	private void buildPanel() {
		this.setLayout(new FormLayout(	
				// cols
				"3dlu,fill:pref,3dlu,fill:8dlu:grow,3dlu", 
				// rows
				"3dlu,fill:pref,7dlu,fill:pref:grow,3dlu"));
		
		buildHeaderPanel();
		buildRightPanel();
		
		if (this.isPanel) {
			buildSidebarButtonPanel();
		}else {
			buildLeftPanel();
		}
		this.initButtons();
		/* ------------------------------------------------------- */
		this.headerPanel.setColor(GECAMedColors.c_GECAMedBackground);
		this.add(this.headerPanel,	cc.xyw(2, 2, 3));
		this.add(this.leftPanel,		cc.xy(2, 4));
		this.add(this.rightPanel,		cc.xy(4, 4));
		/* ------------------------------------------------------- */
		this.setBackground(GECAMedColors.c_GECAMedBackground);
		/* ======================================================= */
	}
	
	
	/**
	 * build the header
	 */
	private void buildHeaderPanel() {
		// ==================================================
		this.headerPanel = new ModuleHeader(Translatrix.getTranslationString("prescription.name"),PrescriptionIcons.getScaledIcon(PrescriptionIcons.PRSC_DRUG,32), GECAMedColors.c_GECAMedBackground);
		this.headerPanel.addButton(this.printButton);
		if(this.isPanel) this.headerPanel.addButton(this.resizeButton); // not use in dialog
		//this.headerPanel.addButton(this.closeButton);
		this.headerPanel.addButton(this.addButton);
		this.headerPanel.addButton(this.saveButton);
		// ==================================================
	}
	
	
	/**
	 *  build the actionbuttonsbar for the panel 
	 */
	private void buildSidebarButtonPanel() {	
		this.sideBarButtonBar = new FormPanel();
		this.sideBarButtonBar.setBackground(Color.WHITE);
		this.leftPanel = new JPanel(new FormLayout("1dlu,fill:pref,1dlu", "0dlu,fill:pref,pref:grow"));
		this.leftPanel.add(this.sideBarButtonBar, cc.xy(2, 2));
		this.leftPanel.setOpaque(false);
	}
	
	
	/**
	 * init the button actionlistener 
	 */
	private void initButtons() {
		this.templateButtonListener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				String txt = null;
				
				if (CMD_CEFIP.equals(e.getActionCommand())) {
					/* ------------------------------------------------------- */
					// open drug browser
					/* ------------------------------------------------------- */
					DrugBrowser db = DrugBrowser.getInstance();
					IDrug drug = db.showDialog(WindowToolbox.getOwnerFrame((Component) e.getSource()), "");
					
					if (drug != null)
						txt = drug.getName() + ", " + drug.getApplicationForm() + ", " + drug.getDose() + " ";
					/* ------------------------------------------------------- */
				} else if (CMD_POSOLOGY.equals(e.getActionCommand())) {
					/* ------------------------------------------------------- */
					PosologyChooserDialog pc = PosologyChooserDialog.getInstance();
					
					if (!isPanel)
					{
						txt = pc.showDialog(WindowToolbox.getOwnerFrame((Component) e.getSource()));
					}else{
						txt = pc.showDialog(MainFrame.getInstance());
					}
					/* ------------------------------------------------------- */
				} else {
					/* ------------------------------------------------------- */
					templateDialog.getTableModel().setType(e.getActionCommand());
					
					Document currentPrescriptionDocument = prescriptionDataModel.getCurrentPrescriptionDocument();
					
					if (!isPanel) {
						txt = templateDialog.showDialog(WindowToolbox.getOwnerFrame((Component) e.getSource()), currentPrescriptionDocument);
					}else{
						txt = templateDialog.showDialog((Window)MainFrame.getInstance(), currentPrescriptionDocument);
					}
				}
				
				if (txt != null) {
					// append the text of the template to the current prescription
//					appendText(txt);
					// insert the text of the template to the current prescription
					insertText(txt);
				}				
			}
		};
		
		// add the template buttons
		List<PrescriptionType> types = PrescriptionUtils.getPrescriptionTypes();
		if (types != null) 
			for (PrescriptionType type : types) {
				JButton button = this.addActionButton(Translatrix.getTranslationString("prescription.name." +type.getName()),
										actionIconMap.get(type.getName()),
										type.getName());
				button.addActionListener(this.templateButtonListener);
			}
		
		// add the cefip and posology button
		this.addActionButton(Translatrix.getTranslationString("prescription.buttons.cefip"),
				PrescriptionIcons.getMediumIcon(PrescriptionIcons.CEFIP_ICON),
				CMD_CEFIP).addActionListener(this.templateButtonListener);
		
		this.addActionButton(Translatrix.getTranslationString("prescription.buttons.posology"),
				PrescriptionIcons.getMediumIcon(PrescriptionIcons.PRESCRIPTION_MODULE),
				CMD_POSOLOGY).addActionListener(this.templateButtonListener);
	}
	
	
	/**
	 * Creates and adds a new JButton to the action panel.
	 * 
	 * @param title
	 * @param icon
	 * @return the new button.
	 */
	public JButton addActionButton(String title, Icon icon, String actionCmd) {
		/* ================================================== */
		JButton b = null;
		/* ------------------------------------------------------- */
		if (this.isPanel) {
			/* ------------------------------------------------------- */
			b = ButtonFactory.createNarrowButton(icon);
			b.setActionCommand(actionCmd);
			b.setToolTipText(title);
			this.sideBarButtonBar.addLine(b);
			/* ------------------------------------------------------- */
		}
		else {
			/* ------------------------------------------------------- */
			b = ButtonFactory.create2LineButton(title, icon);
			b.setActionCommand(actionCmd);
			b.setToolTipText(title);
			this.actionButtonPanel.add(b);
			/* ------------------------------------------------------- */
		}
		
		return b;
		/* ================================================== */
	}
	
	
	/**
	 * build the right side of the panel with the text area and historyview
	 */
	private void buildRightPanel() {
		// ===============================================================
		this.rightPanel = new JPanel();
		rightPanel.setLayout(new BorderLayout());
		rightPanel.setOpaque(false);
		// ===============================================================
		// the view will consist of one Splitpanes.
		// ===============================================================
		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		splitPane.setOneTouchExpandable(false);
		splitPane.setOpaque(false);

		// ===============================================================
		// create the panel for editing prescriptions
		// ===============================================================
		this.textArea  = new UndoTextArea(this.prescriptionDataModel.getCurrentPrescriptionDocument(),new UndoManager());
		this.textArea.setDocument(this.prescriptionDataModel.getCurrentPrescriptionDocument());
		this.textArea.setLineWrap(true);
		this.textArea.setWrapStyleWord(true);
//		JScrollPane scrollPane = new JScrollPane(this.textArea);
		AutoCompletionTextComponent actc = new GECAMedAutoCompletionTextComponent (textArea, GECAMedAutoCompletionHandler.PRESCRIPTION_CONTEXT);
		actc.setSearchMode(MWCompletionProvider.SEARCH_MODE_BOTH);
		splitPane.setTopComponent(actc);
		splitPane.setDividerSize(8);
		splitPane.setDividerLocation(160);
		rightPanel.add(splitPane);

		// ===============================================================
		// create the panel for the history view
		// ===============================================================
		prescriptionHistoryView = new PrescriptionHistoryView(this.patientPanel);
		prescriptionHistoryView.setBorder(null);
		
		
		this.scrollPaneListener =	new AdjustmentListener(){

			public void adjustmentValueChanged(AdjustmentEvent evt) {
			
				if (evt.getValueIsAdjusting()) {
					return;
				}
				int type = evt.getAdjustmentType();
				
				switch (type) {
				case AdjustmentEvent.UNIT_INCREMENT:
					// scrollbar was increased by one unit
					break;
				case AdjustmentEvent.UNIT_DECREMENT:
					// scrollbar was decreased by one unit
					break;
				case AdjustmentEvent.BLOCK_INCREMENT:
					// scrollbar was increased by one block
					break;
				case AdjustmentEvent.BLOCK_DECREMENT:
					// scrollbar was decreased by one block
					break;

				case AdjustmentEvent.TRACK:
					// the knob on the scrollbar was dragged
					prescriptionDataModel.setScrollPaneValue(evt.getValue(),prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().getMaximum());
					break;
				}
			}
		};
		prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().addAdjustmentListener(this.scrollPaneListener);
		splitPane.setBottomComponent(prescriptionHistoryView);
	}

	
	/**
	 * build the left side of the panel and the date panel for the dialog
	 */
	private void buildLeftPanel() {
		
		this.leftPanel = new JPanel(new BorderLayout(10, 10));
		this.leftPanel.setOpaque(false);
		
		
		// the panel for the date forms and accident
		this.datePanel = new JPanel(new FormLayout(
				// cols
				"pref:grow," +
				"pref:grow",
				// rows
				"3dlu," +
				"fill:pref," +
				"7dlu," +
				"fill:pref," +
				"3dlu"));
		
		datePanel.setOpaque(false);
		datePanel.setBorder(BorderFactory.createTitledBorder(""));
		
		
		
		this.datePanel.add(new NamedComponent(Translatrix.getTranslationString("prescription.name.date"),
												this.dateChooser), cc.xy(1, 2));
		this.datePanel.add(new NamedComponent(Translatrix.getTranslationString("prescription.name.expirydate"),
												this.expiryDateChooser), cc.xy(2, 2));
		
		this.datePanel.add(this.accidentPanel, cc.xyw(1, 4, 2));
		
		// the panel for the physician combobox
		this.physicianPanel = new JPanel(new FormLayout(
				// cols
				"pref:grow",
				// rows
				"3dlu," +		// 1
				"fill:pref," +	// 2 physician combobox
				"3dlu"));		// 3
		
		physicianPanel.setOpaque(false);
		physicianPanel.setBorder(BorderFactory.createTitledBorder(""));
		
        // create physician array
//        Physician[] phys = ((OfficeManagerInterface) ManagerFactory.getRemote(OfficeManagerBean.class))
//        	.getAllPhysicians().toArray(new Physician[0]);
        Vector<Physician> phys = new Vector<Physician>(GECAMedLists.getListReference(Physician.class));
        // create physician combobox
        physicianComboBoxModel = new DefaultComboBoxModel<Physician>(phys);
        physicianBox = new JComboBox<Physician>(physicianComboBoxModel);
        physicianBox.setFont(physicianBox.getFont().deriveFont(Font.BOLD,16));
        physicianBox.setOpaque(true);
        physicianBox.setToolTipText(Translatrix.getTranslationString("main.selectCurrentPhysician"));        
        
        initPhysicianCombobox();
        
        if(physicianBox.getSelectedItem() != null)
        	physicianBox.setBackground(new Color(((Physician) physicianBox.getSelectedItem()).getColor()));
        
        if (phys.size() > 5) {
        	AutoCompletion.enable(physicianBox);
        	try {
        		((JTextComponent)physicianBox.getEditor().getEditorComponent()).setOpaque(false);        	
        	} catch (Exception e) {}      	
        }
        
		if (!GECAMedModule.userHasPermission(MainFrame.PERMISSIONS_CORE, MainFrame.PERMISSION_CHANGE_PHYSICIAN)) {
			physicianBox.setEnabled(false);
		}
        
        physicianBox.setRenderer(new DefaultListCellRenderer() {
			private static final long serialVersionUID = 1L;
			@Override
			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
				
				JLabel c = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected,
						cellHasFocus);
				c.setOpaque(true);
				try {
        		        	if (isSelected) {
        		        	    c.setBackground(new Color(((Physician)value).getColor()).brighter());
        		        	    c.setBorder(selectedBorder);
        		        	}
        		        	else {
        		        	    c.setBackground(new Color(((Physician)value).getColor()));
        		        	    c.setBorder(null);
        		        	}
				} catch (Exception e) {
					c.setBackground(new JLabel().getBackground());
				}
				return c;
			}
        });
                
        // ActionListener for the physician combobox
    	physicianBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(listenerActive)
				{
					// set background color of physician combobox
					physicianBox.setBackground(new Color(((Physician) physicianBox.getSelectedItem()).getColor()));
					MainFrame.setCurrentPhysician((Physician)physicianBox.getSelectedItem());
				}
			}
		});
        
        // add physicianBox to panel
		this.physicianPanel.add(physicianBox, cc.xy(1, 2));
		
		JPanel metaPanel = new JPanel(new FormLayout(
				// cols
				"fill:pref:grow",
				// rows
				"fill:pref," +	// 1 datePanel
				"10dlu," +		// 2
				"fill:pref," +	// 3 physicianPanel
				"10dlu," +		// 4
				"fill:pref"		// 5 actionButtonPanel
				));
		
		metaPanel.add(this.datePanel, cc.xy(1, 1));
		metaPanel.add(this.physicianPanel, cc.xy(1, 3));
		metaPanel.add(this.actionButtonPanel, cc.xy(1, 5));   
		metaPanel.setOpaque(false);
		this.leftPanel.add(metaPanel, BorderLayout.CENTER);
	}
	
	/**
	 * set the initial physician if the current user has a link to a physician, select it.
	 */
	public void initPhysicianCombobox() {
		// create physician array
		this.listenerActive = false;
		this.physicianBox.setSelectedItem(MainFrame.getCurrentPhysician());
		this.listenerActive = true;
//		MainFrame.setCurrentPhysician((Physician)physicianBox.getSelectedItem());
//		Physician[] phys = ((OfficeManagerInterface) ManagerFactory.getRemote(OfficeManagerBean.class))
//        	.getAllPhysicians().toArray(new Physician[0]);
//        
//		// set the initial physician
//		// if the current user has a link to a physician, select it
//		if (phys != null) {
//			for (int i = 0; i < phys.length; i++) {
//				if (MainFrame.getCurrentUser().getId().equals(
//						phys[i].getUserId())) {
//					// select the physician in the combobox
//					physicianBox.setSelectedItem(phys[i]);
//					break;
//				}
//			}
//		}
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		// save button prescription editor
		if (this.saveButton.equals(e.getSource())) {
			if(PatientManagerModule.getInstance().isModified()) PatientManagerModule.getInstance().savePatientAction();
			else{
				this.prescriptionDataModel.saveData();
				// show new prescription after save/print function if user setting is true
				if ((Boolean)MainFrame.getInstance().userSettings.getValue(UserSettingsPlugin.OPEN_NEW_PRESCRIPTION_ENABLED))
					this.prescriptionDataModel.setPrescription(new Prescription());
			}
		}else
			// print button prescription editor
			if (this.printButton.equals(e.getSource())) {
				this.prescriptionDataModel.saveData();
				printAction(this.prescriptionDataModel.getPrescription());
				// show new prescription after save/print function if user setting is true
				if ((Boolean)MainFrame.getInstance().userSettings.getValue(UserSettingsPlugin.OPEN_NEW_PRESCRIPTION_ENABLED))
					this.prescriptionDataModel.setPrescription(new Prescription());
			}else
				// add button prescription editor
				if (this.addButton.equals(e.getSource())) {
					this.prescriptionDataModel.setPrescription(new Prescription());
				}else
					// prescriptionEditorPanel Resize Button
					if (this.resizeButton.equals(e.getSource())) {
						this.patientPanel.getPrescriptionDialog().showDialog();
					}
	}
	

	/**
	 * Loads the list of templates for the type and user
	 * 
	 * @param type of template
	 * @param panel the templatepanel
	 */
	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 = getManager().getTemplates(type, phyId);
			
			panel.getTableModel().setData(type, list);
			panel.getTableModel().fireTableDataChanged();
		} catch (Exception e) {
			e.printStackTrace();	
		}
	}

	
	/**
	 *
	 * Get a reference to the prescription manager session bean
	 *
	 * @return
	 */
	protected PrescriptionManager getManager() {
		return (PrescriptionManager)
			ManagerFactory.getRemote(PrescriptionManagerBean.class);
	}
	
	
	/**
	 * Appends a string to the text of the currentPrescriptionDocument
	 * 
	 * @param text
	 */
	public void appendText(String text) {
		String ptext = null;
		
		if (text == null || "".equals(text.trim()))
			return;
		
		try {
			
			ptext = this.prescriptionDataModel.getCurrentPrescriptionDocument().getText(0, this.prescriptionDataModel.getCurrentPrescriptionDocument().getLength());
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
		if (ptext == null || "".equals(ptext.trim()))
			ptext = ptext + text;
		else
			ptext = ptext + " " + text;
		try {
			this.currentPrescriptionDocument.remove(0,
					this.currentPrescriptionDocument.getLength());
			this.currentPrescriptionDocument.insertString(
					0,
					ptext, 
					new SimpleAttributeSet());
			
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Insert a string to the current textcursor position in text of the currentPrescriptionDocument
	 * 
	 * @param text
	 */
	public void insertText(String text)
	{
		int textFieldPosition = this.textArea.getCaretPosition();
		if(textFieldPosition > 0)
		{
			String areaText = this.textArea.getText();
			if(!("" + areaText.charAt(textFieldPosition - 1)).equals("\n") && !("" + areaText.charAt(textFieldPosition - 1)).equals(" ")) text = " " + text;
		}
		try {
			this.currentPrescriptionDocument.insertString(textFieldPosition, text, new SimpleAttributeSet());
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * update the fields of the prescriptionpanel
	 */
	public void updatePrescription(Incident incident) {
		Prescription currentPrescription = this.prescriptionDataModel.getPrescription();
		
		if (this.dateChooser.getDate() != null) {
			// if the date is today, we add the time of now
			if (DateUtil.isSameDay(this.dateChooser.getDate(), new Date()))
				currentPrescription.setPrescriptionDate(new Date());
			else
				currentPrescription.setPrescriptionDate(dateChooser.getDate());
		}
		else
			currentPrescription.setPrescriptionDate(new Date());
			
			currentPrescription.setExpiryDate(this.expiryDateChooser.getDate());
			
			/* ------------------------------------------------------- */
			// accident data. if panel is disabled, we remove the accident data
			/* ------------------------------------------------------- */
			
			if (this.accidentPanel.isAccident()) {	
				currentPrescription.setAccidentDate(this.accidentPanel.getAccidentDate());
				currentPrescription.setAccidentNr(this.accidentPanel.getAccidentNumber());
			}else{
				currentPrescription.setAccidentDate(null);
				currentPrescription.setAccidentNr(null);
			}
				
			// set accident new form incident if panel is not in window mode
			if (incident.getIsAccident() && (!this.windowMode) && (currentPrescription.getAccidentDate() == null) && (currentPrescription.getAccidentNr() == null) ) {
				currentPrescription.setAccidentDate(incident.getAccidentDate());
				currentPrescription.setAccidentNr(incident.getAccidentNr());
			}
	}
	
	
	/**
	 * @return the accidentpanel
	 */
	public AccidentPanel getAccidentPanel() {
		return this.accidentPanel;
	}
	
	
	/**
	 * @return the DateChosser
	 */
	public JDateChooser getDateChooser() {
		return this.dateChooser;	
	}
	
	
	/**
	 * @return true if an accident is activated in the editor
	 */
	public boolean isAccident() {
		return this.accidentPanel.isAccident();
	}
	
	
	/**
	 * Prints the prescription
	 * 
	 * @param p the prescription
	 */
	private void printAction(Prescription p) {
		PrescriptionUtils.printPrescription(PatientManagerModule.getInstance().getPatientPanel().getCurrentIncident(), p, new JDialog());		
	}

	
	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.prescription.gui.editor.PrescriptionDataListener#prescriptionModified()
	 */
	public void prescriptionModified() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				saveButton.setEnabled(true);
				printButton.setEnabled(true);
				headerPanel.setColor(GECAMedColors.c_ModifiedTitleBackground);
				if(patientPanel != null) patientPanel.setModified(true);
			}
		});
	}

	
	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.prescription.gui.editor.PrescriptionDataListener#prescriptionSaved()
	 */
	public void prescriptionSaved() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				saveButton.setEnabled(false);
				if(textArea.getText().equals("")) printButton.setEnabled(false);
				else printButton.setEnabled(true);
				headerPanel.setColor(GECAMedColors.c_GECAMedBackground);
				if(patientPanel != null) patientPanel.setModified(patientPanel.isModified());
			}
		});
	}
	
	
	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.prescription.gui.editor.PrescriptionDataListener#setPrescription(lu.tudor.santec.gecamed.prescription.ejb.entity.beans.Prescription)
	 */
	public void setPrescription(Prescription prescription) {
				
		// no accident
		this.accidentPanel.setAccident(false);
		this.accidentPanel.setAccidentDate(null);
		this.accidentPanel.setAccidentNumber("");
		
		
		Incident incident = null;
		String accidentNumber = null;
		Date accidentDate = null;
//		try {
//			// get incident form selected tab in consultation
//			incident = PatientManagerModule.getInstance().getPatientPanel()
//					.getIncidentTab().getCurrentPanel().getControler().getIncidentModel().getIncidentForPrescription();
//		} catch (Exception e) {
//		}
		
		// get incident
		if(prescription.getIncidentId() != null)
		{
			// get Incident from prescription
			incident = prescription.getIncidentEntry().getIncident();
		} else {
			try {
				// get current Incident if one ist open
				incident = PatientManagerModule.getInstance().getPatientPanel().getCurrentIncident(false);
			} catch (Exception e) {
			}
		}
		
		// get accident data form incident if incident have a accident
		if (incident != null) {
			if (incident.getIsAccident()) {
				
				// set current prescription
				accidentNumber = incident.getAccidentNr();
				accidentDate = incident.getAccidentDate();
				this.accidentPanel.setAccident(true);
				this.accidentPanel.setAccidentDate(incident.getAccidentDate());
				this.accidentPanel.setAccidentNumber(incident.getAccidentNr());
			}
		
//			if (prescription == null)
//				return;
		}
		
		// set date and expiry date
		if (prescription.getPrescriptionDate() == null)
			this.dateChooser.setDate(new Date());
		else
			this.dateChooser.setDate(prescription.getPrescriptionDate());

		this.expiryDateChooser.setDate(prescription.getExpiryDate());

		// set prescription text
		this.textArea.setText(prescription.getTextContent());

		// show print button
		this.printButton.setEnabled(true);

		// highlight open prescription in history view
		this.prescriptionHistoryView.highlightEntry(prescription
				.getIncidentEntry());
		
		// get accident data from prescription if prescription have a accident
		if (prescription.getAccidentDate() != null
				|| prescription.getAccidentNr() != null) {
			this.accidentPanel.setAccident(true);
			this.accidentPanel.setAccidentDate(prescription.getAccidentDate());
			this.accidentPanel.setAccidentNumber(prescription.getAccidentNr());
		} else {
			this.accidentPanel.setAccidentDate(accidentDate);
			this.accidentPanel.setAccidentNumber(accidentNumber);
			if(this.isPanel)
			{
				this.accidentPanel.setAccident(true);
			}else this.accidentPanel.setAccident(false);
		}
	}
	
	
	/**
	 * Set the position of the vertical scroll bar
	 * @param value the position
	 */
	public void setScollPaneValue(int value, int maximum)
	{
		this.prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().removeAdjustmentListener(this.scrollPaneListener);
		this.prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().setMaximum(maximum);
		this.prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().setValue(value);
		this.prescriptionHistoryView.getPrescriptionHistoryTablePanel().getScrollPane().getVerticalScrollBar().addAdjustmentListener(this.scrollPaneListener);
	}
	
	/**
	 * Show the accident dialog to choose a accident of a patient
	 */
	public void showAccidentDialog() {
		
		PatientPanel patientPanel = PatientManagerModule.getInstance().getPatientPanel();
		
		if (patientPanel.getHistoryDataAgent().getLatestIncident() != null ) 
		{

			AccidentRelationDialog are = AccidentRelationDialog.getInstance();

			List<Incident> tList = new ArrayList<Incident>();
			
			tList.addAll(PatientManagerModule.getPatientAccidents(
					GECAMedModule.getCurrentPatient().getId()));
			
			are.showDialog(tList.get(0),tList);
			
			Incident selectedIncident = are.getSelectedAccident();
			
			if (selectedIncident != null) {
						
				if(selectedIncident.getAccidentDate() != null)
					this.accidentPanel.setAccidentDate(selectedIncident.getAccidentDate());
				
				if(selectedIncident.getAccidentNr() != null)
					this.accidentPanel.setAccidentNumber(selectedIncident.getAccidentNr());		
			}
		}
	}
	
	
	/**
	 * Set the windowMode of Prescription witch is the Status if PrescritionPanel is open
	 * in consultation view or seperat in a window
	 * 
	 * @param windowMode if true PrescriptionPanel open in window else in view
	 */
	public void setWindowMode(boolean windowMode)
	{
		this.windowMode = windowMode;
	}
	
	
	/**
	 * Get the current PrescriptionHistoryView of the PrescriptionDataPanel
	 * 
	 * @return PrescriptionHistoryView
	 */
	public PrescriptionHistoryView getPrescriptionHistoryView()
	{
		return prescriptionHistoryView;
	}
}