/*******************************************************************************
 * 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.patient.gui.history;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.util.Vector;

import javax.swing.JList;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import javax.swing.text.SimpleAttributeSet;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedTab;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.PatientDatas;
import lu.tudor.santec.gecamed.patient.ejb.session.beans.HistoryManagerBean;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.HistoryManager;
import lu.tudor.santec.gecamed.patient.gui.PatientPanel;
import lu.tudor.santec.gecamed.patient.gui.allergy.AllergyManagerDialog;
import lu.tudor.santec.gecamed.patient.gui.history.antecedents.AntecedentsListModel;
import lu.tudor.santec.gecamed.patient.gui.history.antecedents.AntecedentsViewDialog;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;


/**
 * Model for the important datas: current incident, alergies, chronical treatments and antecedents.
 * It offers a method to get the panel component to view the data.
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 */
public class ImportantDataModel implements DocumentListener, ActionListener, ListDataListener {

//	private static final long serialVersionUID = 1L;
	private AntecedentsListModel antecedentsModel;
	private Vector<ImportantDataPanel> panels = new Vector<ImportantDataPanel>();
	private Document problemActiveDocument = new PlainDocument();
	private Document chronicalTreatmentsDocument = new PlainDocument();
	private Document allergyDocument = new PlainDocument();
	private HistoryManager manager;
	private PatientDatas data;
	private Patient patient;
	private boolean listenersActivated = true;
	private static Logger m_Logger = Logger.getLogger ("lu.tudor.santec.gecamed.patient.gui.history");
	private AllergyManagerDialog allergyDialog = new AllergyManagerDialog();
	private PatientPanel patientPanel;
	private AntecedentsViewDialog antecedentsViewDialog;
	private boolean	chronicalTreatmentsChanged = false;
	private boolean	problemActiveChanged = false;


	/**
	 * @param panel
	 */
	public ImportantDataModel(AntecedentsListModel model, PatientPanel patientPanel) {
		// ==================================================
		this.patientPanel = patientPanel;
		this.antecedentsModel = model;
		this.antecedentsModel.addListDataListener(this);
		this.problemActiveDocument.addDocumentListener(this);
		this.chronicalTreatmentsDocument.addDocumentListener(this);

		this.allergyDialog.getModel().addTableModelListener(new TableModelListener() {
			public void tableChanged(TableModelEvent e) {
				try {
					allergyDocument.remove(0,allergyDocument.getLength());
					allergyDocument.insertString(0,allergyDialog.getModel().getImportantString(), new SimpleAttributeSet());
				} catch (BadLocationException e1) {
					e1.printStackTrace();
				}
			}
		});

		try {
 			manager = (HistoryManager) ManagerFactory.getRemote(HistoryManagerBean.class);
 			}
 		catch (Exception p_Exception)
 			{
 			m_Logger.warn(p_Exception.getLocalizedMessage());
 			}
 		this.antecedentsViewDialog = new AntecedentsViewDialog(Translatrix.getTranslationString("patient.antecedents"), patientPanel, antecedentsModel);
	}

