/*******************************************************************************
 * 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
 *******************************************************************************/
/*
 * InvoiceListModel.java
 *
 * Created on March 31, 2006
 */

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

/**
 *
 * @author  santec
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Vector;

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.utils.InvoiceWorkflow;
import lu.tudor.santec.gecamed.core.gui.utils.filtertablemodel.FilterTableModel;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.i18n.Translatrix;

//***************************************************************************
//* Class Members                                                           *
//***************************************************************************

public class InvoiceListModel extends FilterTableModel
    {
 	private static final long serialVersionUID = 1L;
	
    private List<Invoice>	m_Invoices;        
    private boolean			m_Editable;
    
    public static final Date c_Epoch = new Date (0);
    
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************

    public static final String c_StatusHeader 				= "InvoiceListModel.StatusHeader";
    public static final String c_HospitalisationClassHeader	= "InvoiceListModel.HospitalisationClassHeader";
    public static final String c_InvoiceNumberHeader 		= "InvoiceListModel.InvoiceNumberHeader";
    public static final String c_InvoiceDateHeader 			= "InvoiceListModel.InvoiceDateHeader";
    public static final String c_DueDateHeader 				= "InvoiceListModel.DueDateHeader";
    public static final String c_PhysicianHeader 			= "InvoiceListModel.PhysicianHeader";
    public static final String c_AmountHeader 				= "InvoiceListModel.AmountHeader";
    public static final String c_PaymentHeader 				= "InvoiceListModel.PaymentHeader";
    public static final String c_DeductionHeader 			= "InvoiceListModel.DeductionHeader";
    public static final String c_BalanceHeader 				= "InvoiceListModel.BalanceHeader";
    public static final String c_SettlementDateHeader 		= "InvoiceListModel.SettlementDateHeader";
    public static final String c_SettlementHeader 			= "InvoiceListModel.SettlementHeader";
    public static final String c_ReminderHeader 			= "InvoiceListModel.ReminderHeader";
    public static final String c_ReminderDateHeader 		= "InvoiceListModel.ReminderDateHeader";
    public static final String c_HealthInsuranceHeader 		= "InvoiceListModel.HealthInsuranceHeader";
    public static final String c_ThirdPartyHeader 			= "InvoiceListModel.ThirdPartyHeader";
    public static final String c_AccidentNumberHeader 		= "InvoiceListModel.AccidentNumberHeader";
    public static final String c_AccidentDateHeader 		= "InvoiceListModel.AccidentDateHeader";
    public static final String c_StatementHeader 			= "InvoiceListModel.StatementHeader";
    
    public static final int		c_StatusColumn					= 0;
    public static final int		c_HospitalisationClassColumn	= 1;
    public static final int		c_InvoiceNumberColumn			= 2;
    public static final int		c_InvoiceDateColumn				= 3;
    public static final int		c_DueDateColumn					= 4;
    public static final int		c_PhysicianColumn				= 5;
    public static final int		c_AmountColumn					= 6;
    public static final int		c_PaymentColumn					= 7;
    public static final int		c_DeductionColumn				= 8;
    public static final int		c_BalanceColumn					= 9;
    public static final int		c_StatementColumn				= 10;
    public static final int		c_SettlementDateColumn			= 11;
    public static final int		c_SettlementColumn				= 12;
    public static final int		c_ReminderColumn				= 13;
    public static final int		c_ReminderDateColumn			= 14;
    public static final int		c_HealthInsuranceColumn			= 15;
    public static final int		c_ThirdPartyColumn				= 16;
    public static final int		c_AccidentNumberColumn			= 17;
    public static final int		c_AccidentDateColumn			= 18;

    static final public String c_TableHeaders [] = { 	c_StatusHeader,
    													c_HospitalisationClassHeader,
    													c_InvoiceNumberHeader,
    													c_InvoiceDateHeader,
    													c_DueDateHeader,
    													c_PhysicianHeader,
    													c_AmountHeader,
    													c_PaymentHeader,
    													c_DeductionHeader,
    													c_BalanceHeader,
    													c_StatementHeader,
    													c_SettlementDateHeader,
    													c_SettlementHeader,
    													c_ReminderHeader,
    													c_ReminderDateHeader,
    													c_HealthInsuranceHeader,
    													c_ThirdPartyHeader,
    													c_AccidentNumberHeader,
    													c_AccidentDateHeader };
 
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************

public InvoiceListModel ()
    {
    m_Invoices       = new ArrayList<Invoice>();
    }

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

private String getSettlement (Settlement p_Settlement)
	{
	Payment	l_Payment;
	Account	l_Account;
	String	l_Settlement	= "";
	
	if (p_Settlement == null) return "";
	
	if (p_Settlement.getPayment() != null)
		{
		l_Payment = p_Settlement.getPayment();
		l_Settlement = l_Payment.getMethod();
		}
	else
		{
		l_Account = p_Settlement.getTransferAccount();
		if (l_Account.getLabel() != null && l_Account.getLabel().trim().length() > 0)
			l_Settlement = l_Account.getLabel();
		else
			l_Settlement = l_Account.getIban();
		}
	
	return l_Settlement;
	}

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

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

public String getColumnName (int p_Column)
    {
    if ((p_Column >=0) && (p_Column < c_TableHeaders.length))
    	 return (Translatrix.getTranslationString(c_TableHeaders[p_Column]));
    else return ("");
    }

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

public int getColumnCount ()
    {
    return (c_TableHeaders.length);
    }

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

public int getRowCount ()
    {
    return (this.getFilteredRowCount());
    }

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

public Object getValueAt (int p_Row, int p_Column)
    {
    Invoice  l_Invoice;
    int l_Row = p_Row;
    l_Invoice = new Invoice ();

    if (this.isFiltering()) l_Row = this.filteredToModel(l_Row);
    
    if ((l_Row >= 0) && (l_Row < m_Invoices.size())) {
    	l_Invoice = m_Invoices.get(l_Row);
    	if (l_Invoice == null) {
    		l_Invoice = new Invoice ();
    	}
    }

    switch (p_Column)
        {
        case  0: return (l_Invoice.getState() != null) ? l_Invoice.getState() : Integer.valueOf (InvoiceWorkflow.c_NewState);
        case  1: return (l_Invoice.getHospitalisationClass() != null) ? l_Invoice.getHospitalisationClass().getAcronym() : "";
        case  2: return l_Invoice.formatInvoiceNumber(true, true); 
        case  3: return (l_Invoice.getInvoiceDate() != null) ? l_Invoice.getInvoiceDate() : c_Epoch;
        case  4: return (l_Invoice.getDueDate() != null) ? l_Invoice.getDueDate() : c_Epoch;
        case  5: return (l_Invoice.getPhysician() != null) ? (l_Invoice.getPhysician()) : new Physician ();
        case  6: return (l_Invoice.getAmount() != null) ? l_Invoice.getAmount() : 0;
        case  7: return (l_Invoice.getPayment() != null) ? l_Invoice.getPayment() : 0;
        case  8: return (l_Invoice.getDeduction() != null) ? l_Invoice.getDeduction() : 0;
        case  9: return (l_Invoice.getBalance() != null) ? l_Invoice.getBalance() : 0;
        case 10: return (l_Invoice.getStatement() != null) ? l_Invoice.getStatement().formatStatementNumber() : ""; 
        case 11: return (l_Invoice.getSettlementDate() != null) ? l_Invoice.getSettlementDate() : c_Epoch;
        case 12: return (l_Invoice.getSettlement() != null) ? this.getSettlement(l_Invoice.getSettlement()) : "";
        case 13: return (l_Invoice.getNumberOfReminders() != null) ? l_Invoice.getNumberOfReminders() : 0;
        case 14: return (l_Invoice.getReminderDate() != null) ? l_Invoice.getReminderDate() : c_Epoch;
        case 15: return (l_Invoice.getHealthInsurance() != null) ? l_Invoice.getHealthInsurance().getAcronym() : "";
        case 16: return (l_Invoice.getThirdPartyPayer() != null) ? l_Invoice.getThirdPartyPayer().getAcronym() : "";
        case 17: return (l_Invoice.getAccidentNumber() != null) ? l_Invoice.getAccidentNumber() : "";
        case 18: return (l_Invoice.getAccidentDate() != null) ? l_Invoice.getAccidentDate() : c_Epoch;
        
        default: return "";
        }
    }
        
//---------------------------------------------------------------------------

public void setValueAt (Object p_Value, int p_Row, int p_Column)
	{
	Invoice  l_Invoice;
	
	if (!m_Editable) return;
	
	l_Invoice = new Invoice ();
	    
	if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
	    
	if ((p_Row >= 0) && (p_Row < m_Invoices.size()))
		{
	    l_Invoice = m_Invoices.get(p_Row);
	    if (l_Invoice == null) l_Invoice = new Invoice ();
	    }
		 
	switch (p_Column)
		{
	    case  c_StatusColumn: 
	        	
	    	l_Invoice.setOldState(l_Invoice.getState());
	    	l_Invoice.setState((Integer)p_Value);
	        this.fireTableCellUpdated(p_Row, p_Column);
	        break;
	    }	
	}

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

public Class<?> getColumnClass (int p_Column) 
    {
    if (getValueAt(0, p_Column) != null)
    		 return (Class<?>) getValueAt(0, p_Column).getClass();
    else return null;
    }

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

public void setEditable (boolean p_Editable)
	{
	m_Editable = p_Editable;
	}

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

public boolean isEditable ()
	{
	return m_Editable;
	}

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

public boolean isCellEditable   (int p_Row, int p_Column)
    {
    if (m_Editable)
    	{
    	if (p_Column == c_StatusColumn) return true;
    	}
	
	return false;
    }

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

public Invoice	getInvoiceAt (int p_Row)
    {
    Invoice  l_Invoice;
     
    if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
    
    if ((p_Row >= 0) && (p_Row < m_Invoices.size()))
        {
	l_Invoice = m_Invoices.get(p_Row);
        return l_Invoice;
        }
    else return null;
    }
	
//---------------------------------------------------------------------------

public void	setInvoiceAt (Invoice p_Invoice, int p_Row)
    {     
	if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
	
	if ((p_Invoice != null) && (p_Row >= 0) && (p_Row < m_Invoices.size()))
        {
    	m_Invoices.set(p_Row, p_Invoice);
        this.update();
        }
    }
	
//---------------------------------------------------------------------------

public void addInvoice (Invoice p_Invoice)
    {
	int	l_LastRowBefore;
	int	l_LastRowAfter;
	
	if (p_Invoice != null)    
        {    
		l_LastRowBefore = this.getRowCount() -1;
		m_Invoices.add(p_Invoice);
		l_LastRowAfter = this.getRowCount() -1;
        if (l_LastRowAfter > l_LastRowBefore) fireTableRowsInserted (l_LastRowAfter,l_LastRowAfter);
        }
    }
	
//---------------------------------------------------------------------------

public void removeAllInvoices ()
	{
	int	l_LastRow;
	
	l_LastRow = this.getRowCount() -1;

	m_Invoices.clear();
 	
	if (l_LastRow > 0) fireTableRowsDeleted (0,l_LastRow);
	}

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

public void removeInvoiceAt (int p_Row)
    {
	int	l_ModelRow;
	
	if (this.isFiltering()) l_ModelRow = this.filteredToModel(p_Row);
					   else l_ModelRow = p_Row;
	
	if ((l_ModelRow >= 0) && (l_ModelRow < m_Invoices.size()))
        {
    	m_Invoices.remove(l_ModelRow);    
    	fireTableRowsDeleted (p_Row,p_Row);
        }
    }

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

public boolean containsInvoice (Invoice p_Invoice)
	{
	return m_Invoices.contains(p_Invoice);
	}

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

public int findInvoice (String p_InvoiceNumber)
    {
    int 	l_Row;
    int		l_RowCount;
    boolean	l_Found;
 	Invoice	l_Invoice;
    
 	l_Found    = false;
  	l_Row      = 0;
  	l_RowCount = this.getRowCount();
  	
  	while ((l_Row < l_RowCount) && !l_Found)
  		{
  		if (this.isFiltering()) l_Row = this.filteredToModel(l_Row);
  		l_Invoice = m_Invoices.get(l_Row);
  		if (l_Invoice.formatInvoiceNumber(Invoice.c_LongFormat, true).equals(p_InvoiceNumber)) 
  			 l_Found = true;
  		else l_Row++;
  		}
     
     if (l_Found) return l_Row;
    	    else return (-1);
     }

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

public void setInvoices (Collection <Invoice> p_Invoices)
    {
    if (p_Invoices == null) return;
        
    removeAllInvoices ();
 
    m_Invoices.addAll(0,p_Invoices);
    this.setTableData(m_Invoices);
    fireTableRowsInserted (0,this.getRowCount());
    }

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

public Collection <Invoice> getInvoices ()
    {
	Vector <Invoice> l_Invoices;
	
	l_Invoices = new Vector <Invoice> (m_Invoices);
	
	return l_Invoices;
    }    
        
//***************************************************************************
//* End of Class															*
//***************************************************************************
}
