/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
/**
 *
 */
package lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.editor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.undo.UndoManager;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.IChangeListener;
import lu.tudor.santec.gecamed.core.gui.utils.UndoTextArea;
import lu.tudor.santec.gecamed.core.gui.utils.UndoTextField;
import lu.tudor.santec.gecamed.core.gui.widgets.ModuleHeader;
import lu.tudor.santec.gecamed.prescription.ejb.entity.beans.drug.IDrug;
import lu.tudor.santec.gecamed.prescription.ejb.entity.dataclasses.DrugLight;
import lu.tudor.santec.gecamed.prescription.gui.PrescriptionIcons;
import lu.tudor.santec.gecamed.prescription.gui.util.NewDrugWorker;
import lu.tudor.santec.gecamed.prescription.gui.widgets.PosologyChooserDialog;
import lu.tudor.santec.gecamed.prescription.gui.widgets.drugbrowser.DrugBrowser;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.DrugInputComponent;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.EditorDrugTableModel;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.TemplateCellRenderer;
import lu.tudor.santec.gecamed.prescription.gui.widgets.editor.template.TemplateModel;
import lu.tudor.santec.i18n.Translatrix;

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

/**
 *
 * This is the editor dialog to add/edit/delete
 * Prescription templates.
 * It is implemented as Singleton.
 *
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: TemplateEditor.java,v $
 * <br>Revision 1.8  2010-03-30 10:34:14  troth
 * <br>Redesign of the prescription view - add Icons
 * <br>
 * <br>Revision 1.7  2009-01-19 15:57:57  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.6  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.5  2008-02-11 16:51:50  heinemann
 * <br>moved IChangeListener to core
 * <br>
 * <br>Revision 1.4  2007/08/01 07:09:01  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.3  2007/03/14 11:46:38  heinemann
 * <br>added cefip browser
 * <br>
 * <br>Revision 1.2  2007/03/02 08:28:44  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1.2.4  2007/01/05 14:28:41  heinemann
 * <br>complete - # 25: The window size of the prescription template dialog is to small
 * <br>http://santec.tudor.lu:8888/gecamed/ticket/25
 * <br>
 * <br>Revision 1.1.2.3  2006/12/28 10:32:26  heinemann
 * <br>bug fixing and template improvements
 * <br>
 * <br>Revision 1.1.2.2  2006/12/21 15:56:06  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.1  2006/12/21 14:26:43  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.1.2.1  2006/12/19 14:53:31  heinemann
 * <br>printing etc
 * <br>
 */
public class TemplateEditor extends JDialog implements DocumentListener, ActionListener, IChangeListener {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;


//	private static TemplateEditor templateEditor = new TemplateEditor();

	private TemplateModel templateModel;


	private TemplateEditorModel editorModel;


	private JPanel mainPanel;


	private UndoManager undoManager;


	private UndoTextField filterTextField;


	private JTable templateTable;


	private JPanel tablePanel;


	private JPanel rightPanel;


	private CellConstraints cc;


	private UndoTextField shortcutField;


	private UndoTextField nameField;


	private EditorDrugTableModel drugTableModel;


	private DrugInputComponent drugInputComponent;


	private JPanel metaPanel;


	private JCheckBox warningBox;


	private UndoTextArea warningArea;

	private boolean disableUpdate = false;


	protected JButton newButton;


	protected JButton saveButton;


	protected JButton closeButton;


	private ModuleHeader header;


