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

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.table.TableCellRenderer;

import lu.tudor.santec.gecamed.core.gui.listener.EntryTypeRegister;
import lu.tudor.santec.gecamed.core.gui.listener.IEntryTypeHandler;
import lu.tudor.santec.gecamed.core.gui.utils.LineColorCellRenderer;
import lu.tudor.santec.gecamed.core.gui.utils.StringHelper;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Incident;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.IncidentEntry;
import lu.tudor.santec.gecamed.patient.ejb.session.interfaces.IncidentManager;
import lu.tudor.santec.gecamed.patient.gui.PatientManagerModule;
import lu.tudor.santec.gecamed.patient.gui.settings.ConsultationEntryConfig;
import lu.tudor.santec.gecamed.patient.gui.settings.PatientModuleSettings;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Logger;

/**
 * Renderer for the history table.
 * 
 * 
 * @author martin.heinemann@tudor.lu 21.01.2008 16:34:02
 * 
 * 
 * @version <br>
 *          $Log: HistoryTableRenderer.java,v $
 *          Revision 1.35  2013-12-27 18:09:25  donak
 *          Cleanup of imports
 *
 *          Revision 1.34  2013-11-29 15:16:17  troth
 *          Fix some bugs:
 *          Consultation view if first panel is empty
 *          History view sickleave date
 *
 *          Revision 1.33  2013-10-29 09:45:27  troth
 *          The new consultation view with more entries and the sickleave version 3 fix several bugs.
 *
 *          Revision 1.32  2013-10-21 11:15:48  ferring
 *          nullpointer exception prevented
 *
 *          Revision 1.31  2013-09-04 15:33:27  troth
 *          The new consultation view with more entries and the sickleave version 2 history view work now.
 *
 *          Revision 1.30  2013-07-15 06:18:36  ferring
 *          logging changed
 *
 *          Revision 1.29  2011-05-11 12:31:27  ferring
 *          Tabs in history panel are replaced by 4 whitespaces
 *
 *          Revision 1.28  2010-11-03 16:40:47  ferring
 *          typing mistake fixed
 *
 *          Revision 1.27  2010-10-25 08:13:07  ferring
 *          catching NullpointerException
 *
 *          Revision 1.26  2010-10-13 15:02:53  troth
 *          Add new dialog to the main menu bar for delete the incidents how have no incident entries.
 *
 *          Revision 1.25  2010-09-08 11:39:23  troth
 *          change color of open prescription entry
 *
 *          Revision 1.24  2010-09-06 14:28:55  troth
 *          Incomplete - # 624: Probleme mit  History-Display von '<'-Zeichen in S.O.A.P. Eintr�gen
 *          http://santec.tudor.lu/trac/gecamed/ticket/624
 *
 *          Revision 1.23  2010-08-24 14:08:56  troth
 *          set new color for open prescription in prescription history
 *
 *          Revision 1.22  2010-07-26 13:59:27  troth
 *          remove two not needed else cases
 *
 *          Revision 1.21  2010-07-22 07:52:09  troth
 *          bug fix - add colored one click select line in history table
 *
 *          Revision 1.20  2010-07-21 08:31:41  troth
 *          add function for colored the line of the open prescription entry in the history table - small fix
 *
 *          Revision 1.19  2010-07-20 14:18:49  troth
 *          add function for colored the line of the open prescription entry in the history table
 *
 *          Revision 1.18  2010-06-15 07:54:28  troth
 *          add logger for warning msg
 *
 *          Revision 1.17  2010-06-07 12:04:57  hermen
 *          fixed NPE
 *
 *          Revision 1.16  2010-05-19 12:45:08  troth
 *          updated Javadoc and refactored code
 *
 *          Revision 1.15  2010-05-19 09:50:09  troth
 *          fix bug in the prescription renderer to draw entries in the history table  Incomplete - # 505: Scheinbar willk�rliche Ver�nderungen beim Anklicken von Historie Eintr�gen
 *          http://santec.tudor.lu/trac/gecamed/ticket/505
 *
 *          Revision 1.14  2009-12-14 15:34:31  hermen
 *          fixed NULL entries in history
 *
 *          Revision 1.13  2008-12-17 15:23:06  heinemann
 *          initial commit after merging of branch new prescription
 *
 *          Revision 1.12.2.1  2008-12-15 14:08:21  heinemann
 *          *** empty log message ***
 *
 *          Revision 1.12  2008-09-25 09:43:08  heinemann
 *          fixed copyrights
 *
 *          Revision 1.11  2008-07-03 11:59:57  heinemann
 *          *** empty log message ***
 *
 *          Revision 1.10  2008-03-10 12:37:52  heinemann
 *          *** empty log message ***
 *
 *          Revision 1.9  2008-03-06 15:34:26  heinemann
 *          *** empty log message ***
 * <br>
 *          Revision 1.8 2008-01-22 13:51:52 heinemann <br>
 *          code cleanup and java doc <br>
 * 
 */
