/********************************************************************
 * Copyright © 2004 EDS. All rights reserved
 ********************************************************************/
//Package
package gov.va.med.esr.messaging.builder.message;

//Framework Classes
import gov.va.med.fw.hl7.segment.ZIC;
import gov.va.med.fw.util.builder.BuilderException;

//ESR Classes
import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.lookup.AssetType;
import gov.va.med.esr.common.model.lookup.ExpenseType;
import gov.va.med.esr.common.model.lookup.IncomeType;
import gov.va.med.esr.common.model.person.*;

/**
 * Class to build the ZIC segment.
 * 
 * @author Alex Yoon
 * @author Rajiv Patnaik
 * @version 1.0
 */
public class ZICBuilder extends AbstractZICBuilder {
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = 3437493018688605276L;
   public ZICBuilder() {
        super();
    }

    /**
     * Method to build the ZIC segment.
     * 
     * @param metaData
     *           The parameter object used to build the a ZIC segment.
     * @return The ZIC segment.
     */
    public Object build(ZICMetaData metaData ) throws BuilderException {
        if((metaData == null) || 
           (metaData.getEntity() == null) ||
           !(metaData.getEntity() instanceof Person) ||
           	metaData.getIncomeYear() == null) {
                throw new BuilderException("Invalid input parameter to build a segment");
        }
        
        ZIC segment = new ZIC();
        
        Person person = (Person)metaData.getEntity();
        Integer incomeYear = metaData.getIncomeYear();
        
        FinancialStatement financialStatement = person.getFinancialStatement(incomeYear);
        
        segment.setSetID("1");

        //Seq 2
        super.setIncomeYear(segment, incomeYear); 
        
        if (financialStatement != null)
        {
	        //Seq 1,2,3, 9, 12-16, 18-19 when ZMT-30 = 1
	        //Seq 1-20 when ZMT-30 = 0        
	        Boolean isPost2005Format = financialStatement.getIsPost2005Format();
	        
	        segment = buildCommonAttributes(segment, incomeYear, financialStatement,isPost2005Format);
	        
	        //If ZMT-30 = 0
	        if(isPost2005Format != null && !isPost2005Format.booleanValue()) 
	        {
	            segment = buildPre2005FormatAttributes(segment, financialStatement);
	        }
        }
        return segment;
        
    } 
    
    private ZIC buildPre2005FormatAttributes(ZIC segment, FinancialStatement financialStatement) throws BuilderException
    {
        //Seq 4
        segment.setCivilService(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_CIVIL_SERVICE.getName()));
        //Seq 5        
        segment.setRailroadRetirement(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_RAILROAD_RETIREMENT.getName()));
        //Seq 6
        segment.setMilitaryRetirement(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_MILITARY_RETIREMENT.getName()));
        //Seq 7
        segment.setUnemploymentCompensation(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_UNEMPLOYMENT_COMPENSATION.getName()));
        //Seq 8
        segment.setOtherRetirement(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_OTHER_RETIREMENT.getName()));
        //Seq 10
        segment.setInterestDividendAnnuity(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_INTEREST_DIVIDEND_ANNUITY.getName()));
        //Seq 11
        segment.setWorkersCompBlackLung(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_WORKERS_COMP_BLACK_LUNG.getName()));
        //Seq 17
        segment.setStocksAndBonds(
                getAssetAmountAsString(financialStatement, AssetType.CODE_STOCKS_AND_BONDS.getName()));
        
        segment.setDebts(financialStatement.getDebt() == null ? null : super
                .build(financialStatement.getDebt().getAmount()));
        
        return segment;
    }
    /**
     * @param segment
     * @param incomeYear
     * @param financialStatement
     * @throws BuilderException
     */
    private ZIC buildCommonAttributes(ZIC segment, Integer incomeYear, FinancialStatement financialStatement, Boolean isPost2005Format) throws BuilderException
    {
        
        //pre 2005 format
        if (isPost2005Format == null || !isPost2005Format.booleanValue())
        {
            //Seq 3
            segment.setSocialSecurity(
                    getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_SOCIAL_SECURITY.getName()));
            //Seq 12
            segment.setOtherIncome(
                    getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME.getName()));     
        }
        else {
            //Seq 3
            segment.setSocialSecurity(
                    getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME.getName()));
            //Seq 12
            segment.setOtherIncome(
                    getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_FARM_RANCH_PROPERTY_OR_BUSINESS_INCOME.getName()));             	
       }
        
        //Seq 9
        segment.setEmploymentIncome(
                getIncomeAsString(financialStatement, IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT.getName()));
        //Seq 13
        segment.setMedicalExpenses(
                getExpensesAsString(financialStatement, ExpenseType.EXPENSE_TYPE_ADJUSTED_MEDICAL.getName()));
        //Seq 14
        segment.setFuneralExpenses(
                getExpensesAsString(financialStatement, ExpenseType.EXPENSE_TYPE_FUNERAL_AND_BURIAL.getName()));
        //Seq 15
        segment.setEducationalExpenses(
                getExpensesAsString(financialStatement, ExpenseType.EXPENSE_TYPE_COLLEGE_AND_VOCATION.getName()));

        //VFA: seq 16, 18, 19: Populated only if Income Year is earlier than 2009
        this.discontinueNetWorth(incomeYear, segment, financialStatement);
        
        return segment;
    }


}