/*******************************************************************************
 * 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.statement;

/**
 *
 * @author  santec
 */

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;

import org.apache.commons.httpclient.methods.GetMethod;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Invoice;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.InvoiceStub;
import lu.tudor.santec.gecamed.billing.gui.invoice.stub.GenericInvoiceStubListInterface;
import lu.tudor.santec.gecamed.billing.utils.InvoiceWorkflow;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.filtertablemodel.FilterTableModel;
import lu.tudor.santec.gecamed.core.utils.SSNChecker;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Insurance;
import lu.tudor.santec.i18n.Translatrix;

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

public class InvoiceStubListModel extends FilterTableModel implements GenericInvoiceStubListInterface
    {
 	private static final long serialVersionUID = 1L;
	
    private Vector      	<InvoiceStub> m_InvoiceStubs;        
    private boolean			m_Editable;
     
    public static final Date c_Epoch = new Date (0);
    
	private HashMap<Integer, Insurance> insurances = new HashMap<Integer, Insurance>();
	
    
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************

    public static final String c_SettlementHeader 			= "InvoiceListModel.SettlementHeader";
    public static final String c_StatusHeader 				= "InvoiceListModel.StatusHeader";
    public static final String c_ClassHeader 				= "InvoiceListModel.ClassHeader";
    public static final String c_PatientNameHeader			= "InvoiceListModel.PatientNameHeader";
    public static final String c_PatientSSNHeader			= "InvoiceListModel.PatientSSNHeader";
    public static final String c_InvoiceNumberHeader 		= "InvoiceListModel.InvoiceNumberHeader";
    public static final String c_InvoiceDateHeader 			= "InvoiceListModel.InvoiceDateHeader";
    public static final String c_InsuranceHeader 			= "StatementListModel.ThirdPartyPayerHeader";
    public static final String c_PhysicianNameHeader		= "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 int		c_SettlementColumn			= 0;
    public static final int		c_StateColumn				= 1;
    public static final int		c_ClassColumn				= 2;
    public static final int		c_PatientNameColumn			= 3;
    public static final int		c_PatientSSNColumn			= 4;
    public static final int		c_InvoiceNumberColumn		= 5;
    public static final int		c_InvoiceDateColumn			= 6;
    public static final int		c_InsuranceColumn			= 7;
    public static final int		c_PhysicianNameColumn		= 8;
    public static final int		c_AmountColumn				= 9;
    public static final int		c_PaymentColumn				= 10;
    public static final int		c_DeductionColumn			= 11;
    public static final int		c_BalanceColumn				= 12;
 
    static final public String c_TableHeaders [] = { 	c_SettlementHeader,
												    	c_StatusHeader,
														c_ClassHeader,
    													c_PatientNameHeader,
    													c_PatientSSNHeader,
    													c_InvoiceNumberHeader,
    													c_InvoiceDateHeader,
    													c_InsuranceHeader,
    												    c_PhysicianNameHeader,
    													c_AmountHeader,
    													c_PaymentHeader,
    													c_DeductionHeader,
    													c_BalanceHeader };
 
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************

public InvoiceStubListModel ()
    {
    m_InvoiceStubs  = new Vector <InvoiceStub> ();
    }

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

private String getPatientName (InvoiceStub p_InvoiceStup)
	{
	String  l_Name		= "-";

	if (p_InvoiceStup != null)
		{
		l_Name = (p_InvoiceStup.getPatientName() != null) ? p_InvoiceStup.getPatientName().toUpperCase() : "";
		l_Name += " ";
		l_Name += (p_InvoiceStup.getPatientFirstName() != null) ? p_InvoiceStup.getPatientFirstName() : "";
		}

	return l_Name;
	}

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

private String getPatientSSN (InvoiceStub p_InvoiceStup)
	{
	String  l_SSN		= "-";

	if (p_InvoiceStup != null && p_InvoiceStup.getPatientSSN() != null)
		{
		l_SSN = SSNChecker.getFormattedSSN(p_InvoiceStup.getPatientSSN(), false);
		}

	return l_SSN;
	}


private String getInsuranceName(InvoiceStub p_InvoiceStup) {
	try {
		return insurances.get(p_InvoiceStup.getThirdPartyPayerId()).getAcronym();					
	} catch (Exception e) {
		return "";
	}
}

public void setInsurances(Collection<Insurance> l_Insurances) {
	insurances.clear();
	for (Insurance ins : l_Insurances) {
		insurances.put(ins.getId(), ins);
	}
}

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

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

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

public boolean isEditable ()
	{
	return m_Editable;
	}

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

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)
    {
    InvoiceStub  l_Stub;
    
    l_Stub = new InvoiceStub ();
    
    if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
    
    if ((p_Row >= 0) && (p_Row < m_InvoiceStubs.size()))
        {
    	l_Stub = m_InvoiceStubs.elementAt (p_Row);
    	if (l_Stub == null) l_Stub = new InvoiceStub ();
        }
	 
    switch (p_Column)
        {
        case  c_SettlementColumn: 	return (InvoiceWorkflow.c_PaidState == l_Stub.getState());
        case  c_StateColumn: 		return (l_Stub.getState() != null) ? l_Stub.getState() : Integer.valueOf (InvoiceWorkflow.c_NewState);
        case  c_ClassColumn: 		return (l_Stub.getHospitalisationClassId() != null) ? lu.tudor.santec.gecamed.billing.gui.reminder.InvoiceStubListModel.getHospitalisationClass(l_Stub.getHospitalisationClassId()) : "";
        case  c_PatientNameColumn: 	return this.getPatientName (l_Stub);
        case  c_PatientSSNColumn: 	return this.getPatientSSN (l_Stub);
        case  c_InvoiceNumberColumn:return l_Stub.formatInvoiceNumber(Invoice.c_ShortFormat, true); 
        case  c_InvoiceDateColumn: 	return (l_Stub.getInvoiceDate() != null) ? l_Stub.getInvoiceDate() : c_Epoch;
        case  c_InsuranceColumn: 	return this.getInsuranceName(l_Stub);
        case  c_PhysicianNameColumn:return this.getPhysicianMnemonic(l_Stub);
        case  c_AmountColumn: 		return (l_Stub.getAmount() != null) ? l_Stub.getAmount() : 0;
        case  c_PaymentColumn: 		return (l_Stub.getPayment() != null) ? l_Stub.getPayment() : 0;
        case  c_DeductionColumn: 	return (l_Stub.getDeduction() != null) ? l_Stub.getDeduction() : 0;
        case  c_BalanceColumn: 		return (l_Stub.getBalance() != null) ? l_Stub.getBalance() : 0;
         
        default: return "";
        }
    }
        

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


