package lu.tudor.santec.gecamed.billing.gui.hospitalisation;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Rate;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.RateIndex;
import lu.tudor.santec.gecamed.billing.gui.BillingModule;
import lu.tudor.santec.gecamed.core.gui.LoginScreen;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.core.gui.widgets.PhysicianListModel;
import lu.tudor.santec.gecamed.core.gui.widgets.ReloadListener;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.office.gui.PhysicianComboBoxRenderer;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.jtimechooser.JTimeChooser;
import lu.tudor.santec.jtimechooser.TimeChangedEvent;
import lu.tudor.santec.jtimechooser.TimeChangedListener;

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

/**
 * @author hermenj
 *
 * @version
 * <br>$Log: HospitalisationPeriodGeneralTab.java,v $
 */
public class HospitalisationPeriodReanimationTab extends JPanel {


	private static final long serialVersionUID = 1L;
	private CellConstraints cc = new CellConstraints();

	JDateChooser		hospitalisationStartDateChooser;
	JDateChooser		hospitalisationEndDateChooser;

	JList<CBItem> 		transferOptionBox;
	private JLabel				transferOptionsLabel;
	DefaultListModel<CBItem> transferOptionModel = new DefaultListModel<CBItem>();

	JList<String> 		sectionList;
	private HospitalisationPeriodDialog parentDialog;

	private boolean listenersActive = false;
	JTimeChooser hospitalisationStartTimeChooser;
	JTimeChooser hospitalisationEndTimeChooser;
	
	private JComboBox<Physician>  			physicianChooser;
	
	private static final String	SECTION_SETTING	= "billing.hospitalisationPeriod.reanimationsection";