	/**
	 * Creates a new instance of the ImportantDataPanel with this model.
	 * 
	 * @param shortVersion true -> 3 column version
	 * @return
	 */
	public ImportantDataPanel getImportantDataPanelView(boolean shortVersion) {
		// ==================================================
		ImportantDataPanel panel = new ImportantDataPanel(shortVersion, this);
		panel.antecedantsList.setModel(antecedentsModel);
		panel.antecedantsList.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() >= 2) {
					JList list = new JList();
					int index = 0;
					list = (JList) e.getSource();
					index = list.getSelectedIndex();
					antecedentsViewDialog.setSelectIndex(index);
					antecedentsViewDialog.showDialog(true);
				}
			}
		});
		
		panel.antecedantsButton.addActionListener(this);
		
		panel.problemActiveField.setDocument(this.problemActiveDocument);
		panel.chronicalTreatmentsField.setDocument(this.chronicalTreatmentsDocument);
		
		panel.allergyField.setDocument(this.allergyDocument);
		panel.allergyField.addMouseListener(new MouseAdapter() {
			@Override
		    public void mouseClicked(MouseEvent e){
		        if(e.getClickCount()==2){
		        	allergyDialog.showDialog();	
		        }
		    }
		});
		panel.allergyButton.addActionListener(this);
		
		panels.add(panel);
		
		/* ------------------------------------------------------- */
		panel.setBackground(GECAMedColors.c_GECAMedBackground);
		panel.setOpaque(true);
		return panel;
		/* ================================================== */
	}

	
	public void insertUpdate(DocumentEvent e) {
		if (this.listenersActivated) {
			informChanges(e.getDocument());
		}
	}
	public void removeUpdate(DocumentEvent e) {
		if (this.listenersActivated)
			informChanges(e.getDocument());
	}
	public void changedUpdate(DocumentEvent e) {
		if (this.listenersActivated)
			informChanges(e.getDocument());
	}
	
	private void informChanges(Document doc) {
		/* ================================================== */
//		patientPanel.setModified(true);
		
		if (doc.equals(this.chronicalTreatmentsDocument)) 
			this.chronicalTreatmentsChanged = true;
		
		if (doc.equals(this.problemActiveDocument)) 
			this.problemActiveChanged = true;
		
		PropertyChangeEvent ev = new PropertyChangeEvent(this, GECAMedTab.DATA_CHANGED, false, true);
		patientPanel.propertyChange(ev);
		/* ================================================== */
	}
	

	/**
	 * @param patient
	 */
	public void setPatient(Patient patient) {
		/* ================================================== */
		this.listenersActivated = false;
		this.patient 			= patient;
		/* ------------------------------------------------------- */
		m_Logger.info("loading ImportantPatientdata for patientID  " + patient.getId());
		/* ------------------------------------------------------- */
		// set the patient to the allergy model
		/* ------------------------------------------------------- */
		this.allergyDialog.getModel().setPatient(patient);
		/* ------------------------------------------------------- */
		// try to remove old data from the important data components
		/* ------------------------------------------------------- */
		try {
			/* ------------------------------------------------------- */
			this.chronicalTreatmentsDocument.remove(0,this.chronicalTreatmentsDocument.getLength());
			this.problemActiveDocument.remove(0,this.problemActiveDocument.getLength());
			this.data = manager.getPatientDatas(patient.getId());
			if (data != null) {
				this.problemActiveDocument.insertString(0,data.getActiveProblem(), new SimpleAttributeSet());
				this.chronicalTreatmentsDocument.insertString(0,data.getChronicalTreatments(), new SimpleAttributeSet());
			} else {
				m_Logger.info("no ImportantPatientdata found ! ");
			}
			/* ------------------------------------------------------- */
		} catch (Exception e) {
			m_Logger.warn("ERROR loading ImportantPatientdata for patientID  " + patient.getId());
			e.printStackTrace();
		}
		this.listenersActivated = true;
		
		chronicalTreatmentsChanged = false;
		problemActiveChanged = false;
		/* ================================================== */
	}

	public void saveData() {
		if (patient == null)
			return;

		if (data == null) {
			data = new PatientDatas();
			data.setPatientId(patient.getId());
			m_Logger.info("new ImportantPatientdata for patientID  " + patient.getId() + " created! ");
		}

		try {
			data.setActiveProblem(this.problemActiveDocument.getText(0,this.problemActiveDocument.getLength()));

			data.setChronicalTreatments( this.chronicalTreatmentsDocument.getText(0,this.chronicalTreatmentsDocument.getLength()));
			
			if (chronicalTreatmentsChanged || problemActiveChanged)
				data	= manager.savePatientDatas(data, chronicalTreatmentsChanged, problemActiveChanged);
		} catch (Exception e) {
			m_Logger.info("ERROR saving  ImportantPatientdata for patientID  " + patient.getId());
			MainFrame.reportServerError(e);
		}
		patientPanel.setModified(false);
		chronicalTreatmentsChanged = false;
		problemActiveChanged = false;
	}

	public void actionPerformed(ActionEvent e) {
		
		if (e.getActionCommand().equals(ImportantDataPanel.ALLERGY)) {
			allergyDialog.showDialog();	
		}
		
		if (e.getActionCommand().equals(ImportantDataPanel.ANTECEDANTS)) {
			this.antecedentsViewDialog = new AntecedentsViewDialog(Translatrix.getTranslationString("patient.antecedents"), patientPanel, antecedentsModel);
			antecedentsViewDialog.addAntecedents(); 
		}
	}

	public void contentsChanged(ListDataEvent e) {}
	public void intervalAdded(ListDataEvent e) {}
	public void intervalRemoved(ListDataEvent e) {}
	
	
	public Document getProblemActiveDocument()
	{
		return problemActiveDocument;
	}
	
	
	public Document getChronicalTreatmentsDocument()
	{
		return chronicalTreatmentsDocument;	
	}
	
	
	public Document getAllergyDocument()
	{
		return	allergyDocument;
	}
}
