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

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
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.CaretEvent;
import javax.swing.event.CaretListener;
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.formeditor.gui.component.NumericField;
import lu.tudor.santec.i18n.Translatrix;

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 HospitalisationPeriodGeneralTab extends JPanel {


	private static final long serialVersionUID = 1L;
	private CellConstraints cc = new CellConstraints();
	
	NumericField		intensiveCareDaysSpentField;
	
	JCheckBox 			intensiveCarePeriodBox;
	
	JDateChooser		hospitalisationStartDateChooser;
	JDateChooser		hospitalisationEndDateChooser;
	JDateChooser		intensiveCareStartDateChooser;
	JDateChooser		intensiveCareEndDateChooser;

	JList<CBItem> 		transferOptionBox;
	private JLabel				transferOptionsLabel;
	DefaultListModel<CBItem> transferOptionModel = new DefaultListModel<CBItem>();
	
	JList<String> 		sectionList;
	private HospitalisationPeriodDialog parentDialog;
	
	private int 	daysAlreadySpent = 0;
	private boolean listenersActive = false;
	
	private static final String	SECTION_SETTING	= "billing.hospitalisationPeriod.generalsection";
	
	
	
	 public HospitalisationPeriodGeneralTab(final HospitalisationPeriodDialog parent) {
		 this.parentDialog = parent;
		 
			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);
					}		
				}
			};
		 
		// 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);
			hospitalisationEndDateChooser 		= GECAMedGuiUtils.getDateChooser(false);
			
			hospitalisationStartDateChooser.addPropertyChangeListener(periodUpdater);
			hospitalisationEndDateChooser.addPropertyChangeListener(periodUpdater);
			
			// PERIOD OF INTENSIVE CARE
			intensiveCarePeriodBox = new JCheckBox(
					Translatrix.getTranslationString("HospitalisationPeriodDialog.intensiveCarePeriod"));
			intensiveCarePeriodBox.setOpaque(false);
			JLabel intensiveCareFromLabel 		= new JLabel(
					Translatrix.getTranslationString("HospitalisationPeriodDialog.from"));
			JLabel intensiveCareToLabel 		= new JLabel(
					Translatrix.getTranslationString("HospitalisationPeriodDialog.to"));
			JLabel intensiveCareDaysSpentLabel 	= new JLabel(
					Translatrix.getTranslationString("HospitalisationPeriodDialog.daysAlreadySpent"));
			JPanel intensiveCareDaysSpentPanel 	= new JPanel(new FormLayout("30px, 5px, f:p", "f:p"));
			intensiveCareDaysSpentPanel.setOpaque(false);
			intensiveCareStartDateChooser 	= GECAMedGuiUtils.getDateChooser(false);
			intensiveCareEndDateChooser 	= GECAMedGuiUtils.getDateChooser(false);
			intensiveCareDaysSpentField 	= new NumericField(String.valueOf(daysAlreadySpent), false);
			intensiveCarePeriodBox.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					enableIntensiveCare();
					loadTransferRates();
					parent.calculateRates(false);
				}
			});
			intensiveCareDaysSpentField.setMaximumSize(new Dimension(30, 30));
			intensiveCareStartDateChooser.addPropertyChangeListener(periodUpdater);
			intensiveCareEndDateChooser.addPropertyChangeListener(periodUpdater);
			intensiveCareDaysSpentField.addCaretListener(new CaretListener()
			{
				public void caretUpdate(CaretEvent e)
				{
					if (daysAlreadySpent != intensiveCareDaysSpentField.getInt())
					{
						daysAlreadySpent = (int)intensiveCareDaysSpentField.getInt();
						parent.calculateRates(false);
					}
				}
			});
			
			intensiveCareDaysSpentPanel.add(intensiveCareDaysSpentField, cc.xy(1, 1));
			intensiveCareDaysSpentPanel.add(intensiveCareDaysSpentLabel, cc.xy(3, 1));
			
			enableIntensiveCare();
			
			// nomenclature section (physician type and post-OP)
			JLabel sectionChooserLabel		= new JLabel(
					Translatrix.getTranslationString("HospitalisationPeriodDialog.selectSection"));
			sectionChooserLabel.setOpaque(false);
			
			sectionList = new JList<String>(HospitalisationPeriodDialog.GENERAL_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());
//			sectionList.setPreferredSize(new Dimension())
			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:80dlu, 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), 20px, f:p, 5px, f:max(150px;p),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(hospitalisationToLabel, 			cc.xy (7, 4));
		hospPanel.add(hospitalisationEndDateChooser, 	cc.xy (9, 4));
		this.add(hospPanel, cc.xy(2, generalRow+=2));
		
		JPanel intensivPanel = new JPanel(new FormLayout(
				"5px, 15px, f:p, 5px, f:max(150px;p), 20px, f:p, 5px, f:max(150px;p),5px",
				"5px, 20px, 5px, pref, 5px, pref, 5px"
		));
		intensivPanel.setOpaque(false);
		intensivPanel.setBorder(new LineBorder(Color.BLACK));
		intensivPanel.add(intensiveCarePeriodBox, 		cc.xyw(2, 2, 9));
		intensivPanel.add(intensiveCareFromLabel, 		cc.xy (3, 4));
		intensivPanel.add(intensiveCareStartDateChooser,cc.xy (5, 4));
		intensivPanel.add(intensiveCareToLabel, 		cc.xy (7, 4));
		intensivPanel.add(intensiveCareEndDateChooser,  cc.xy (9, 4));
		intensivPanel.add(intensiveCareDaysSpentPanel, 	cc.xyw(2, 6, 9));
		this.add(intensivPanel, cc.xy(4, generalRow));
		
		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));
		
		intensiveCareDaysSpentField.setOpaque(true);
		listenersActive = true;
		loadTransferRates();
	}
	
		private void enableIntensiveCare ()
		{
			boolean enable = intensiveCarePeriodBox.isSelected();
			intensiveCareStartDateChooser.setEnabled(enable);
			intensiveCareEndDateChooser.setEnabled(enable);
			intensiveCareDaysSpentField.setEnabled(enable);
		}
		
		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 if ((selectedSection.equals(HospitalisationPeriodDialog.SECTION_71) || selectedSection.equals(HospitalisationPeriodDialog.SECTION_72)) && !intensiveCarePeriodBox.isSelected()) {
				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);
			intensiveCarePeriodBox.setSelected(false);
			intensiveCareStartDateChooser.setDate(date);
			intensiveCareEndDateChooser.setDate(date);
			intensiveCareDaysSpentField.setText("0");
			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) {
				
			}
		}
}