public class HistoryTableRenderer extends JEditorPane implements
		TableCellRenderer {

	// ***************************************************************************
	// * Class Constants *
	// ***************************************************************************

	private static final long serialVersionUID = 1L;
	
	private static final String HTML_TAG 	= "<html>";
	private static final String TAB			= "\t";
	private static final String SPACES		= "    ";
	private static final String HTML_SPACES = "&nbsp;&nbsp;&nbsp;&nbsp;";

	/**
	 * static logger for this class
	 */
	private static Logger logger = Logger.getLogger(HistoryTableModel.class.getName());
	
	private static final int c_Gap = 2;

	private final static int fontSize = 9;

	private static final Color c_OddColor = new Color(237, 243, 254);

	private static final Color c_OpenColor = new Color(144, 200, 216);
	
	private static final Color c_EvenColor = new Color(255, 255, 255);

	private static final LineColorCellRenderer dateRenderer = new LineColorCellRenderer();
	
	private static final LineColorCellRenderer typeRenderer = new LineColorCellRenderer();

	private static final LineColorCellRenderer physicianRenderer = new LineColorCellRenderer();

	private HistoryTableModel model;

	private Font f = new Font("Arial", Font.BOLD, 9);

	private Font f1 = new Font("Arial", Font.BOLD, 12);

	private DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

	private DateFormat timeFormat = new SimpleDateFormat("HH:mm", Translatrix.getLocale());

	private Border b = BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLUE);

	private int openIncidentEntryId = -1 ;
	

	/**
	 * @param model
	 */
	public HistoryTableRenderer(HistoryTableModel model) {
		/* ================================================== */
		this.model = model;
		setContentType("text/html");
		this.setBorder(BorderFactory.createEmptyBorder(c_Gap, c_Gap, c_Gap, c_Gap));
		/* ================================================== */
	}

	/* (non-Javadoc)
	 * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
	 */
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
		/* ================================================== */
		// look if this line is a new Incident
		/* ------------------------------------------------------- */
		boolean newIncident = true;
		
		try {
			newIncident = (!model.getValueAt(row, 0).equals(model.getValueAt(row - 1, 0)));
		} catch (Exception e) {
			logger.warn("ROW: " + row + "   " + e.getMessage());
		}
		
		// flag to select the open incident entry
		boolean openIncidentEntry = false;
		
		// highlight the open incident entry
		IncidentEntry incidentEntry = (IncidentEntry) model.getValueAt(row, 3);
		if(incidentEntry != null && incidentEntry.isPersistent() && incidentEntry.getId() == openIncidentEntryId) {
			openIncidentEntry = true;			
		} else {
			openIncidentEntry = false;			
		}
		
		/* ------------------------------------------------------- */
		// we need a default renderer for incidents.
		// it will paint the date of an incident in the first line
		// and if it is an accident also the accidents data in the 4. column
		// all other data will be rendered by the responsible module
		/* ------------------------------------------------------- */
		JComponent renderComponent = null;
		// draw the columns
		switch (column) {
		/* ------------------------------------------------------- */
		// the date of the incident
		/* ------------------------------------------------------- */
		case 0:
			
			String text = "";
						
			if (newIncident && value != null) {
				text = df.format(value)
						+ "<br></span><span style=\"font-family:Arial;font-size:"
						+ (fontSize - 1) + "px;text-align:center;\">"
						+ timeFormat.format(value) + "</span></html>";
			}
			
			
			text = "<html><span style=\"font-family:Arial;font-size:"
					+ fontSize + "px;font-weight:bold;text-align:center;\">"
					+ text;
			
			
			JLabel c0 = (JLabel) dateRenderer
			.getTableCellRendererComponent(table, text, isSelected,
											hasFocus, row, column);
			c0.setVerticalAlignment(JLabel.TOP);
			renderComponent = c0;
			
			break;
			/* ********************************************************* */
			/* ********************************************************* */
			// the physician mnemonic
			/* ********************************************************* */
			/* ********************************************************* */
			case 1:
				/* ------------------------------------------------------- */
				text = (String) value;
				if (!newIncident) {
					text = "";
				}
				JLabel c1 = (JLabel) physicianRenderer
								.getTableCellRendererComponent(table, text, isSelected,
																hasFocus, row, column);
				c1.setFont(f);
				c1.setVerticalAlignment(JLabel.TOP);
				if (newIncident)
					c1.setBorder(b);
				else
					c1.setBorder(null);

				renderComponent = c1;
				break;
			/* ********************************************************* */
			/* ********************************************************* */
			// the type
			/* ********************************************************* */
			/* ********************************************************* */
			case 2:
				/* ------------------------------------------------------- */
				JComponent c2 = null;
				if (value instanceof Incident) {
					/* ------------------------------------------------------- */
					// we might have an accident here
					/* ------------------------------------------------------- */
					c2 = (JLabel) typeRenderer.getTableCellRendererComponent(
							table, "Ac",
							isSelected, hasFocus, row, column);
					/* ------------------------------------------------------- */
				} else
				if (value instanceof IncidentEntry) {
					/* ------------------------------------------------------- */
					// try to get a responsible renderer from the modules
					/* ------------------------------------------------------- */
					IncidentEntry entry = (IncidentEntry) value;
					TableCellRenderer entryRenderer = getRenderer(entry);
					
					if (entryRenderer != null)
						c2 =  (JComponent) entryRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
					else{
						// get the acronym for the entry
						ConsultationEntryConfig entryConfig	= null;
						PatientModuleSettings patientGlobalSettings = PatientManagerModule.getInstance().patientSettings;
						
						entryConfig = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(entry.getEntryType().getName()));
						// render the new cons.1, cons.2, cons.3 or sick_leave entry type
						// this types have no extra entry renderer at the moment
						if(entryConfig.getId() != null)
						{
							c2 = (JComponent) typeRenderer.getTableCellRendererComponent(
									table, entryConfig.getAcronym(),
									isSelected, hasFocus, row, column);
						}else
							// render all other entry types
							c2 = (JComponent) typeRenderer.getTableCellRendererComponent(
									table, entry.getEntryType().getName(), 
									isSelected, hasFocus, row, column);
					}
					/* ------------------------------------------------------- */
				}  else
					/* ------------------------------------------------------- */
					c2 = (JComponent) typeRenderer.getTableCellRendererComponent(
														table,  value,
														isSelected, hasFocus, row, column);
					/* ------------------------------------------------------- */
				c2.setFont(f1);
				/* ------------------------------------------------------- */
				// if c2 is JLabel
				/* ------------------------------------------------------- */
				if (c2 instanceof JLabel) {
					((JLabel)c2).setVerticalAlignment(  JLabel.TOP);
					((JLabel)c2).setHorizontalAlignment(JLabel.CENTER);
				}