	/**
	 * @param templateModel the model for the list of all templates
	 * @param editorModel the model for the current template
	 * @param drugTableModel the model for the drug input editor, the panel tah takes the prescription
	 */
	public TemplateEditor(TemplateModel templateModel,
			TemplateEditorModel editorModel,
			EditorDrugTableModel drugTableModel) {
		/* ====================================================== */
		super(MainFrame.getInstance(), true);
		/* ------------------------------------------------------ */
		this.templateModel = templateModel;
		this.editorModel = editorModel;
		this.drugTableModel = drugTableModel;

		initComponent();

		editorModel.addChangeListener(this);

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


	/* ************************************************************
	 * GUI methods
	 * ----------------------------------------------------------- */



	private void initComponent() {
		/* ============================================= */
		// set borderlayout for base panel
		this.setLayout(new BorderLayout());
		this.getContentPane().setBackground(Color.WHITE);


		// header to the norh
		this.header = new ModuleHeader(
				Translatrix.getTranslationString("prescription.name.templates"),
				PrescriptionIcons.getMediumIcon(PrescriptionIcons.TEMPLATES), new Color(204, 187, 243));
		this.add(header, BorderLayout.NORTH);
		/* ------------------------------------------------------ */
		// the main panel
		this.mainPanel = new JPanel(new BorderLayout());
		this.mainPanel.setOpaque(false);
		this.cc = new CellConstraints();

		initTable();

		initRightPanel();
		this.add(mainPanel, BorderLayout.CENTER);

		initDrugTableListener();

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


	/**
	 * Create a mouselister for the drugTable
	 * for posology chooser and cefip browser
	 */
	private void initDrugTableListener() {
		/* ============================================= */
		drugInputComponent.getTable().addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {

				if (SwingUtilities.isLeftMouseButton(e)) {
					JTable tb = drugInputComponent.getTable();
					if (tb.columnAtPoint(e.getPoint()) == 1) {
						/* ------------------------------------------------------ */
						int row = tb.rowAtPoint(e.getPoint());
						if (row%2 == 0) {
							// show the cefip browser
							showCefipBrowser(row);
						}else {
							// show the posology chooser
							String pos = PosologyChooserDialog.getInstance().showDialog(MainFrame.getInstance());
							if (pos != null) {
								// add the posology to the drugTableModel
								drugTableModel.setValueAt(
										(drugTableModel.getValueAt(row, 0) != null
												&& !drugTableModel.getValueAt(row, 0).equals("")
												? drugTableModel.getValueAt(row, 0)+ "\n" :
													"")
												+ pos
										, row, 1);
							}
						}
						/* ------------------------------------------------------ */
					}
				}
			}
		});
		/* ============================================= */
	}


	/**
	 * @param row to know where to return the selected drug
	 */
	private void showCefipBrowser(int row) {
		/* ====================================================== */
		drugInputComponent.getTable().getColumnModel().getColumn(0).getCellEditor().stopCellEditing();
		DrugBrowser nb = DrugBrowser.getInstance();
		DrugLight dl = (DrugLight) drugTableModel.getValueAt(row, 0);
		/* ------------------------------------------------------- */

		IDrug iD = nb.showDialog((dl != null ? dl.getName() : ""));
		/* ------------------------------------------------------- */
		if (iD != null) {
			drugTableModel.setValueAt(NewDrugWorker.IDrug2DrugLight(iD), row, 0);
		}
		/* ====================================================== */
	}