private String getPhysicianMnemonic (InvoiceStub p_InvoiceStub)
{
Physician		l_Physician	= MainFrame.getPhysicianById(p_InvoiceStub.getPhysicianId());

if (l_Physician == null)
	return "";

return l_Physician.getMnemonic();
}

public void setValueAt (Object p_Value,int p_Row, int p_Column)
	{
	Invoice		l_Invoice;
	InvoiceStub	l_Stub;
	boolean		l_Settled;
	int			l_Action;
	
	if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
	
	switch (p_Column)
		{
		case c_SettlementColumn : 
			
			if (p_Value instanceof Boolean)
				{
				l_Settled = (Boolean) p_Value;
				if ((p_Row >= 0) && (p_Row < m_InvoiceStubs.size()))
					{
					l_Stub = m_InvoiceStubs.elementAt(p_Row);
					l_Invoice = new Invoice ();
					
					l_Invoice.setState (l_Stub.getState());
					l_Invoice.setOldState (l_Stub.getOldState());
					
					if (l_Settled == true)
						 l_Action = InvoiceWorkflow.changeInvoiceState (l_Invoice, InvoiceWorkflow.c_PayAction);
				    else l_Action = InvoiceWorkflow.changeInvoiceState (l_Invoice, InvoiceWorkflow.c_RevokeAction);
			
				    l_Stub.setState (l_Invoice.getState());
				    l_Stub.setOldState (l_Invoice.getOldState());
				    
					switch (l_Action)
				   		{
				   		case InvoiceWorkflow.c_DoPay:
				   			
				   			m_InvoiceStubs.setElementAt(l_Stub, p_Row);
							fireTableCellUpdated (p_Row,p_Column);	
				   			break;
							
				   		case InvoiceWorkflow.c_DoRevoke:
				   			
				   			m_InvoiceStubs.setElementAt(l_Stub, p_Row);
							fireTableCellUpdated (p_Row,p_Column);	
							break;
				   		}
					}
				}
			break;
		}
	}

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

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

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

