/*******************************************************************************
 * 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.core.gui.widgets;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Invoice;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.utils.ComponentTitledPanel;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.core.utils.AccidentNumberFormatter;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Insurance;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

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

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

public class AccidentPropertiesPanel extends JPanel implements ItemListener,
															   ActionListener,
															   PropertyChangeListener,
															   Relocalizable
	{
	private static final long serialVersionUID = 1L;
	
	private ComponentTitledPanel	m_BorderPanel;
	private JCheckBox				m_IsAccident;
	private JPanel					m_Content;
	
	private JLabel					m_AccidentNumberLabel;
	private JLabel					m_AccidentDateLabel;
	
	private JFormattedTextField 	m_AccidentNumber;
	private JDateChooser 			m_AccidentDate;
	
	private DateFormat				m_DateFormat;
	
	private JTextField				m_AccidentNumberField;
	private JTextField				m_AccidentDateField;
	
	private boolean					m_Enabled;
	
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************

	public static final String  c_IsAccident     = "AccidentPropertiesPanel.IsAccident";
	public static final String  c_AccidentDate   = "AccidentPropertiesPanel.AccidentDate";
	public static final String  c_AccidentNumber = "AccidentPropertiesPanel.AccidentNumber";
	
	private final static String c_Columns= 	"fill:max(60dlu;pref),3dlu," +
										 	"fill:max(60dlu;pref)";
	
	private final static String c_Rows=    	"fill:pref,3dlu,fill:pref";
	
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************

public AccidentPropertiesPanel ()
    {	
	CellConstraints		l_Constraints;
    FormLayout			l_Layout;
    JSpinnerDateEditor	l_DateEditor;
    Color				l_DefaultColor; 
     
    this.setOpaque(false);
    this.setLayout(new BorderLayout());
    
    l_Constraints  = new CellConstraints();
     
    m_Content	= new JPanel ();
    m_Content.setOpaque(false);
    
    l_Layout = new FormLayout(c_Columns, c_Rows);
    m_Content.setLayout(l_Layout);
     
    m_AccidentNumberLabel			= new JLabel ();
    m_AccidentNumberLabel.setForeground (GECAMedColors.c_LabelColor);
    
    m_AccidentDateLabel			= new JLabel ();
    m_AccidentDateLabel.setForeground (GECAMedColors.c_LabelColor);
           
    l_DefaultColor = (Color) UIManager.getDefaults().get("TextField.inactiveBackground");   
    UIManager.getDefaults().put("TextField.inactiveBackground", Color.WHITE );
    
    m_AccidentNumber = new JFormattedTextField (new AccidentNumberFormatter());
    m_AccidentNumber.setHorizontalAlignment (JTextField.RIGHT);
    m_AccidentNumber.addActionListener (this);
    m_AccidentNumberField = new JTextField (); 
    m_AccidentNumberField.setEditable (false);
    
    m_AccidentDate = GECAMedGuiUtils.getDateChooser(false); 

    m_AccidentDate.addPropertyChangeListener(this);
    m_AccidentDateField = new JTextField ();
    m_AccidentDateField.setEditable (false);
     
    UIManager.getDefaults().put("TextField.inactiveBackground", l_DefaultColor );
      
    this.relocalize ();
    
    m_Content.add (m_AccidentNumberLabel, 		l_Constraints.xywh(1,1, 1, 1));
    m_Content.add (m_AccidentDateLabel, 		l_Constraints.xywh(3,1, 1, 1));
 
    m_Content.add (m_AccidentNumber, 		l_Constraints.xywh(1,3, 1, 1));
    m_Content.add (m_AccidentDate, 		l_Constraints.xywh(3,3, 1, 1));
  
    m_IsAccident = new JCheckBox (Translatrix.getTranslationString("AccidentPropertiesPanel.Title"));
    m_IsAccident.setBackground(GECAMedColors.c_GECAMedBackground);
    m_IsAccident.setSelected(true);
    m_IsAccident.addItemListener (this);
    
    m_BorderPanel = new ComponentTitledPanel (m_IsAccident,m_Content);
    this.add(m_BorderPanel);
    
    this.setEnabled(true);
    }

//***************************************************************************
//* Class Primitives                                                        *
//***************************************************************************

//---------------------------------------------------------------------------
/**
 * Method is part of the Relocalizable interface. The method does everything
 * required to reflect changes of active Locale
 */
//---------------------------------------------------------------------------