	/**
	 * Init the right panel with the fields
	 */
	private void initRightPanel() {
		/* ============================================= */
		this.rightPanel = new JPanel(new FormLayout(
				// cols
				"3dlu," +
				"fill:pref," +
				"8dlu," +
				"fill:pref:grow," +
				"3dlu",
				// rows
				"3dlu," +		// 1
				"fill:pref," +	// 2
				"3dlu," +		// 3
				"fill:pref," +	// 4
				"3dlu," +		// 5
				"fill:pref," +	// 6
				"3dlu," +		// 7
				"fill:20dlu:grow," + // 8
				"3dlu," +		// 9
				"fill:pref," +	// 10
				"3dlu," +		// 11
				"fill:pref," +	// 12
				"3dlu," +		// 13
				"fill:pref," +	// 14
				"3dlu"));		// 15
		rightPanel.setOpaque(false);
		/* ------------------------------------------------------ */

		// create info panel
		ModuleHeader infoHeader = new ModuleHeader(
				Translatrix.getTranslationString("template.desc.edit"),
				GECAMedModule.getMediumIcon(GECAMedIconNames.INFO),
				new Color(255, 204, 204));
		infoHeader.setBorder(BorderFactory.createTitledBorder(""));

		rightPanel.add(infoHeader, cc.xywh(2, 2, 3, 1));
		/* ------------------------------------------------------ */
		// the shortcut and name field
		this.shortcutField = new UndoTextField(this.undoManager);
		this.shortcutField.getDocument().addDocumentListener(this);

		this.nameField = new UndoTextField(this.undoManager);
		this.nameField.getDocument().addDocumentListener(this);
		/* ------------------------------------------------------ */
		// add
		rightPanel.add(new JLabel(
				Translatrix.getTranslationString("template.field.shortcut")
					+":")
			, cc.xy(2, 4));
		rightPanel.add(new JLabel(
				Translatrix.getTranslationString("template.field.name")
					+":")
			, cc.xy(4, 4));
		/* ------------------------------------------------------ */
		rightPanel.add(this.shortcutField, cc.xy(2, 6));
		rightPanel.add(this.nameField, cc.xy(4, 6));
		/* ------------------------------------------------------ */

		this.drugInputComponent = new DrugInputComponent(this.drugTableModel);

		drugInputComponent.getTextArea().getDocument().addDocumentListener(this);

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

		this.metaPanel = new JPanel(new BorderLayout());
		rightPanel.add(metaPanel, cc.xywh(2, 8, 3, 1));
		/* ------------------------------------------------------ */


		/* ------------------------------------------------------ */
		// the warning
		this.warningBox = new JCheckBox(
				Translatrix.getTranslationString("template.field.warning"));
		warningBox.setOpaque(false);
		// ActionListener
		warningBox.addActionListener(this);
		/* ------------------------------------------------------ */
		this.warningArea = new UndoTextArea(this.undoManager);

		warningArea.setRows(5);

		warningArea.setLineWrap(true);
		warningArea.setWrapStyleWord(true);
		warningArea.getDocument().addDocumentListener(this);

		warningArea.setEnabled(false);


		JScrollPane wScroll = new JScrollPane(warningArea);
		wScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		/* ------------------------------------------------------ */
		// add to the panel
		rightPanel.add(warningBox, cc.xy(2, 10));
		rightPanel.add(wScroll, cc.xywh(2, 12, 3, 1));
		/* ------------------------------------------------------ */


		/* ------------------------------------------------------ */
		// add button panel
		ButtonBarBuilder bb = new ButtonBarBuilder();
		this.newButton = new JButton(
				Translatrix.getTranslationString("template.buttons.new"));
		bb.addGridded(newButton);
		bb.addGlue();
		/* ------------------------------------------------------ */
		this.saveButton = new JButton(Translatrix.getTranslationString("prescription.core.save"));
		bb.addGridded(saveButton);

		this.closeButton = new JButton(Translatrix.getTranslationString("prescription.core.close"));
		bb.addGridded(closeButton);

		bb.getPanel().setOpaque(false);
		/* ------------------------------------------------------ */
		rightPanel.add(bb.getPanel(),cc.xywh(2, 14, 3, 1));
		/* ------------------------------------------------------ */
		mainPanel.add(rightPanel, BorderLayout.CENTER);
		/* ============================================= */
	}


	/**
	 * Init the left column with the jTable
	 */
	private void initTable() {
		/* ============================================= */
		this.undoManager = new UndoManager();
		/* ------------------------------------------------------ */
		// filter textfield
		this.filterTextField = new UndoTextField(undoManager);
		/* ------------------------------------------------------ */
		// table
		this.templateTable = new JTable();
		templateTable.setModel(templateModel);
		// layout tweaks
		templateTable.getColumnModel().getColumn(0).setMinWidth(40);
		templateTable.getColumnModel().getColumn(0).setMaxWidth(40);

		templateTable.getColumnModel().getColumn(0)
					.setCellRenderer(new TemplateCellRenderer(templateModel));
		templateTable.getColumnModel().getColumn(1)
					.setCellRenderer(new TemplateCellRenderer(templateModel));

//		templateTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		templateTable.getTableHeader().setReorderingAllowed(false);

		templateTable.setColumnSelectionAllowed(false);
		templateTable.setRowSelectionAllowed(true);

		JScrollPane tScroll = new JScrollPane(templateTable);
		templateTable.setOpaque(false);

		tScroll.getViewport().setOpaque(false);
		tScroll.getViewport().setBackground(Color.WHITE);
		tScroll.setOpaque(false);
		/* ------------------------------------------------------ */
		this.tablePanel = new JPanel(new BorderLayout());
		tablePanel.setOpaque(false);
		tablePanel.add(filterTextField, BorderLayout.NORTH);
		tablePanel.add(tScroll, BorderLayout.CENTER);

		tablePanel.setBorder(BorderFactory.createTitledBorder(
				Translatrix.getTranslationString("prescription.buttons.templates")));

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

		tablePanel.setPreferredSize(new Dimension(180,
				tablePanel.getPreferredSize().height));

		mainPanel.add(tablePanel, BorderLayout.WEST);
		/* ============================================= */
	}