//				if (newIncident)
//					c2.setBorder(b);
//				else
//					c2.setBorder(null);
//				return c2;
				renderComponent = c2;
				break;
			/* ********************************************************* */
			/* ********************************************************* */
			// the main text
			/* ********************************************************* */
			/* ********************************************************* */
			default:
				/* ------------------------------------------------------- */
				if (value instanceof Incident) {
					/* ------------------------------------------------------- */
					// we might have an accident here
					/* ------------------------------------------------------- */
					Incident in = (Incident) value;
					if (in.getIsAccident() != null && in.getIsAccident() ) {
						String s = in.getAccidentNr();
						if (in.getAccidentDate() != null)
							s += " " + in.getAccidentDate();
						setText("<html><span style=\"font-family:Arial;font-size:"
								+ fontSize + "px;\">"
								+ s.replaceAll("\n", "<br>")
								//+ HistoryTableRenderer.stringFormater(s)
								+ "</span></html>");
					}
					/* ------------------------------------------------------- */
				} else
				if (value instanceof IncidentEntry) {
					/* ------------------------------------------------------- */
					// try to get a responsible renderer from the modules
					/* ------------------------------------------------------- */
					IncidentEntry entry = (IncidentEntry) value;
					
					TableCellRenderer entryRenderer = getRenderer(entry);
					if (entryRenderer != null) {
						/* ------------------------------------------------------- */
						renderComponent =  (JComponent) entryRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
						if (renderComponent instanceof JLabel)
							((JLabel)renderComponent).setHorizontalAlignment(JLabel.LEFT);
						/* ------------------------------------------------------- */
					}
					else {
						String str = entry.getTextContent() != null ? entry.getTextContent() : "";
						str = StringHelper.getText(str);
						String code = "";
						// get the codelabel for the entry
						ConsultationEntryConfig entryConfig	= null;
						PatientModuleSettings patientGlobalSettings = PatientManagerModule.getInstance().patientSettings;
						
						entryConfig = new ConsultationEntryConfig((String) patientGlobalSettings.getValue(entry.getEntryType().getName()));
						
						if(entry.getCode() != null)
						{
							if(!entry.getCode().equals(""))
							{
								if(entryConfig.getId() != null)
								{
									if(entryConfig.getId().equals(IncidentManager.SICK_LEAVE))
									{
										String startDate = "";
										String endDate = "";
										if(entry.getSickLeaveStartDate() != null) startDate = df.format(entry.getSickLeaveStartDate());
										if(entry.getSickLeaveEndDate() != null) endDate = df.format(entry.getSickLeaveEndDate());
										code = entryConfig.getTranslatedName() + ": " + entry.getCode() + " | " +
//										Translatrix.getTranslationString("patient.incident.sickLeaveStartDateLabel") + ": " +
										startDate + " - " +
//										Translatrix.getTranslationString("patient.incident.sickLeaveEndDateLabel") + ": " +
										endDate;
									}else
										code = "<b>" + entryConfig.getCodeLabel() + ": " + entry.getCode()+"<b>";
								}
							}
						}
						setText("<html><span style=\"font-family:Arial;font-size:"+ fontSize + "px;\">" +
								code +
								str +
								"</span></html>");
					}
					/* ------------------------------------------------------- */
				} else{
					setText("" + value);
				}
				// the text