public void relocalize() 
	{
   	Locale  l_Locale;
  	
	l_Locale = Translatrix.getLocale ();
	  	
//	if (l_Locale != null) 
//		 m_DateFormat = new SimpleDateFormat ("d MMMM yyyy",l_Locale);
//	else m_DateFormat = new SimpleDateFormat ("d MMMM yyyy");  
	
	m_DateFormat = GECAMedGuiUtils.getDateFormat(false);

	if (m_IsAccident != null)
		{
		m_IsAccident.setText (Translatrix.getTranslationString("AccidentPropertiesPanel.Title"));
//		m_IsAccident.repaint();
		}
		
	if (m_AccidentNumberLabel!=null) 
		m_AccidentNumberLabel.setText (Translatrix.getTranslationString("AccidentPropertiesPanel.AccidentNumberLabel"));
	
	if (m_AccidentDateLabel!=null) 
		m_AccidentDateLabel.setText (Translatrix.getTranslationString("AccidentPropertiesPanel.AccidentDateLabel"));
	}

//---------------------------------------------------------------------------

private void swapComponents (JComponent p_Out, JComponent p_In, CellConstraints p_Constraints)
	{
	if (p_Out.getParent() == m_Content)
		{
		m_Content.remove (p_Out);
		m_Content.add( p_In,p_Constraints);
		}
	}

//---------------------------------------------------------------------------

private void setEnabledState (boolean p_EnableIt)
	{
	CellConstraints		l_Constraints;
	
    l_Constraints  = new CellConstraints();
	
	if (p_EnableIt)
		{
		this.swapComponents(m_AccidentNumberField,	m_AccidentNumber,		l_Constraints.xywh(1, 3, 1, 1));
		this.swapComponents(m_AccidentDateField,  	m_AccidentDate,  		l_Constraints.xywh(3, 3, 1, 1));
		}
	else
		{
		this.swapComponents(m_AccidentNumber,		m_AccidentNumberField,	l_Constraints.xywh(1, 3, 1, 1));
		this.swapComponents(m_AccidentDate,  		m_AccidentDateField,  	l_Constraints.xywh(3, 3, 1, 1));
		}
	
	this.validate(); //m_BorderPanel.repaint();
	this.repaint();
	}

//---------------------------------------------------------------------------

public void propertyChange (PropertyChangeEvent p_ChangeEvent) 
	{
	Date	l_AccidentDate;
	String	l_AccidentNumber;
	
	if (!this.isEnabled()) return;
	
	if ( (p_ChangeEvent.getSource() == m_AccidentDate) &&
		 ("date".equals(p_ChangeEvent.getPropertyName())))	
		{
		l_AccidentDate = m_AccidentDate.getDate();
		this.firePropertyChange(c_AccidentDate,   
								p_ChangeEvent.getOldValue(), 
								p_ChangeEvent.getNewValue());
		
		if (m_IsAccident.isSelected() && this.getAccidentNumber().length() == 0)
			{
			l_AccidentNumber = AccidentNumberFormatter.getAccidentNumber(l_AccidentDate);
			this.setAccidentNumber(l_AccidentNumber);
			this.firePropertyChange(c_AccidentNumber, null, l_AccidentNumber);		
			}
		}
	}

//---------------------------------------------------------------------------

public void actionPerformed (ActionEvent p_ChangeEvent) 
	{
	if (!this.isEnabled()) return;
	
	if (p_ChangeEvent.getSource() == m_AccidentNumber)
    	{
    	this.firePropertyChange(c_AccidentNumber, null, this.getAccidentNumber());
    	}
	}

//---------------------------------------------------------------------------

public void itemStateChanged (ItemEvent p_ChangeEvent) 
	{
	Object	l_Source;

	l_Source = p_ChangeEvent.getItemSelectable();
	if ((l_Source == m_IsAccident) && (this.isEnabled()))
		{
		if (p_ChangeEvent.getStateChange() == ItemEvent.DESELECTED)
			{
			this.m_AccidentNumber.setText("");
			this.m_AccidentDateField.setText("");
			this.setEnabledState(false);
			this.firePropertyChange(c_IsAccident, true, false);
			}
		else if (p_ChangeEvent.getStateChange() == ItemEvent.SELECTED)
			{
			this.setEnabledState(true);
			this.firePropertyChange(c_IsAccident, false, true);
			}
		}
	}

//***************************************************************************
//* Class Body                                                              *
//***************************************************************************

//---------------------------------------------------------------------------

public void setEnabled (boolean p_EnableIt)
	{
	if (p_EnableIt) {
		m_IsAccident.setEnabled (p_EnableIt);
		if (m_IsAccident.isSelected()) 
			this.setEnabledState(p_EnableIt);
	} else {
		m_IsAccident.setEnabled (p_EnableIt);
		this.setEnabledState(p_EnableIt);
	}
	m_Enabled = p_EnableIt;
	}

//---------------------------------------------------------------------------

public boolean isEnabled ()
	{
	return m_Enabled;
	}

//---------------------------------------------------------------------------