public boolean isCellEditable   (int p_Row, int p_Column)
    {
	if (m_Editable == false) return false;
	
	switch (p_Column)
    	{
    	case c_SettlementColumn : return true;

    	default					: return false;
    	}
     }

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

public InvoiceStub	getInvoiceStubAt (int p_Row)
    {
    InvoiceStub  l_Stub;
     
    if (this.isFiltering()) p_Row = this.filteredToModel(p_Row); 
    
    if ((p_Row >= 0) && (p_Row < m_InvoiceStubs.size()))
        {
    	l_Stub = m_InvoiceStubs.elementAt (p_Row);
        return l_Stub;
        }
    else return null;
    }
	
//---------------------------------------------------------------------------

public void	setInvoiceStubAt (InvoiceStub p_Stub, int p_Row)
    {     
    if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
	
	if ((p_Stub != null) && (p_Row >= 0) && (p_Row < m_InvoiceStubs.size()))
        {
    		m_InvoiceStubs.setElementAt(p_Stub,p_Row);
         }
    this.fireTableRowsUpdated(p_Row, p_Row);
    }
	
//---------------------------------------------------------------------------

public void addInvoiceStub (InvoiceStub p_Stub)
    {
	int	l_Row;
	
	if (p_Stub != null)    
        {    
        m_InvoiceStubs.addElement (p_Stub);
         
        l_Row = m_InvoiceStubs.size() - 1;
        fireTableRowsInserted (l_Row,l_Row);
        }
    }
	
//---------------------------------------------------------------------------

public void removeAllInvoiceStubs ()
	{
	int	l_LastRow;
	
	l_LastRow = m_InvoiceStubs.size() -1;

	m_InvoiceStubs.removeAllElements ();
	
	if (l_LastRow >= 0) fireTableRowsDeleted (0,l_LastRow);
	}

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

public void removeInvoiceStubAt (int p_Row)
    {
    if (this.isFiltering()) p_Row = this.filteredToModel(p_Row);
	
	if ((p_Row >= 0) && (p_Row < m_InvoiceStubs.size()))
        {
    	m_InvoiceStubs.removeElementAt(p_Row); 
    	fireTableRowsDeleted (p_Row,p_Row);
        }
    }

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

public int findInvoiceStub (Integer p_InvoiceId)
{
//int 		l_Row;
//boolean		l_Found;
//	InvoiceStub	l_InvoiceStub;
//
//	l_Found = false;
//	
//	if (p_InvoiceNumber == null) return -1;
//	
//	for (l_Row = 0; (l_Row < m_InvoiceStubs.size()) && (!l_Found); l_Row++)
//		{
//		l_InvoiceStub = m_InvoiceStubs.elementAt(l_Row);
//		if (p_InvoiceNumber.equals(l_InvoiceStub.formatInvoiceNumber(Invoice.c_LongFormat))) l_Found = true;
//		}
//
//if (l_Found) return l_Row;
//		   else return (-1);
return -1; 
}
//---------------------------------------------------------------------------

public boolean containsInvoiceStub (InvoiceStub p_Stub)
	{
	return m_InvoiceStubs.contains (p_Stub);
	}
	
//---------------------------------------------------------------------------

public void setInvoiceStubs (Collection <InvoiceStub> p_Stubs)
    {
 	if (p_Stubs == null) return;
        
    removeAllInvoiceStubs ();
 
    m_InvoiceStubs.addAll (0,p_Stubs);
    this.setTableData(m_InvoiceStubs); 
    
    fireTableRowsInserted (0,p_Stubs.size());
    }

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

public void addInvoiceStubs (Collection <InvoiceStub> p_Stubs)
	{
	if (p_Stubs == null) return;
  
    m_InvoiceStubs.addAll (0,p_Stubs);
    this.setTableData(m_InvoiceStubs);
    
    fireTableRowsInserted (0,p_Stubs.size());	
	}

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

public Collection <InvoiceStub> getInvoiceStubs ()
    {
	Vector <InvoiceStub> l_Stubs;
	
	l_Stubs = new Vector <InvoiceStub> (m_InvoiceStubs);
	
	return l_Stubs;
    }

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

public void removeInvoiceStub (InvoiceStub p_InvoiceStub)
	{
	int	l_Index;
	
	if (p_InvoiceStub != null)
		{
		l_Index = m_InvoiceStubs.indexOf(p_InvoiceStub);
		if (l_Index >= 0) this.removeInvoiceStubAt(l_Index);		
		}
	}

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