	@SuppressWarnings("unchecked")
	public HospitalisationPeriodReanimationTab(final HospitalisationPeriodDialog parent) {
		this.parentDialog = parent;

	    ReloadListener reloadListener = new ReloadListener()
		{
	    	private Object p;
	    	public void prepareReload ()
	    	{
	    		if (physicianChooser != null)
	    			p = physicianChooser.getSelectedItem();
	    	}
			public void reloaded ()
			{
				if (physicianChooser != null)
					physicianChooser.setSelectedItem(p);
			}
		};
	    physicianChooser	= new JComboBox<Physician> (new PhysicianListModel(reloadListener));
	    physicianChooser.setRenderer(new PhysicianComboBoxRenderer ());
	    physicianChooser.addItemListener (new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				parent.setPhysician((Physician) physicianChooser.getSelectedItem());
				parent.calculateRates(false);
			}
		});
		
		PropertyChangeListener periodUpdater = new PropertyChangeListener()
		{
			public void propertyChange(PropertyChangeEvent evt)
			{
				
				if (listenersActive && "date".equals(evt.getPropertyName())) {

					Date d = (Date) evt.getNewValue();
					if (!BillingModule.getInstance().checkActDate(d)) {
						try {
							listenersActive = false;
							((JDateChooser)evt.getSource()).setDate((Date) evt.getOldValue());
							listenersActive = true;
						} catch (Exception e) {}
						
						return;
					}
					parent.calculateRates(true);
				}

			}
		};
		
		TimeChangedListener timeUpdater = new TimeChangedListener()
		{
			public void timeChanged(TimeChangedEvent evt) {
				if (evt.isTimeModified()) {
					parent.calculateRates(true);					
				}
			}
		};

		// HOSPITALIZATION PERIOD
		JLabel hospitalisationPeriodLabel 	= new JLabel(
				Translatrix.getTranslationString("HospitalisationPeriodDialog.hospitalisatoinPeriod"));
		JLabel hospitalisationFromLabel 	= new JLabel(
				Translatrix.getTranslationString("HospitalisationPeriodDialog.from"));
		JLabel hospitalisationToLabel 		= new JLabel(
				Translatrix.getTranslationString("HospitalisationPeriodDialog.to"));
		
		hospitalisationStartDateChooser = GECAMedGuiUtils.getDateChooser(false);
		hospitalisationStartDateChooser.addPropertyChangeListener(periodUpdater);

		hospitalisationStartTimeChooser = new JTimeChooser();
		hospitalisationStartTimeChooser.setEnabledWithDoubleClick(false);
		hospitalisationStartTimeChooser.setShowSeconds(false);
		hospitalisationStartTimeChooser.setShowIcon(true);
		hospitalisationStartTimeChooser.addTimeChangedListener(timeUpdater);

		hospitalisationEndDateChooser = GECAMedGuiUtils.getDateChooser(false);
		hospitalisationEndDateChooser.addPropertyChangeListener(periodUpdater);

		hospitalisationEndTimeChooser = new JTimeChooser();
		hospitalisationEndTimeChooser.setEnabledWithDoubleClick(false);
		hospitalisationEndTimeChooser.setShowSeconds(false);
		hospitalisationEndTimeChooser.setShowIcon(true);
		hospitalisationEndTimeChooser.addTimeChangedListener(timeUpdater);

		// nomenclature section (physician type and post-OP)
		JLabel sectionChooserLabel		= new JLabel(Translatrix.getTranslationString("HospitalisationPeriodDialog.selectSection"));
		sectionChooserLabel.setOpaque(false);

		sectionList = new JList<String>(HospitalisationPeriodDialog.REANIMATION_SECTIONS);
		sectionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		sectionList.setCellRenderer(new SectionListRenderer());
		sectionList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				sectionChanged();
			}
		});
		sectionList.setSelectedIndex(0);
		sectionList.setVisibleRowCount(sectionList.getModel().getSize());
		JScrollPane listScroller = new JScrollPane(sectionList);

		// TRANSFER OPTIONS
		transferOptionsLabel 	= new JLabel(Translatrix.getTranslationString("HospitalisationPeriodDialog.transferOption"));
		transferOptionBox = new JList<CBItem>(transferOptionModel);
		transferOptionBox.setCellRenderer(new TransferOptionBoxRenderer());
		transferOptionBox.addListSelectionListener(new ListSelectionListener()
		{
			public void valueChanged(ListSelectionEvent e) {
				parentDialog.calculateRates(false);
			}
		});
		transferOptionsLabel.setVisible(false);
		transferOptionBox.setVisible(false);

		setLayout(new FormLayout(
				"5px, f:100dlu:grow, 5px, f:100dlu:grow, 5px",
				"10px, f:p, 10px, f:p, 5px, f:30dlu, 5px, f:p, 5px, f:pref, 5px"));
		this.setOpaque(false);
		int generalRow = 0;

		JPanel hospPanel = new JPanel(new FormLayout(
				"5px, 15px, f:p, 5px, f:max(150px;p), 5px, f:max(70px;p), 20px, f:p, 5px, f:max(150px;p), 5px, f:max(70px;p),5px, pref, 5px, pref, 5px",
				"5px, 20px, 5px, pref, 5px, pref, 5px"
				));
		hospPanel.setOpaque(false);
		hospPanel.setBorder(new LineBorder(Color.BLACK));
		hospPanel.add(hospitalisationPeriodLabel, 		cc.xyw(2, 2, 9));
		hospPanel.add(hospitalisationFromLabel, 		cc.xy (3, 4));
		hospPanel.add(hospitalisationStartDateChooser, 	cc.xy (5, 4));
		hospPanel.add(hospitalisationStartTimeChooser, 	cc.xy (7, 4));
		hospPanel.add(hospitalisationToLabel, 			cc.xy (9, 4));
		hospPanel.add(hospitalisationEndDateChooser, 	cc.xy (11, 4));
		hospPanel.add(hospitalisationEndTimeChooser, 	cc.xy (13, 4));
		hospPanel.add(new JLabel(Translatrix.getTranslationString("core.physician")+":"), cc.xy (15, 4));
		hospPanel.add(physicianChooser, 				cc.xy (17, 4));
		
		this.add(hospPanel, cc.xyw(2, generalRow+=2, 3));

		this.add(sectionChooserLabel,				cc.xyw(2, generalRow+=2, 3));
		this.add(listScroller,						cc.xyw(2, generalRow+=2, 3));
		this.add(transferOptionsLabel, 				cc.xyw(2, generalRow+=2, 3));
		this.add(transferOptionBox, 				cc.xyw(2, generalRow+=2, 3));

		listenersActive = true;
		loadTransferRates();
	}


	private void sectionChanged()
	{
		loadTransferRates();
		parentDialog.calculateRates(false);
	}

	private void loadTransferRates() {
		if (!listenersActive) return;

		listenersActive = false;
		transferOptionModel.clear();

		String selectedSection = (String) sectionList.getSelectedValue();

		String[] sectionTransferCodes = HospitalisationPeriodDialog.TRANSFER_CODES.get(selectedSection);
		if (sectionTransferCodes == null) {
			transferOptionsLabel.setVisible(false);
			transferOptionBox.setVisible(false);
		} else {
			for (String code : sectionTransferCodes)
			{				
				//					System.out.println("load transfercode: " + code);
				if (code.indexOf("_") > 0) {
					// load Subchapter
					RateIndex r = parentDialog.getChapter(code);
					if (r != null) {
						CBItem item = new CBItem(r.getLabel(), HospitalisationPeriodDialog.trimDesc(r.getTitle()));
						transferOptionModel.addElement(item);
					}
				} else {
					// load Rate
					Rate r = parentDialog.getRate(code);
					if (r != null) {
						CBItem item = new CBItem(r.getCode(), HospitalisationPeriodDialog.trimDesc(r.getLabel()));
						transferOptionModel.addElement(item);											
					}
				}
			}
			transferOptionBox.setSelectedIndex(0);
			transferOptionBox.setVisibleRowCount(transferOptionModel.getSize());
			transferOptionsLabel.setVisible(true);
			transferOptionBox.setVisible(true);
			transferOptionBox.setPreferredSize(transferOptionBox.getPreferredScrollableViewportSize());
		}
		listenersActive  = true;
	}

	@SuppressWarnings("rawtypes")
	/* ======================================== */
	// 		CLASS: ComboBoxToolTippRenderer
	/* ======================================== */

	class SectionListRenderer extends DefaultListCellRenderer 
	{
		private static final long serialVersionUID = 1L;

		public Component getListCellRendererComponent(JList list, Object value, 
				int index, boolean isSelected, boolean cellHasFocus)
		{

			String valueText = "";
			String section = (String) value;
			RateIndex ri = parentDialog.getChapter(section);
			if (ri != null) {
				valueText = ri.getLabel().replaceAll("G_", "").replaceAll("_", ".") + " " + HospitalisationPeriodDialog.trimDesc(ri.getTitle());
			}

			Component c =  super.getListCellRendererComponent(list, valueText, index, isSelected, cellHasFocus);
			return c;
		}
	}

	class TransferOptionBoxRenderer extends DefaultListCellRenderer
	{
		private static final long serialVersionUID = 1L;

		public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)
		{
			String text = "";

			CBItem item = (CBItem) value; 
			if (item != null) {	
				String code = item.getCode().replaceAll("G_", "").replaceAll("_", ".");
				text = code + " - " + item.getLabel();
			}
			Component c = super.getListCellRendererComponent(list, text.replace("<html>", "").replace("<br>", ""), index, isSelected, cellHasFocus);

			if (isSelected)
				list.setToolTipText(text);
			return c;
		}
	}

	public void init(Date date) {
		listenersActive = false;
		// initialise the components
		hospitalisationStartDateChooser.setDate(date);
		hospitalisationEndDateChooser.setDate(date);
		Calendar c = new GregorianCalendar();
		c.set(Calendar.HOUR_OF_DAY, 12);
		c.set(Calendar.MINUTE, 		0);
		c.set(Calendar.SECOND, 		0);
		c.set(Calendar.MILLISECOND, 0);
		hospitalisationStartTimeChooser.setTimeOnCalendar(c);
		hospitalisationEndTimeChooser.setTimeOnCalendar(c);
		listenersActive = true;
	}


	void saveSectionSelection ()
	{
		String section = sectionList.getSelectedValue();
		LoginScreen.setMachineSetting(SECTION_SETTING, section);
	}

	void loadSectionSelection()
	{
		try {
			String sectionSetting = LoginScreen.getMachineSetting(SECTION_SETTING);
			sectionList.setSelectedIndex(0);
			sectionList.setSelectedValue(sectionSetting, true);			
		} catch (Exception e) {

		}
	}
}