	/* (non-Javadoc)
	 * @see java.awt.Component#setVisible(boolean)
	 */
	@Override
	public void setVisible(boolean b) {
		/* ============================================= */
		switchType(editorModel.getType());
		super.setVisible(b);
		/* ============================================= */
	}

	/**
	 * Switch the panel,according to the type
	 *
	 * @param type
	 */
	public void switchType(String type) {
		/* ====================================================== */
		try {
			metaPanel.removeAll();
		} catch (Exception e) {}

		metaPanel.add(drugInputComponent.getPanel(type));

		metaPanel.validate();
		metaPanel.updateUI();

		// change the header
		this.header.setTopic(Translatrix.getTranslationString("prescription.name.templates")
				+ " - " + Translatrix.getTranslationString("prescription.name."+type));
		/* ====================================================== */
	}


	public void changedUpdate(DocumentEvent e) {
		/* ============================================= */
		updateModel();
		/* ============================================= */
	}
	public void insertUpdate(DocumentEvent e) {
		/* ============================================= */
		updateModel();
		/* ============================================= */
	}
	public void removeUpdate(DocumentEvent e) {
		/* ============================================= */
		updateModel();
		/* ============================================= */
	}


	public void actionPerformed(ActionEvent e) {
		/* ============================================= */
			this.warningArea.setEnabled(warningBox.isSelected());
			this.editorModel.setWarning(warningBox.isSelected());

			updateModel();

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


	/**
	 * Write the data from the fields to the TemplateEditorModel
	 * and, if possible, to the drugTabelModel
	 */
	private void updateModel() {
		/* ====================================================== */

		if (!this.disableUpdate) {
			/* ------------------------------------------------------ */
			this.editorModel.setModified(true);
			this.editorModel.setShortcut(shortcutField.getText());
			this.editorModel.setDescription(nameField.getText());
			this.editorModel.setWarningMsg(warningArea.getText());
			this.editorModel.setWarning(warningBox.isSelected());

			this.editorModel.setTextContent(drugInputComponent.getTextArea().getText());
			/* ------------------------------------------------------ */
		}
		/* ====================================================== */

	}


	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.prescription.gui.util.IChangeListener#fireEvent()
	 */
	public void fireEvent() {
		/* ============================================= */
		// update the view from the model
		this.disableUpdate = true;
		/* ------------------------------------------------------ */
		this.shortcutField.setText(editorModel.getTemplate().getShortcut());
		this.nameField.setText(editorModel.getTemplate().getDescription());

		this.warningBox.setSelected(editorModel.getTemplate().getIsWarning());
		// this will bring the changes to the checkbox and the textarea
		actionPerformed(null);

		this.warningArea.setText(editorModel.getTemplate().getWarningMsg());

		drugInputComponent.getTextArea().setText(editorModel.getTemplate().getTextContent());
		/* ------------------------------------------------------ */
		this.disableUpdate = false;
		/* ============================================= */
	}



	/**
	 * @return
	 */
	public JButton getNewButton() {
		/* ====================================================== */
		return this.newButton;
		/* ====================================================== */

	}

	/**
	 * @return
	 */
	public JButton getCloseButton() {
		/* ====================================================== */
		return this.closeButton;
		/* ====================================================== */

	}
	/**
	 * @return
	 */
	public JButton getSaveButton() {
		/* ====================================================== */
		return this.saveButton;
		/* ====================================================== */

	}

	/**
	 * Return the template table of the left
	 *
	 * @return
	 */
	public JTable getTemplateTable() {
		/* ====================================================== */
		return this.templateTable;
		/* ====================================================== */
	}

	/* --------------------------------------------------------------
	 * End of GUI methods
	 * ************************************************************* */




}