//				if (value != null && !value.equals(""))
//					setText("<html><span style=\"font-family:Arial;font-size:"
//							+ fontSize + "px;\">"
//							+ ((String) value).replaceAll("\n", "<br>"));
//				else
//					setText("");
				break;
			}
		
		/* ------------------------------------------------------- */
		// adjust some settings of the render component
		/* ------------------------------------------------------- */
		if (renderComponent != null) {
			/* ------------------------------------------------------- */
			if (renderComponent instanceof JLabel)
			{
				String text = ((JLabel)renderComponent).getText();
				text = text.replaceAll(TAB, text.startsWith(HTML_TAG) ? HTML_SPACES : SPACES);
				((JLabel)renderComponent).setText(text);
			}
			
			Color l_Background = (row % 2 == 0) ? c_OddColor : c_EvenColor;
			
			if (isSelected)
				renderComponent.setBackground(table.getSelectionBackground());
			else
				renderComponent.setBackground(l_Background);

			if (newIncident)
				renderComponent.setBorder(b);
			else
				renderComponent.setBorder(null);
			
			if (openIncidentEntry)
				renderComponent.setBackground(c_OpenColor);
			
			return renderComponent;
			/* ------------------------------------------------------- */
		}

			
		Color l_Background = (row % 2 == 0) ? c_OddColor : c_EvenColor;
		if (isSelected)
			this.setBackground(table.getSelectionBackground());
		else
			this.setBackground(l_Background);

		if (newIncident)
			this.setBorder(b);
		else
			this.setBorder(null);

		if (openIncidentEntry)
			this.setBackground(c_OpenColor);

		String text = this.getText();
		text = text.replaceAll(TAB, text.startsWith(HTML_TAG) ? HTML_SPACES : SPACES);
		this.setText(text);
		
		return this;
		/* ================================================== */
	}
	
	
	/**
	 * @param entry
	 * @return
	 */
	private TableCellRenderer getRenderer(IncidentEntry entry) {
		/* ================================================== */
		try {
			/* --------------------------------------------- */
			IEntryTypeHandler handler = EntryTypeRegister.getHandler(entry.getEntryType().getName());
			/* ------------------------------------------------------- */
			return handler.getRenderer(entry.getEntryType().getName());
			/* --------------------------------------------- */
		} catch (Exception e) {
			/* --------------------------------------------- */
			return null;
			/* --------------------------------------------- */
		}
		/* ================================================== */
	}
	
	public void setOpenIncidentEntryId(int id) {
		openIncidentEntryId  = id;
		model.fireTableDataChanged();
	}
	
	public int getOpenIncidentEntryId() {
		return openIncidentEntryId;
	}
	
	/**
	 * The method format the given string for the output in the history table.
	 * It replace all: 	"<" with "&#60;"
	 * 					">" with "&#62;"
	 * 					"\n" with "<br>"
	 * 
	 * @param str the string to formatted
	 * @return the formatted string
	 */
	public static String stringFormater(String str)
	{
		if(str != null)
		{
			str = str.replaceAll("<", "&#60;");
			str = str.replaceAll(">", "&#62;");
			str = str.replaceAll("\n", "<br>");
		}
		return str;
	}
//	
//	private String getHistoryTypeShortCut(Integer type) {
//		if (type == null) {
//			return "";
//		}
//		switch (type) {
//		// case HistoryElement.INCIDENT:
//		// return "I";
//		// case HistoryElement.ACCIDENT:
//		// return "Ac";
//		// case HistoryElement.ANAMNESIS:
//		// return "S";
//		// case HistoryElement.FINDING:
//		// return "O";
//		// case HistoryElement.DIAGNOSIS:
//		// return "A";
//		// case HistoryElement.TRAITMENT:
//		// return "P";
//		// case HistoryElement.PRESCRIPTION:
//		// return "M";
//		// case HistoryElement.MEASUREMENT:
//		//			return "";
//		//		case HistoryElement.HOSPITALISATION:
//		//			return "H";
//		default:
//			return type + "";
//		}
//	}

}
