/*******************************************************************************
 * 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.billing.gui.settlement;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.TextAttribute;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Currency;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Account;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Invoice;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Payment;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Settlement;
import lu.tudor.santec.gecamed.billing.gui.BillingModule;
import lu.tudor.santec.gecamed.billing.utils.CurrencyFormat;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
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;

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

public class SettlementDialog extends JDialog implements ActionListener,
														 PropertyChangeListener,
													     Relocalizable
	{
	private static final long serialVersionUID = 1L;
	
	private JLabel					m_InvoiceLabel;
	private JLabel					m_AmountLabel;
	private JLabel					m_PayedLabel;
	private JLabel					m_AmountToPayLabel;
	private JLabel					m_PaymentLabel;
	private JLabel					m_DeductionLabel;
	private JLabel					m_ReturnLabel;
	private JLabel					m_DateLabel;
	private JLabel					m_MethodLabel;

	private TitledBorder			m_InvoiceBorder;
	private TitledBorder			m_SettlementBorder;
	private TitledBorder			m_PrintBorder;
	private TitledBorder			m_PaymentBorder;
	private TitledBorder			m_TransferBorder;

	private JLabel					m_InvoiceNumber;
	private JLabel					m_Amount;
	private JLabel					m_Payed;
	private JLabel					m_AmountToPay;
	private JFormattedTextField		m_Payment;
	private JFormattedTextField		m_Deduction;
	private JTextField				m_Return;
	private JDateChooser			m_Date;

	private JCheckBox				m_PrintSettledInvoice;
	
	private	Invoice					m_Invoice;
	private CurrencyFormat			m_CurrencyFormat;
	private DateFormat				m_DateFormat;
	
	private JPanel					m_TransferPanel;
	
	private Vector <JButton>		m_PaymentButtons;
	private Vector <JButton>		m_TransferButtons;
	private JButton					m_CancelButton;
	
	private boolean					m_InvoiceSettled;
	private double					m_PaidAmount;
	private double					m_ReturnedAmount;
	
	private Physician				m_Physician;
	
	private Collection <Settlement>	m_PaymentSettlements;
	private Collection <Settlement>	m_TransferSettlements;
	
	private Hashtable <JButton,Settlement>	m_SettlementLookup;
	
	private Color					m_DefaultBackground;
	private Color					m_DefaultForeground;

	private Settlement m_Settlement;

	private JCheckBox m_DeductionActive;
		
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************
	
	private final static String c_Columns				= 	"3dlu,fill:max(100dlu;pref):grow," +
															"3dlu,fill:max(100dlu;pref):grow,3dlu";
	
	private final static String c_Rows					=   "3dlu,fill:pref," +
															"3dlu,fill:pref," +
															"3dlu,fill:pref," +
															"3dlu,fill:pref," +
										 					"3dlu,fill:pref,3dlu";
	
	private final static String c_InvoicePanelColumns 	= 	"3dlu,fill:max(70dlu;pref)," +
															"3dlu,fill:max(110dlu;pref),3dlu, pref, 3dlu";

	private final static String c_InvoicePanelRows 		= 	"3dlu,fill:pref,"
															+ "3dlu,fill:pref,"
															+ "3dlu,fill:pref,"
															+ "3dlu,fill:pref,"
															+ "3dlu,fill:pref,3dlu";
	
	private final static String c_SettlementPanelColumns = 	"3dlu,fill:max(70dlu;pref)," +
														   	"3dlu,fill:max(110dlu;pref),3dlu";

	private final static String c_SettlementPanelRows 	= 	"3dlu,fill:pref," +
															"3dlu,fill:pref," +
															"3dlu,fill:pref,3dlu";

	private final static String c_PrintPanelColumns 	= 	"3dlu,fill:max(70dlu;pref)," +
															"3dlu,fill:max(110dlu;pref),3dlu";

	private final static String c_PrintPanelRows 		= 	"3dlu,fill:pref,3dlu";

	private final static String c_MethodPanelColumns 	= 	"3dlu,fill:pref:grow,3dlu";

//***************************************************************************
//* Constructor                                                             *
//***************************************************************************

public SettlementDialog (Physician p_Physician, Collection <Settlement> p_Settlements)	
	{	
	super (MainFrame.getInstance(),Translatrix.getTranslationString("SettlementDialog.Title"),true);
	
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;
	
	JPanel			l_InvoicePanel;
	JPanel			l_PaymentPanel;
	JPanel			l_PrintPanel;
	JPanel			l_SettlementPanel;
	
	m_InvoiceSettled    = false;
	m_Physician			= p_Physician;
	
	m_InvoiceBorder 	= new TitledBorder ("");
	m_SettlementBorder 	= new TitledBorder ("");
	m_PrintBorder		= new TitledBorder ("");
	m_PaymentBorder  	= new TitledBorder ("");
	m_TransferBorder  	= new TitledBorder ("");

	m_InvoiceLabel 		= new JLabel ();
	m_InvoiceLabel.setForeground(GECAMedColors.c_LabelColor);
	m_AmountLabel 		= new JLabel ();
	m_AmountLabel.setForeground(GECAMedColors.c_LabelColor);
	m_PayedLabel 		= new JLabel ();
	m_PayedLabel.setForeground(GECAMedColors.c_LabelColor);
	m_AmountToPayLabel 		= new JLabel ();
	m_AmountToPayLabel.setForeground(GECAMedColors.c_LabelColor);
	m_PaymentLabel 		= new JLabel ();
	m_PaymentLabel.setForeground(GECAMedColors.c_LabelColor);
	m_DeductionLabel 		= new JLabel ();
	m_DeductionLabel.setForeground(GECAMedColors.c_LabelColor);
	m_ReturnLabel 		= new JLabel ();
	m_ReturnLabel.setForeground(GECAMedColors.c_LabelColor);
	m_DateLabel 		= new JLabel ();
	m_DateLabel.setForeground(GECAMedColors.c_LabelColor);
	m_MethodLabel 		= new JLabel ();
	m_MethodLabel.setForeground(GECAMedColors.c_LabelColor);

	m_PrintSettledInvoice = new JCheckBox ();
	m_PrintSettledInvoice.setOpaque(false);
	
	m_CancelButton = new JButton ();
	m_CancelButton.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL));
	m_CancelButton.addActionListener(this);
	
	this.getContentPane().setBackground(GECAMedColors.c_GECAMedBackground);
	this.relocalize();
	
	//------------------------------------------------------------------------
	// Build Invoice Panel
	//------------------------------------------------------------------------
	
	l_Constraints  = new CellConstraints();
    
	l_InvoicePanel       = new JPanel ();
	l_InvoicePanel.setBorder (m_InvoiceBorder);
	    
	l_Layout = new FormLayout(c_InvoicePanelColumns, c_InvoicePanelRows);
	l_InvoicePanel.setLayout (l_Layout);
	l_InvoicePanel.setOpaque(false);
	
	m_InvoiceNumber = new JLabel ();
	m_Amount   		= new JLabel ("", JLabel.RIGHT);
	m_Payed   		= new JLabel ("", JLabel.RIGHT);
	m_AmountToPay   = new JLabel ("", JLabel.RIGHT);
	
	m_Deduction = new JFormattedTextField (m_CurrencyFormat);
	m_Deduction.setHorizontalAlignment(JTextField.RIGHT);
	m_Deduction.setText (formatCurrency(0.0));
	m_Deduction.addPropertyChangeListener("value",this);
	m_Deduction.setEditable(false);
	
	m_DeductionActive = new JCheckBox();
	m_DeductionActive.setSelected(false);
	m_DeductionActive.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			m_Deduction.setEditable(m_DeductionActive.isSelected());
		}
	});
	
	
	l_InvoicePanel.add (m_InvoiceLabel,    	l_Constraints.xywh(2, 2, 1, 1));
	l_InvoicePanel.add (m_InvoiceNumber,   	l_Constraints.xywh(4, 2, 1, 1));
	
	l_InvoicePanel.add (m_AmountLabel,    	l_Constraints.xywh(2, 4, 1, 1));
	l_InvoicePanel.add (m_Amount,   		l_Constraints.xywh(4, 4, 1, 1));
	
	l_InvoicePanel.add (m_PayedLabel,    	l_Constraints.xywh(2, 6, 1, 1));
	l_InvoicePanel.add (m_Payed,   			l_Constraints.xywh(4, 6, 1, 1));
	
	l_InvoicePanel.add (m_DeductionLabel,  	l_Constraints.xywh(2, 8, 1, 1));
	l_InvoicePanel.add (m_Deduction,   		l_Constraints.xywh(4, 8, 1, 1));
	l_InvoicePanel.add (m_DeductionActive,  l_Constraints.xywh(6, 8, 1, 1));
	
	l_InvoicePanel.add (m_AmountToPayLabel, l_Constraints.xywh(2, 10, 1, 1));
	l_InvoicePanel.add (m_AmountToPay,      l_Constraints.xywh(4, 10, 1, 1));
	
	//------------------------------------------------------------------------
	// Build Settlement Panel
	//------------------------------------------------------------------------

	l_SettlementPanel      = new JPanel ();
	l_SettlementPanel.setBorder (m_SettlementBorder);
	l_SettlementPanel.setOpaque(false);
	
	l_Layout = new FormLayout(c_SettlementPanelColumns, c_SettlementPanelRows);
	l_SettlementPanel.setLayout (l_Layout);
	
	m_Payment = new JFormattedTextField (m_CurrencyFormat);
	m_Payment.setHorizontalAlignment(JTextField.RIGHT);
	m_Payment.setText (formatCurrency(0.0));
	m_Payment.addPropertyChangeListener("value",this);
		
	m_Return = new JTextField ();
	m_Return.setHorizontalAlignment(JTextField.RIGHT);
	m_Return.setText (formatCurrency(0.0));
	m_Return.setEditable(false);
	
	m_DefaultForeground = m_Return.getForeground();
	m_DefaultBackground = m_Return.getBackground();
	
	m_Date    = GECAMedGuiUtils.getDateChooser(false);
	m_Date.setDate(new Date());
	m_Date.addPropertyChangeListener (this);
	
	l_SettlementPanel.add (m_PaymentLabel,  	l_Constraints.xywh(2, 2, 1, 1));
	l_SettlementPanel.add (m_Payment,   		l_Constraints.xywh(4, 2, 1, 1));
	l_SettlementPanel.add (m_ReturnLabel,  	l_Constraints.xywh(2, 4, 1, 1));
	l_SettlementPanel.add (m_Return,   		l_Constraints.xywh(4, 4, 1, 1));
	l_SettlementPanel.add (m_DateLabel,    		l_Constraints.xywh(2, 6, 1, 1));
	l_SettlementPanel.add (m_Date,   			l_Constraints.xywh(4, 6, 1, 1));
	
	
	//------------------------------------------------------------------------
	// Build Print Panel
	//------------------------------------------------------------------------
	
	l_Constraints  = new CellConstraints();
    
	l_PrintPanel       = new JPanel ();
	l_PrintPanel.setBorder (m_PrintBorder);
	    
	l_Layout = new FormLayout(c_PrintPanelColumns, c_PrintPanelRows);
	l_PrintPanel.setLayout (l_Layout);
	l_PrintPanel.setOpaque(false);
	
	l_PrintPanel.add (m_PrintSettledInvoice,   	l_Constraints.xywh(4, 2, 1, 1));
	
	//------------------------------------------------------------------------
	// Build Method Panel
	//------------------------------------------------------------------------

//	this.loadSettlementMethods();
	this.populateSettlements(p_Settlements);
	this.createSettlementButtons();
	
	l_PaymentPanel = this.buildPaymentPanel();
	m_TransferPanel = this.buildTransferPanel();
	
	l_Layout = new FormLayout(c_Columns, c_Rows);
    this.setLayout (l_Layout);

	//------------------------------------------------------------------------
	// Cancel Button
	//------------------------------------------------------------------------
     
    this.add(l_InvoicePanel,     l_Constraints.xywh(2, 2, 3, 1));
    this.add(l_SettlementPanel,  l_Constraints.xywh(2, 4, 3, 1));
    this.add(l_PrintPanel,       l_Constraints.xywh(2, 6, 3, 1));
    this.add(l_PaymentPanel,     l_Constraints.xywh(2, 8, 1, 1));
    this.add(m_TransferPanel,    l_Constraints.xywh(4, 8, 1, 1));
    this.add(m_CancelButton,     l_Constraints.xywh(4, 10, 1, 1));
	}
	
//***************************************************************************
//* Class Primitives                                                        *
//***************************************************************************
//---------------------------------------------------------------------------

private double getPayment ()
	{
	double	l_Payment;
	
	try	{
		l_Payment = parseCurrency(m_Payment.getText());
		}
	catch (ParseException p_Exception)
		{
		l_Payment = 0;
		}

	return l_Payment;
	}

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

public double getDeduction ()
	{
	double	l_Deduction;
	
	try	{
		l_Deduction = parseCurrency(m_Deduction.getText());
		}
	catch (ParseException p_Exception)
		{
		l_Deduction = 0;
		}

	return l_Deduction;
	}

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

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

private double calculateReturn ()
	{
	BigDecimal l_Payment;
	BigDecimal l_Amount2Pay;
	
	if (m_Invoice == null) return 0;

	l_Amount2Pay= new BigDecimal(this.getAmount2Pay()).setScale (2,RoundingMode.HALF_DOWN);
	l_Payment 	= new BigDecimal(this.getPayment()).setScale (2,RoundingMode.HALF_DOWN);
	
	double l_Return = l_Payment.subtract(l_Amount2Pay).doubleValue();
	m_ReturnedAmount = (l_Return > 0)?l_Return:0;
	
	return  l_Return;
	}

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

private void populateSettlements (Collection <Settlement> p_Settlements)
	{
	Iterator <Settlement> 	l_SettlementIterator;
	Settlement				l_SettlementMethod;
	
	if (p_Settlements == null) return;
	
	m_PaymentSettlements  = new ArrayList <Settlement> ();
	m_TransferSettlements = new ArrayList <Settlement> ();
	
	l_SettlementIterator = p_Settlements.iterator();
	while (l_SettlementIterator.hasNext())
		{
		l_SettlementMethod = l_SettlementIterator.next();
		switch (l_SettlementMethod.getSettlementMethod())
			{
			case Settlement.c_Payment :
				
				m_PaymentSettlements.add(l_SettlementMethod);
				break;
				
			case Settlement.c_Transfer :
				
				m_TransferSettlements.add(l_SettlementMethod);
				break;
			}
		}
	}

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

@SuppressWarnings("unchecked")
private void createSettlementButtons ()
	{
	Iterator <Settlement>	l_SettlementIterator;
	Settlement				l_Settlement;
	Payment					l_Payment;
	Account					l_Account;
	JButton					l_Button;
	StringBuilder			l_Label;
	ImageIcon				l_Icon;
	Map<TextAttribute, Object>	l_Attributes;
	
	m_SettlementLookup = new Hashtable <JButton,Settlement> ();
	m_PaymentButtons   = new Vector <JButton> ();
	
	l_SettlementIterator = m_PaymentSettlements.iterator();
	while (l_SettlementIterator.hasNext())
		{
		l_Settlement = l_SettlementIterator.next();
		l_Payment    = l_Settlement.getPayment();
		
		l_Icon = BillingModule.getIconResource(l_Payment.getMethod().toLowerCase().replace(" ", "") + ".png");
		
		l_Button = new JButton ();
		l_Button.setIcon(l_Icon);
		l_Button.setText(l_Payment.getMethod());
		l_Button.setHorizontalAlignment(SwingConstants.LEFT);
		l_Button.addActionListener(this);
		
		m_PaymentButtons.add(l_Button);
		m_SettlementLookup.put(l_Button, l_Settlement);
		}
	
	m_TransferButtons = new Vector <JButton> ();
	
	l_SettlementIterator = m_TransferSettlements.iterator();
	while (l_SettlementIterator.hasNext())
		{
		l_Settlement = l_SettlementIterator.next();
		l_Account    = l_Settlement.getTransferAccount();
		
		//====================================================================
		//= If Settlement Account specifies a holder, then we have to check
		//= whether holder matches current physician. If Settlement Account
		//= doesn't specify a holder, then we'll assume its a shared account
		//= and it will always be shown.
		//====================================================================
				 
		if (l_Account.getHolder() != null)
			{
			if (!l_Account.getHolder().equals (m_Physician)) continue;
			}
		
			if(!l_Account.getObsolete())
			{
				l_Icon = BillingModule.getIconResource("transfer.png");
				
				l_Button = new JButton ();
				l_Button.setIcon(l_Icon);
				
				l_Label = new StringBuilder("<html><b>");
				if (l_Account.getLabel() != null 
						&& l_Account.getLabel().trim().length() > 0)
				{
					l_Label.append(l_Account.getLabel())
							.append("</b><br>");
				}
				l_Label.append(l_Account.getBankname())
						.append("<br>")
						.append("<span style=\"font-size: 7px\">")
						.append(l_Account.getIban());
				
				l_Attributes	= (Map<TextAttribute, Object>) l_Button.getFont().getAttributes();
				l_Attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
				l_Button.setFont(new Font(l_Attributes));
				l_Button.setText(l_Label.toString());
				l_Button.setToolTipText(l_Account.getIban());
				l_Button.setHorizontalAlignment(SwingConstants.LEFT);
				l_Button.addActionListener(this);
				
				m_TransferButtons.add(l_Button);
				m_SettlementLookup.put(l_Button, l_Settlement);
			}
		}	
	}

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

private String getMethodRows ()
	{
	String			l_MethodPanelRows;
	int				l_NumberOfRows;
	int				l_Row;

	l_NumberOfRows = Math.max(m_PaymentButtons.size(),m_TransferButtons.size());
	
	l_MethodPanelRows = "3dlu";
	
	for (l_Row = 0; l_Row < l_NumberOfRows; l_Row++)
		{
		l_MethodPanelRows += ",fill:pref,3dlu";
		}
	
	return l_MethodPanelRows;
	}

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

private JPanel buildPaymentPanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;

	JPanel			l_PaymentPanel;
		
	String			l_MethodPanelRows;
	int				l_Row;
	int				l_Position;

	l_Constraints  = new CellConstraints();
	
	l_MethodPanelRows = this.getMethodRows();
	
	l_PaymentPanel      = new JPanel ();
	l_PaymentPanel.setBorder (m_PaymentBorder);
	l_PaymentPanel.setOpaque(false);
	
	l_Layout = new FormLayout(c_MethodPanelColumns, l_MethodPanelRows);
	l_PaymentPanel.setLayout (l_Layout);

	for (l_Row = 0; l_Row < m_PaymentButtons.size(); l_Row++)
		{
		l_Position = (l_Row+1) * 2;
		
		l_PaymentPanel.add (m_PaymentButtons.elementAt(l_Row), l_Constraints.xywh(2, l_Position, 1, 1));
		}
	
	return l_PaymentPanel;
	}
	
//---------------------------------------------------------------------------

private JPanel buildTransferPanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;

	JPanel			l_TransferPanel;
		
	String			l_MethodPanelRows;
	int				l_Row;
	int				l_Position;

	l_Constraints  = new CellConstraints();

	l_MethodPanelRows = this.getMethodRows();
		
	l_TransferPanel = new JPanel ();
	l_TransferPanel.setBorder (m_TransferBorder);
	l_TransferPanel.setOpaque (false);
	
	l_Layout = new FormLayout(c_MethodPanelColumns, l_MethodPanelRows);
	l_TransferPanel.setLayout (l_Layout);
	
	for (l_Row = 0; l_Row < m_TransferButtons.size(); l_Row++)
		{
		l_Position = (l_Row+1) * 2;
		
		l_TransferPanel.add (m_TransferButtons.elementAt(l_Row), l_Constraints.xywh(2, l_Position, 1, 1));
		}
	
	return l_TransferPanel;
	}

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

private void enableSettlementButtons (boolean p_EnableIt)
	{
	Iterator <JButton> l_ButtonIterator;
	
	l_ButtonIterator = m_PaymentButtons.iterator();
	while (l_ButtonIterator.hasNext())
		{
		l_ButtonIterator.next().setEnabled(p_EnableIt);
		}
	
	l_ButtonIterator = m_TransferButtons.iterator();
	while (l_ButtonIterator.hasNext())
		{
		l_ButtonIterator.next().setEnabled(p_EnableIt);
		}
	}


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

private void settleInvoice (Settlement p_Settlement)
	{
//	double	l_AlreadyPaid;
//	double	l_Deduction;
//	double	l_Return;
	
	m_InvoiceSettled = false;
	
	if ((m_Invoice==null) || (p_Settlement == null)) return;
	
	if (m_Invoice.getBalance() == 0f) return;
	
	m_Settlement = p_Settlement;
	
	m_PaidAmount = this.getPayment();
//	l_Deduction  = this.getDeduction();
//	l_AlreadyPaid 	 = m_Invoice.getPayment();
	
//	l_Return		 = this.calculateReturn();
	
//	m_ReturnedAmount = (l_Return > 0)?l_Return:0;
	
	// payed by money transfer -> no change given to client
	if (p_Settlement.getTransferAccount() != null) {
		m_ReturnedAmount = 0.0;
	}
	
	if (p_Settlement.getPayment() != null || p_Settlement.getTransferAccount() != null) {
		m_InvoiceSettled = true;
	}
	
	// TODO LEDGER -> moved to Beanmethod
//	//========================================================================
//	//= Direct Payment
//	//========================================================================
//	
//	if (p_Settlement.getPayment() != null)
//		{
//		if (l_Balance > 0)
//			{
//			m_Invoice.setPayment	(l_AlreadyPaid + m_Invoice.getBalance());
//			m_Invoice.setDeduction	(0d);
//			}
//		else
//			{
//			m_Invoice.setPayment	(l_AlreadyPaid + m_PaidAmount);
//			m_Invoice.setDeduction	(l_Deduction);
//			}
//		
//		m_Invoice.setSettlement 	(p_Settlement);
//		m_Invoice.setSettlementDate	(m_Date.getDate());
//		m_InvoiceSettled = true;
//		}
//	
//	//========================================================================
//	//= Payment via Money Transfer
//	//========================================================================
//
//	else if (p_Settlement.getTransferAccount() != null)
//		{
//		m_Invoice.setPayment   		(l_AlreadyPaid + m_PaidAmount);
//		m_Invoice.setDeduction 		(l_Deduction);
//		m_Invoice.setSettlement 	(p_Settlement);
//		m_Invoice.setSettlementDate	(m_Date.getDate());
//		m_InvoiceSettled = true;
//		}

	}

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

private void checkSettlementDate ()
	{
	Date		l_SettlementDate;
	String []	l_Filler;
	
	if ((m_Invoice != null) && (m_Date != null))
		{
		l_SettlementDate = m_Date.getDate();
		if (l_SettlementDate.before(m_Invoice.getInvoiceDate()))
			{
			l_Filler = new String [1];
			l_Filler[0] = m_DateFormat.format(m_Invoice.getInvoiceDate());
			
			BillingModule.notifyUser("SettlementDialog.SettlementDateTitle", 
								 	 "SettlementDialog.SettlementDateMessage", l_Filler);
			}
		}
	}

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

public void setInvoice (Invoice p_Invoice)
	{
	if (p_Invoice == null) return;
	
	m_Invoice = p_Invoice;
	
	m_InvoiceNumber.setText(m_Invoice.formatInvoiceNumber(false, true));
	m_Amount.setText	(formatCurrency(m_Invoice.getAmount()));
	m_Payed.setText		(formatCurrency(m_Invoice.getPayment()));
	m_Deduction.setText	(formatCurrency(m_Invoice.getDeduction()));
	
	setAmount2Pay(true);

	valueChanged(true);
	
	m_DeductionActive.setSelected(false);

	m_Return.setBackground(m_DefaultBackground);
	this.enableSettlementButtons(true);
	
	m_InvoiceSettled = false;
	}

private void setAmount2Pay(boolean setPayment) {
	double amount2pay = m_Invoice.getAmount()-m_Invoice.getPayment()-getDeduction();
	m_AmountToPay.setText(formatCurrency(amount2pay));
	
	if (setPayment && amount2pay < 0.0) {
		m_Payment.setText(formatCurrency(0.0));
	} else {
		m_Payment.setText(formatCurrency(amount2pay));
	}
}

private double getAmount2Pay() {
	{
	double	l_Amount2Pay;
	
	try	{
		l_Amount2Pay = parseCurrency(m_AmountToPay.getText());
		}
	catch (ParseException p_Exception)
		{
		l_Amount2Pay = 0;
		}

	return l_Amount2Pay;
	}
}

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

public Invoice getInvoice ()
	{
	return m_Invoice;
	}

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

public void setPhysician (Physician p_Physician)
	{
	CellConstraints	l_Constraints;

	m_Physician = p_Physician;
	
	this.remove(m_TransferPanel);
	
	this.createSettlementButtons();	
	m_TransferPanel = this.buildTransferPanel();
	
	l_Constraints  = new CellConstraints();

	this.add (m_TransferPanel,   l_Constraints.xywh(4, 8, 1, 1));
	
	if (this.isVisible()) this.repaint();
	}

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

public Physician getPhysician ()
	{
	return m_Physician;
	}

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

public void setPrintSettledInvoice (Boolean p_PrintIt)
	{
	m_PrintSettledInvoice.setSelected(p_PrintIt);
	}

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

public boolean getPrintSettledInvoice ()
	{
	return m_PrintSettledInvoice.isSelected();
	}

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

public void setSettlementDate (Date p_Date)
	{
	m_Date.setDate(p_Date);
	}

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

public Date getSettlementDate ()
	{
	return m_Date.getDate();
	}

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

public boolean invoiceSettled ()
	{
	return m_InvoiceSettled;
	}

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

public double getPaidAmount ()
	{
	return m_PaidAmount;
	}

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

public double getReturnedAmount ()
	{
	return m_ReturnedAmount;
	}

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

public Settlement getSettlement ()
	{
	return m_Settlement;
	}

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

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);
	
//	m_CurrencyFormat = NumberFormat.getCurrencyInstance (Translatrix.getLocale());
//	m_CurrencyFormat.setCurrency(Currency.getInstance ("EUR"));
//	m_CurrencyFormat.setMaximumFractionDigits(2);
	
	m_CurrencyFormat = new CurrencyFormat (Currency.getInstance ("EUR"));
	
//	if (m_Date != null) 
//		{
//		m_Date.setLocale (l_Locale);
//		m_Date.setDateFormatString("d MMMM yyyy");   
//		m_Date.getDateEditor().setLocale (l_Locale);
//		}
	
	this.setTitle(Translatrix.getTranslationString("SettlementDialog.Title"));
	
	if (m_InvoiceBorder != null)
		m_InvoiceBorder.setTitle(Translatrix.getTranslationString("SettlementDialog.InvoiceBorder"));
	
	if (m_InvoiceLabel != null)
		m_InvoiceLabel.setText(Translatrix.getTranslationString("SettlementDialog.InvoiceLabel"));
	
	if (m_AmountLabel != null)
		m_AmountLabel.setText(Translatrix.getTranslationString("SettlementDialog.AmountLabel"));
	
	if (m_PayedLabel != null)
		m_PayedLabel.setText(Translatrix.getTranslationString("SettlementDialog.PayedLabel"));
	
	if (m_AmountToPayLabel != null)
		m_AmountToPayLabel.setText(Translatrix.getTranslationString("SettlementDialog.AmountToPayLabel"));
	
	if (m_SettlementBorder != null)
		m_SettlementBorder.setTitle(Translatrix.getTranslationString("SettlementDialog.SettlementBorder"));
	
	if (m_PaymentLabel != null)
		m_PaymentLabel.setText(Translatrix.getTranslationString("SettlementDialog.PaymentLabel"));
	
	if (m_DeductionLabel != null)
		m_DeductionLabel.setText(Translatrix.getTranslationString("SettlementDialog.DeductionLabel"));
	
	if (m_ReturnLabel != null)
		m_ReturnLabel.setText(Translatrix.getTranslationString("SettlementDialog.ReturnLabel"));
	
	if (m_DateLabel != null)
		m_DateLabel.setText(Translatrix.getTranslationString("SettlementDialog.DateLabel"));
	
	if (m_PaymentBorder != null)
		m_PaymentBorder.setTitle(Translatrix.getTranslationString("SettlementDialog.PaymentBorder"));
	
	if (m_PrintBorder != null)
		m_PrintBorder.setTitle(Translatrix.getTranslationString("SettlementDialog.PrintBorder"));
	
	if (m_PrintSettledInvoice != null)
		m_PrintSettledInvoice.setText(Translatrix.getTranslationString("SettlementDialog.PrintInvoice"));

	if (m_TransferBorder != null)
		m_TransferBorder.setTitle(Translatrix.getTranslationString("SettlementDialog.TransferBorder"));
	
	if (m_CancelButton != null)
		m_CancelButton.setText(Translatrix.getTranslationString("core.cancel"));
	}
//---------------------------------------------------------------------------

public void actionPerformed(ActionEvent p_ActionEvent) 
	{
	JButton		l_PressedButton;
	Settlement	l_Settlement;
	
	if (p_ActionEvent.getSource() instanceof JButton)
		{
		if (p_ActionEvent.getSource() == m_CancelButton)
			{
			this.setVisible (false);
			m_InvoiceSettled = false;
			}
		else
			{
			l_PressedButton = (JButton) p_ActionEvent.getSource();
			l_Settlement = m_SettlementLookup.get (l_PressedButton);
			this.settleInvoice(l_Settlement);
			this.setVisible (false);
			}
		}
	}

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

	public void propertyChange (PropertyChangeEvent p_Event)
	{
		
		if (p_Event.getSource() == m_Payment) {
			valueChanged(true);
			
		} else if (p_Event.getSource() == m_Deduction){
			setAmount2Pay(true);
			valueChanged(false);
			
		} else if ((p_Event.getSource() == m_Date) && ("date".equals(p_Event.getPropertyName()))) {
			this.checkSettlementDate();
		}
		
	}


	private void valueChanged (boolean paymentChanged)
	{
		double l_Return;
		double l_Payment;
		
		l_Return = this.calculateReturn();
		if (l_Return >= 0)
		{
			m_Return.setText(formatCurrency(l_Return));
			m_Return.setForeground(m_DefaultForeground);
			m_Return.setBackground(m_DefaultBackground);
			m_ReturnLabel.setText(Translatrix.getTranslationString("SettlementDialog.ReturnLabel"));
		}
		else
		{
			m_Return.setText(formatCurrency(l_Return));
			m_Return.setForeground(GECAMedColors.c_InvalidFieldForeground);
			m_Return.setBackground(GECAMedColors.c_InvalidFieldBackground);
			m_ReturnLabel.setText(Translatrix.getTranslationString("SettlementDialog.DueLabel"));
		}
		
		if (paymentChanged)
		{
			l_Payment = this.getPayment();
			if (l_Payment >= 0)
			{
				m_Payment.setForeground(m_DefaultForeground);
				m_Payment.setBackground(m_DefaultBackground);
				this.enableSettlementButtons(true);
			}
			else
			{
				m_Payment.setForeground(GECAMedColors.c_InvalidFieldForeground);
				m_Payment.setBackground(GECAMedColors.c_InvalidFieldBackground);
//				this.enableSettlementButtons(false);
			}
		}
	}


	private double parseCurrency (String currencyValue) throws ParseException 
	{
		double result = m_CurrencyFormat.parse(currencyValue).doubleValue();
		
//		if (currencyValue.trim().startsWith("-"))
//			result *= -1;
		
		return result;
	}
	
	
	private String formatCurrency (double currencyValue)
	{
		String result = m_CurrencyFormat.format(currencyValue);
		
//		if (currencyValue < 0)
//			result = new StringBuffer(result.length() + 1)
//					.append("-").append(result).toString();
		
		return result;
	}

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

}