public void setInvoice (Invoice p_Invoice)
	{
	if (p_Invoice == null) return;
	
	setAccident				(p_Invoice.isAccident());
	setAccidentNumber	 	(p_Invoice.getAccidentNumber());
	setAccidentDate		 	(p_Invoice.getAccidentDate());
	}

//---------------------------------------------------------------------------

public boolean updateInvoice (Invoice p_Invoice)
	{
	boolean l_InvoiceModified = false;
	
	if (p_Invoice == null) return false;
	
	if (this.isAccident() == true)
		{
		if (!this.getAccidentNumber().equals (p_Invoice.getAccidentNumber()))
			{
			p_Invoice.setAccidentNumber (this.getAccidentNumber());
			l_InvoiceModified = true;
			}

		if (!this.getAccidentDate().equals (p_Invoice.getAccidentDate()))
			{
			p_Invoice.setAccidentDate (this.getAccidentDate());
			l_InvoiceModified = true;
			}
		
//		// changed Insurance to AAI
//		if (p_Invoice.getHealthInsurance() == null || !Insurance.INSURANCE_AAA.equals(p_Invoice.getHealthInsurance().getAcronym())) {
//			p_Invoice.setHealthInsurance(Insurance.INSURANCE_AAA);
//			l_InvoiceModified = true;
//		}
//		// changed Insurance to AAI
//		if (p_Invoice.getThirdPartyPayer() == null || !Insurance.INSURANCE_AAA.equals(p_Invoice.getThirdPartyPayer().getAcronym())) {
//			p_Invoice.setThirdPartyPayer(Insurance.INSURANCE_AAA);
//			l_InvoiceModified = true;
//		}
		
		}
	else
		{
		if (p_Invoice.isAccident())
			{
			p_Invoice.setAccidentDate (null);
			p_Invoice.setAccidentNumber (null);
			l_InvoiceModified = true;
			}
		}
		
	return l_InvoiceModified;
	}

//---------------------------------------------------------------------------

public void reset ()
	{
	this.setAccident(false);
	this.resetAccidentDate();
	this.resetAccidentNumber();
	}

//---------------------------------------------------------------------------

public boolean isAccident ()
	{
	return m_IsAccident.isSelected();
	}

//---------------------------------------------------------------------------

public void setAccident (boolean p_IsAccident)
	{
	m_IsAccident.setSelected(p_IsAccident);
//	if (this.isEnabled()) this.setEnabledState(p_IsAccident);
	}

//---------------------------------------------------------------------------
/**
 * Returns the Accident Number currently present in m_AccidentNumber text field
 */
//---------------------------------------------------------------------------

public String getAccidentNumber ()
	{
	String	l_Value;
	
	l_Value = (String) m_AccidentNumber.getValue();
	if (l_Value == null || l_Value.equals(AccidentNumberFormatter.c_EmptyField)) l_Value = "";
	
	return l_Value;
	}

//---------------------------------------------------------------------------

public void setAccidentNumber (String p_AccidentNumber)
	{
	if ((p_AccidentNumber != null) && (p_AccidentNumber.length() > 0))
		{
		m_AccidentNumber.setValue (p_AccidentNumber);
		m_AccidentNumberField.setText(m_AccidentNumber.getText());
		}
	else resetAccidentNumber ();
	}

//---------------------------------------------------------------------------

public void resetAccidentNumber ()
	{
	m_AccidentNumber.setValue (AccidentNumberFormatter.c_EmptyField);
	m_AccidentNumberField.setText("");
	}

//---------------------------------------------------------------------------
/**
 * Returns the Accident Date currently selected in the Accident date chooser.
 * @return : returns the currently selected date if date chooser is enabled,
 * <b>null</b> otherwise.
 */
//---------------------------------------------------------------------------

public Date getAccidentDate ()
	{
	return m_AccidentDate.getDate();
	}

//---------------------------------------------------------------------------

public void setAccidentDate (Date p_AccidentDate)
	{
	if (this.isAccident())
		{
//		if ((p_AccidentDate != null) && (getAccidentNumber().length() > 0))
		if (p_AccidentDate != null)
			{
			m_AccidentDate.setDate (p_AccidentDate);
			m_AccidentDateField.setText(m_DateFormat.format (p_AccidentDate));
			
			if (this.getAccidentNumber().length() == 0)
				this.setAccidentNumber(AccidentNumberFormatter.getAccidentNumber (p_AccidentDate));		
			}
		else resetAccidentDate ();
		}
	else resetAccidentDate ();
	}

//---------------------------------------------------------------------------

public void resetAccidentDate ()
	{
	m_AccidentDate.setDate (new Date());
	m_AccidentDateField.setText("");
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class															*
//***************************************************************************
}
