package gov.va.med.esr.service.external;

import gov.va.med.esr.common.model.ee.AgentOrangeExposure;
import gov.va.med.esr.common.model.ee.CDCondition;
import gov.va.med.esr.common.model.ee.CDDiagnosis;
import gov.va.med.esr.common.model.ee.CDProcedure;
import gov.va.med.esr.common.model.ee.CampLejeuneVerification;
import gov.va.med.esr.common.model.ee.CancelDecline;
import gov.va.med.esr.common.model.ee.CatastrophicDisability;
import gov.va.med.esr.common.model.ee.ClinicalDetermination;
import gov.va.med.esr.common.model.ee.Eligibility;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.ee.EnvironmentalContaminationExposure;
import gov.va.med.esr.common.model.ee.IneligibilityFactor;
import gov.va.med.esr.common.model.ee.MECPeriod;
import gov.va.med.esr.common.model.ee.MilitarySexualTrauma;
import gov.va.med.esr.common.model.ee.MonetaryBenefit;
import gov.va.med.esr.common.model.ee.MonetaryBenefitAward;
import gov.va.med.esr.common.model.ee.NoseThroatRadium;
import gov.va.med.esr.common.model.ee.RadiationExposure;
import gov.va.med.esr.common.model.ee.SpecialFactor;
import gov.va.med.esr.common.model.lookup.Diagnosis;
import gov.va.med.esr.common.model.lookup.EnrollmentCategory;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.Indicator;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.service.EligibilityEnrollmentService;
import gov.va.med.esr.service.external.person.CDConditionInfo;
import gov.va.med.esr.service.external.person.CDProcedureInfo;
import gov.va.med.esr.service.external.person.CancelDeclineInfo;
import gov.va.med.esr.service.external.person.CatastrophicDisabilityInfo;
import gov.va.med.esr.service.external.person.EESummary;
import gov.va.med.esr.service.external.person.EligibilityInfo;
import gov.va.med.esr.service.external.person.EligibilityStatusInfo;
import gov.va.med.esr.service.external.person.EnrollmentDeterminationInfo;
import gov.va.med.esr.service.external.person.IneligibilityFactorInfo;
import gov.va.med.esr.service.external.person.MilitaryServiceInfo;
import gov.va.med.esr.service.external.person.MilitarySexualTraumaInfo;
import gov.va.med.esr.service.external.person.MonetaryBenefitAwardInfo;
import gov.va.med.esr.service.external.person.MonetaryBenefitInfo;
import gov.va.med.esr.service.external.person.NoseThroatRadiumInfo;
import gov.va.med.esr.service.external.person.ServiceConnectionAwardInfo;
import gov.va.med.esr.service.external.person.SpecialFactorsInfo;
import gov.va.med.esr.service.external.person.collections.CDConditionCollection;
import gov.va.med.esr.service.external.person.collections.CDDiagnosisCollection;
import gov.va.med.esr.service.external.person.collections.CDProcedureCollection;
import gov.va.med.esr.service.external.person.collections.EligibilityCollection;
import gov.va.med.esr.service.external.person.collections.MonetaryBenefitCollection;
import gov.va.med.esr.service.impl.ChangeEvent;
import gov.va.med.esr.service.impl.HistoricalInfo;
import gov.va.med.fw.service.ServiceException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Comparator;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.xmlsoap.schemas.soap.encoding.DateTime;

public class EnrollmentDeterminationFactoryimpl implements EnrollmentDeterminationFactory, BeanFactoryAware {

	private ServiceConnectionAwardFactory serviceConnectionAwardFactory;
	private String preciseDateTimeFormat = "yyyyMMddHHmmss";
	private BeanFactory beanFactory;
	private static final String ENROLLED ="ENROLLED";
	private static final String NOT_ENROLLED ="NOT_ENROLLED";

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	public ServiceConnectionAwardFactory getServiceConnectionAwardFactory() {
		return serviceConnectionAwardFactory;
	}

	public void setServiceConnectionAwardFactory(
			ServiceConnectionAwardFactory serviceConnectionAwardFactory) {
		this.serviceConnectionAwardFactory = serviceConnectionAwardFactory;
	}



	public  void applyEnrollmentDeterminationInfo(Person person,
			EESummary summary) {
		EnrollmentDetermination ed = person.getEnrollmentDetermination();

		//evaluation done specifically for IVM service

		if (ed == null)
			return;

		EnrollmentDeterminationInfo edInfo = new EnrollmentDeterminationInfo();

		setBaseFields(person, edInfo);



		Set pEligibilitySet = new HashSet();
		if (ed.getPrimaryEligibility() != null) {
			pEligibilitySet.add(ed.getPrimaryEligibility());
		}
		EligibilityInfo[] primaryEligibilities = getEligibilities(pEligibilitySet);
		if (primaryEligibilities != null && primaryEligibilities.length == 1) {
			edInfo.setPrimaryEligibility(primaryEligibilities[0]);
		}

		EligibilityInfo[] secEligibilities = getEligibilities(ed
				.getSecondaryEligibilities());

		if ( secEligibilities != null && secEligibilities.length > 0 )
		{
			edInfo.setSecondaryEligibilities(new EligibilityCollection(secEligibilities));
		}


		EligibilityInfo[] otherEligibilities = getEligibilities(ed
				.getOtherEligibilities());
		if (otherEligibilities != null && otherEligibilities.length > 0  )
		{
			edInfo.setOtherEligibilities(new EligibilityCollection(otherEligibilities));
		}

		ServiceConnectionAwardInfo serviceConnectionAwardInfo=
					serviceConnectionAwardFactory.buildServiceConnectionAward(person);
		edInfo.setServiceConnectionAward(serviceConnectionAwardInfo);

		IneligibilityFactorInfo ineligibilityFactorInfo =buildIneligibilityFactor(person);
		if ( ineligibilityFactorInfo != null ) {
			edInfo.setIneligibilityFactor(ineligibilityFactorInfo);
		}

		CancelDeclineInfo cancelDeclineInfo=  buildCancelDecline(person);
		if ( cancelDeclineInfo != null ) {
			edInfo.setCancelDeclineInfo(cancelDeclineInfo);
		}


		MilitarySexualTraumaInfo militarySexualTraumaInfo = applyMilitarySexualTrauma(person);
		if ( militarySexualTraumaInfo != null ) {
			edInfo.setMilitarySexualTraumaInfo(militarySexualTraumaInfo);
		}

		NoseThroatRadiumInfo noseThroatRadiumInfo = buildNSTData(person);
		if ( noseThroatRadiumInfo != null ) {
			edInfo.setNoseThroatRadiumInfo(noseThroatRadiumInfo);
		}


		SpecialFactorsInfo specialFactorsInfo = applySpecialFactors(person);
		edInfo.setSpecialFactors(specialFactorsInfo);

		edInfo.setMonetaryBenefitAwardInfo(applyMonetaryBenefitAward(person));
		edInfo.setCatastrophicDisabilityInfo(applyCatastrophicDisabilityInf(person));
		summary.setEnrollmentDeterminationInfo(edInfo);

	}

    public  void applyEligibilityStatusInfo(Person person,
            EESummary summary) {
        EnrollmentDetermination ed = person.getEnrollmentDetermination();
        EligibilityStatusInfo info = new EligibilityStatusInfo();
        if (ed == null){
            info.setEligibilityStatus("Not Eligible");
            summary.setEligibilityStatusInfo(info);
            return;
        }
        if (ed.getEnrollmentStatus()== null){
            info.setEligibilityStatus("Eligible");
            summary.setEligibilityStatusInfo(info);
            return;
        }
        if(ed.getEnrollmentStatus() != null){
                if (ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Verified")||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending;No Eligibility Code") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending; Means Test Required") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending; Eligibility Status is Unverified") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending; Other") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Not Eligible; Ineligible Date") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Not Eligible; Ineligible Date; Null") ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Not Applicable") ||
                       // ed.getEnrollmentStatus().getName()== null ||
                        ed.getEnrollmentStatus().getName().trim().equalsIgnoreCase("Pending; Purple Heart Unconfirmed")){
                    info.setEligibilityStatus("Eligible");
                } else {
                    info.setEligibilityStatus("Not Eligible");
                }
                summary.setEligibilityStatusInfo(info);
            }
    }


    public  void applyDisabilityInfo(Person person,
            EESummary summary) {
        EnrollmentDetermination ed = person.getEnrollmentDetermination();

        if (ed == null)
            return;

        EnrollmentDeterminationInfo edInfo = summary.getEnrollmentDeterminationInfo();
            //new EnrollmentDeterminationInfo();
        ServiceConnectionAwardInfo serviceConnectionAwardInfo=
            serviceConnectionAwardFactory.buildServiceConnectionAward(person);
                edInfo.setServiceConnectionAward(serviceConnectionAwardInfo);
        summary.setEnrollmentDeterminationInfo(edInfo);
    /*    if(person.getMilitaryService() != null){
        MilitaryServiceInfo info = new MilitaryServiceInfo();
        info.setDischargeDueToDisability(person.getMilitaryService().getDischargeDueToDisability());
        summary.setMilitaryServiceInfo(info);
        }
       */
    }

    public void applyEligibilityInfo(Person person,EESummary summary){
        EnrollmentDetermination ed = person.getEnrollmentDetermination();

        if (ed == null)
            return;

        EnrollmentDeterminationInfo edInfo = summary.getEnrollmentDeterminationInfo();
           // new EnrollmentDeterminationInfo();

        Set pEligibilitySet = new HashSet();
        if (ed.getPrimaryEligibility() != null) {
            pEligibilitySet.add(ed.getPrimaryEligibility());
        }
        EligibilityInfo[] primaryEligibilities = getEligibilities(pEligibilitySet);
        if (primaryEligibilities != null && primaryEligibilities.length == 1) {
            edInfo.setPrimaryEligibility(primaryEligibilities[0]);
        }

        EligibilityInfo[] secEligibilities = getEligibilities(ed
                .getSecondaryEligibilities());

        if ( secEligibilities != null && secEligibilities.length > 0 )
        {
            edInfo.setSecondaryEligibilities(new EligibilityCollection(secEligibilities));
        }


        EligibilityInfo[] otherEligibilities = getEligibilities(ed
                .getOtherEligibilities());
        if (otherEligibilities != null && otherEligibilities.length > 0  )
        {
            edInfo.setOtherEligibilities(new EligibilityCollection(otherEligibilities));
        }
        IneligibilityFactorInfo ineligibilityFactorInfo =buildIneligibilityFactor(person);
        if ( ineligibilityFactorInfo != null ) {
            edInfo.setIneligibilityFactor(ineligibilityFactorInfo);
        }

        summary.setEnrollmentDeterminationInfo(edInfo);

    }
    public void applyEnrollmentInfo(Person person,EESummary summary){
        EnrollmentDetermination ed = person.getEnrollmentDetermination();

        if (ed == null)
            return;

        EnrollmentDeterminationInfo edInfo = summary.getEnrollmentDeterminationInfo();
           // new EnrollmentDeterminationInfo();

        setBaseFields(person, edInfo);
        summary.setEnrollmentDeterminationInfo(edInfo);

    }

    //WI 324899 MEC Period ACA coverage period by date
    public void applyMecInfo(Person person,EESummary summary, boolean covered, MECPeriod period, Date acaStart, Date acaEnd) throws ServiceException{

        EnrollmentDeterminationInfo edInfo = summary.getEnrollmentDeterminationInfo();

        try {

	        if (covered) {
	        	edInfo.setEnrollmentCategoryName(ENROLLED);

	        } else {
	        	edInfo.setEnrollmentCategoryName(NOT_ENROLLED);
	        }

	        if (covered && period != null) {
        		if (period.getMecEndDate() != null) {
        			if (period.getMecEndDate().after(acaEnd)) {
        				edInfo.setEndDate(acaEnd);
        			} else {
        				edInfo.setEndDate(period.getMecEndDate());
        			}

        		} else {
        			edInfo.setEndDate(acaEnd);
        		}

        		if (period.getMecStartDate() != null) {
        			if (period.getMecStartDate().before(acaStart)) {
        				edInfo.setEnrollmentDate(acaStart);
        			} else {
        				edInfo.setEnrollmentDate(period.getMecStartDate());
        			}

        		} else {
        			edInfo.setEnrollmentDate(acaStart);
        		}
        	}

        } catch (Exception e) {
        	throw new ServiceException ("Unknown Lookup Exception in applyMecInfo", e);
        }

        summary.setEnrollmentDeterminationInfo(edInfo);

    }


	/**
	 * Set the direct primitive fields for EESummary
	 *
	 * @param person
	 * @param summary
	 */
	private  void setBaseFields(Person person, EnrollmentDeterminationInfo enrollmentDeterminationInfo) {
		enrollmentDeterminationInfo.setApplicationDate(
				person.getApplication()!=null ?person.getApplication().getApplicationDate():null);

		enrollmentDeterminationInfo.setUserEnrolleeValidThrough(person
				.getUserEnrolleeValidThrough());

		enrollmentDeterminationInfo
				.setUserEnrolleeSite(person.getUserEnrolleeSite() != null ? person
						.getUserEnrolleeSite().getSiteNumberAndName()
						: null);

		enrollmentDeterminationInfo.setEligibleForMedicaid(
				person.getMedicaidFactor() != null? person.getMedicaidFactor().getEligibleForMedicaid():null);

         // part of 16 fields added for E/E service
        enrollmentDeterminationInfo.setMedicaidLastModifiedDate(
                person.getMedicaidFactor() != null? person.getMedicaidFactor().getModifiedOn():null);
        // This is person created date not the enrollment.
       // enrollmentDeterminationInfo.setRecordCreatedDate(person.getCreatedOn() != null? person.getCreatedOn():null);
       // enrollmentDeterminationInfo.setRecordModifiedDate(person.getModifiedOn() != null? person.getModifiedOn():null);

        // end of 16 fields

        EnrollmentDetermination ed = person.getEnrollmentDetermination();
        if(ed.getEnrollmentStatus() != null)
            enrollmentDeterminationInfo.setEnrollmentCategoryName(ed.getEnrollmentStatus().getEnrollmentCategory().getName());
        // end of 16 fields

		if (ed.getPriorityGroup() != null)
			enrollmentDeterminationInfo.setPriorityGroup(ed.getPriorityGroup().getDescription());

		if (ed.getPrioritySubGroup() != null)
			enrollmentDeterminationInfo.setPrioritySubGroup(ed.getPrioritySubGroup().getDescription());


		//private String calculationSource = null;
		if (ed.getCalculationSource() != null) {
			enrollmentDeterminationInfo.setCalculationSource(ed.getCalculationSource().getDescription());
		}

		if (ed.getEnrollmentStatus() != null) {
			enrollmentDeterminationInfo.setEnrollmentStatus(ed.getEnrollmentStatus().getName());
		}

		enrollmentDeterminationInfo.setEnrollmentDate(ed.getEnrollmentDate());
        enrollmentDeterminationInfo.setEffectiveDate(ed.getEffectiveDate());
		enrollmentDeterminationInfo.setEndDate(ed.getEndDate());
        enrollmentDeterminationInfo.setRecordCreatedDate(ed.getCreatedOn());
        enrollmentDeterminationInfo.setRecordModifiedDate(ed.getModifiedOn());


		if (ed.getFacilityReceived() != null) {
			enrollmentDeterminationInfo.setFacilityReceived(ed.getFacilityReceived()
					.getSiteNumberAndName());
		}

		if(ed.getPriorityGroup() != null ){
			enrollmentDeterminationInfo.setPriorityGroup(ed.getPriorityGroup().getDescription());
		}

		if(ed.getPrioritySubGroup() != null ){
			enrollmentDeterminationInfo.setPrioritySubGroup(ed.getPrioritySubGroup().getDescription());
		}

		enrollmentDeterminationInfo.setEnrollmentStatus(ed.getEnrollmentStatus() != null?ed.getEnrollmentStatus().getDescription():null);
		enrollmentDeterminationInfo.setEffectiveDate(ed.getEffectiveDate());

		enrollmentDeterminationInfo.setVeteran(person.getVeteran());

	}



	private  EligibilityInfo[] getEligibilities(Set eligibilities) {
		if (eligibilities == null && eligibilities.size() <= 0)
			return null;

		Iterator eligIterator = eligibilities.iterator();
		EligibilityInfo[] eInfos = new EligibilityInfo[eligibilities.size()];
		int i = 0;
		while (eligIterator.hasNext()) {
			Eligibility e = (Eligibility) eligIterator.next();
			EligibilityInfo eInfo = new EligibilityInfo();

			if (e.getType() != null)
				eInfo.setType(e.getType().getDescription());

			if (e.getFactor() != null)
				eInfo.setType(e.getFactor().getDescription());


			/**
			if (e.getFactor() != null)
				eInfo.setFactor(e.getFactor().getCode());
			**/

			eInfo.setIndicator(e.getIndicator());

			//Added for date of service
            eInfo.setCreateDate(e.getCreatedOn());
            //modified date does not get exposed in the E&E service instead use eligibilityReportDate
            //eInfo.setModifiedDate(e.getModifiedOn());
            eInfo.setEligibilityReportDate(e.getModifiedOn());
			eInfos[i] = eInfo;
			i++;
		}
		return eInfos;
	}


	private  IneligibilityFactorInfo buildIneligibilityFactor(Person person)
	{
		IneligibilityFactor ieFactor = person.getIneligibilityFactor();
		if ( ieFactor == null) return null;

		IneligibilityFactorInfo iefInfo = new IneligibilityFactorInfo();
		iefInfo.setFacilityReceived(
				ieFactor.getFacilityReceived() != null ?
						ieFactor.getFacilityReceived().getSiteNumberAndName():null);
		iefInfo.setIneligibleDate(ieFactor.getIneligibleDate());
		iefInfo.setReason(ieFactor.getReason());
		iefInfo.setVaroDecision(ieFactor.getVaroDecision());
        //16 fields
          iefInfo.setRecordCreatedDate(ieFactor.getCreatedOn());
		return iefInfo;
	}

	private  CancelDeclineInfo buildCancelDecline(Person person)
	{
		CancelDecline cd = person.getCancelDecline();
		if ( cd == null ) return null;

		CancelDeclineInfo cdInfo = new CancelDeclineInfo();
		cdInfo.setCancelDeclineIndicator(cd.getCancelDeclineIndicator());
		//cdInfo.setEffectiveDate(cd.getEffectiveDate());
		cdInfo.setReason(cd.getReason() != null ?cd.getReason().getDescription():null);
		//cdInfo.setReasonNotProcessed(cd.getReasonNotProcessed() != null ?cd.getReasonNotProcessed().getCode():null);
		cdInfo.setRemarks(cd.getRemarks());
		return cdInfo;
	}


	private  MilitarySexualTraumaInfo applyMilitarySexualTrauma(Person person) {
		MilitarySexualTrauma mst = (MilitarySexualTrauma) getClinicalDetermination(MilitarySexualTrauma.class, person);

		if (mst == null)
			return null;

		MilitarySexualTraumaInfo mstInfo = new MilitarySexualTraumaInfo();
		mstInfo
				.setDeterminationFacility(mst.getDeterminationFacility() != null ? mst
						.getDeterminationFacility().getSiteNumberAndName()
						: null);
		mstInfo.setStatus(mst.getStatus() != null ? mst.getStatus().getDescription()
				: null);
		mstInfo.setStatusChangeDate(mst.getStatusChangeDate());
		return mstInfo;

	}


	private   NoseThroatRadiumInfo buildNSTData(Person person) {
		NoseThroatRadium ntr = (NoseThroatRadium) getClinicalDetermination(NoseThroatRadium.class, person);

		if (ntr == null)
			return null;

		NoseThroatRadiumInfo ntrinfo = new NoseThroatRadiumInfo();

		ntrinfo.setVerificationDate(ntr.getVerificationDate());

		if (ntr.getVerificationMethod() != null) {
			ntrinfo
					.setVerificationMethod(ntr.getVerificationMethod()
							.getDescription());
		}

		if (ntr.getVerificationFacility() != null) {
			ntrinfo.setVerificationFacility(ntr.getVerificationFacility()
					.getSiteNumberAndName());
		}

		if (ntr.getDeterminationFacility() != null) {
			ntrinfo.setDeterminationFacility(ntr.getDeterminationFacility()
					.getSiteNumberAndName());
		}

		if (ntr.getReceivingTreatment() != null)
			ntrinfo.setReceivingTreatment(ntr.getReceivingTreatment()
					.toString());

		ntrinfo.setFromAviatorServiceBefore1955(ntr
				.getFromAviatorServiceBefore1955());
		ntrinfo.setFromSubmarinerServiceBefore1965(ntr
				.getFromSubmarinerServiceBefore1965());
		ntrinfo.setDiagnosedWithCancer(ntr.getDiagnosedWithCancer());
		ntrinfo.setDiagnosisVerifiedDate(ntr.getDiagnosisVerifiedDate());
		return ntrinfo;
	}


	private  SpecialFactorsInfo applySpecialFactors(Person person) {
		Set specialFactors = person.getSpecialFactors();

		if (specialFactors == null)
			return null;

		SpecialFactorsInfo specialFactorInfo = new SpecialFactorsInfo();
		Iterator sfIterator = specialFactors.iterator();
		while (sfIterator.hasNext()) {
			SpecialFactor sf = (SpecialFactor) sfIterator.next();
			if (sf instanceof CampLejeuneVerification) {
			    CampLejeuneVerification cl = (CampLejeuneVerification) sf;

			    if(cl.getSpecialFactorIndicator()==null ||  (! Indicator.YES.getCode().equals(cl.getSpecialFactorIndicator().getCode()) && !Indicator.NO.getCode().equals(cl.getSpecialFactorIndicator().getCode())))
			    continue;
			    specialFactorInfo.setCampLejeuneInd(cl.getSpecialFactorIndicator().toBoolean());
			} else if (sf instanceof AgentOrangeExposure) {
				AgentOrangeExposure ao = (AgentOrangeExposure) sf;
				if ( ao.getAgentOrangeExposureIndicator() != null )
				    specialFactorInfo.setAgentOrangeInd(ao.getAgentOrangeExposureIndicator().toBoolean());
				if ( ao.getLocation() != null )
					specialFactorInfo.setAgentOrangeLocation(ao.getLocation().getDescription());
			}else if (sf instanceof RadiationExposure) {
				RadiationExposure re = (RadiationExposure) sf;
				if ( re.getRadiationExposureIndicator() != null )
				specialFactorInfo.setRadiationExposureInd(re.getRadiationExposureIndicator().toBoolean());

				if ( re.getExposureMethod() != null)
				{
					specialFactorInfo.setRadiationExposureMethod(re.getExposureMethod().getDescription());
				}
			} else if (sf   instanceof EnvironmentalContaminationExposure) {
				EnvironmentalContaminationExposure ec = (EnvironmentalContaminationExposure) sf;
				if ( ec.getEnvironmentalContaminationExposureIndicator() != null )
				specialFactorInfo.setEnvContaminantsInd(ec.getEnvironmentalContaminationExposureIndicator().toBoolean());
			}
		}
		return specialFactorInfo;
	}


	private LookupService getLookupService() {
        // TODO Auto-generated method stub
        return null;
    }

    private  MonetaryBenefitAwardInfo applyMonetaryBenefitAward(Person person) {
		MonetaryBenefitAward mAward = person.getMonetaryBenefitAward();

		if (mAward == null)
			return null;

		MonetaryBenefitAwardInfo mAwardInfo = new MonetaryBenefitAwardInfo();
		mAwardInfo.setCheckAmount(mAward.getCheckAmount());

		Set mBenefits = mAward.getMonetaryBenefits();
		int setSize = 0;
		Iterator mBenefitsItr = null;
		if (mBenefits != null) {
			mBenefitsItr = mBenefits.iterator();
			setSize = mBenefits.size();
		}
		MonetaryBenefitInfo[] mBenefitInfos = new MonetaryBenefitInfo[setSize];
		int i = 0;
		while (mBenefitsItr != null && mBenefitsItr.hasNext()) {
			MonetaryBenefit mBenefit = (MonetaryBenefit) mBenefitsItr.next();
			MonetaryBenefitInfo mBenefitInfo = new MonetaryBenefitInfo();

			if (mBenefit.getMonetaryBenefitIndicator() != null)
			{
				mBenefitInfo.setMonetaryBenefitIndicator(mBenefit
					.getMonetaryBenefitIndicator().toBoolean());
			}

			mBenefitInfo.setType(mBenefit.getType() != null ? mBenefit.getType().getDescription() : null);
			mBenefitInfo.setMonetaryBenefitReportDate(mBenefit.getModifiedOn() != null ? mBenefit.getModifiedOn() : null);
			mBenefitInfos[i] = mBenefitInfo;
			i++;
		}

		if ( mBenefitInfos != null && mBenefitInfos.length > 0 )
		{
			mAwardInfo.setMonetaryBenefits(new MonetaryBenefitCollection(mBenefitInfos));
		}
		return mAwardInfo;
	}



	/**
	 * CatastrophicDisabilityInfo
	 *
	 */
	private  CatastrophicDisabilityInfo applyCatastrophicDisabilityInf(Person person) {
		CatastrophicDisability cd = person.getCatastrophicDisability();

		if (cd == null)
			return null;

		CatastrophicDisabilityInfo cdInfo = new CatastrophicDisabilityInfo();
		cdInfo.setReviewDate(cd.getReviewDate());
		cdInfo.setDeterminedBy(cd.getDeterminedBy());
		if (cd.getDeterminationFacility() != null)
			cdInfo.setDeterminationFacility(cd.getDeterminationFacility()
					.getSiteNumberAndName());
		cdInfo.setDecisionDate(cd.getDecisionDate());

		if (cd.getDeterminationMethod() != null)
			cdInfo
					.setDeterminationMethod(cd.getDeterminationMethod()
							.getDescription());



		cdInfo.setVeteranRequestedCDReviewDate(cd
				.getVeteranRequestedCDReviewDate());
		cdInfo.setVeteranWasNotifiedCDDate(cd.getVeteranWasNotifiedCDDate());


		cdInfo.setCatastrophicallyDisabled(cd.getCatastrophicallyDisabled());


		//private String[] diagnoses = null;
		if (cd.getDiagnoses() != null) {
			Set diagnoses = cd.getDiagnoses();
			String[] diagArr = new String[diagnoses.size()];
			Iterator diagIter = diagnoses.iterator();

			int i = 0;
			while (diagIter.hasNext()) {
				CDDiagnosis cdDiagnosis = (CDDiagnosis) diagIter.next();
				Diagnosis  diagnosis = cdDiagnosis.getDiagnosis();
				String d = diagnosis.getDescription();
				diagArr[i] = d;
				i++;
			}

			if ( diagArr != null && diagArr.length > 0 )
			{
				cdInfo.setDiagnoses(new CDDiagnosisCollection(diagArr));
			}
		}
		//private CDProcedureInfo[] cdProcedures = null;
		if (cd.getProcedures() != null) {
			Set procedures = cd.getProcedures();
			Iterator procedureItr = procedures.iterator();
			CDProcedureInfo[] procedureArr = new CDProcedureInfo[procedures
					.size()];
			int i = 0;
			while (procedureItr.hasNext()) {
				CDProcedure p = (CDProcedure) procedureItr.next();
				CDProcedureInfo pInfo = new CDProcedureInfo();
				if (p.getProcedure() != null)
					pInfo.setProcedure(p.getProcedure().getDescription());

				if (p.getAffectedExtremity() != null)
					pInfo.setAffectedExtremity(p.getAffectedExtremity()
							.getDescription());

				procedureArr[i] = pInfo;
				i++;
			}
			if ( procedureArr != null && procedureArr.length > 0 )
			{
				cdInfo.setCdProcedures(new CDProcedureCollection(procedureArr));
			}

		}

		//private CDConditionInfo[] cdConditions = null;
		if (cd.getConditions() != null) {
			Set conditions = cd.getConditions();
			Iterator conditionsItr = conditions.iterator();
			CDConditionInfo[] conditionArr = new CDConditionInfo[conditions
					.size()];
			int i = 0;
			while (conditionsItr.hasNext()) {
				CDCondition c = (CDCondition) conditionsItr.next();
				CDConditionInfo cInfo = new CDConditionInfo();
				if (c.getCondition() != null)
					cInfo.setCondition(c.getCondition().getName());


				if (c.getPermanentIndicator() != null)
					cInfo.setPermanentIndicator(c.getPermanentIndicator().toBoolean());

				cInfo.setScore(c.getScore());

				conditionArr[i] = cInfo;
				i++;
			}
			if ( conditionArr != null)
			{
				cdInfo.setCdConditions(new CDConditionCollection(conditionArr));
			}
		}

		return cdInfo;
	}





	   /**
     * Return the particular type of clinical determination from person.
     *
     * @param classObject
     * @param person
     * @return
     */
    public  ClinicalDetermination getClinicalDetermination(Class classObject,
            Person person) {

        if (person == null) {
            return null;
        }
        Set clinicalDeterminations = person.getClinicalDeterminations();
        ClinicalDetermination clinicalDetermination = null;

        if (clinicalDeterminations != null && clinicalDeterminations.size() > 0) {
            Iterator iterClinicalDeterminations = clinicalDeterminations
                    .iterator();

            while (iterClinicalDeterminations.hasNext()) {
                ClinicalDetermination temp = (ClinicalDetermination) iterClinicalDeterminations
                        .next();

                if (temp != null
                        && temp.getClass().isAssignableFrom(classObject)) {
                    clinicalDetermination = temp;
                    break;
                }
            }
        }

        return clinicalDetermination;
    }

    private String toPreciseDateTimeFormat(Date date) {
        if (date != null) {
            SimpleDateFormat format = new SimpleDateFormat(preciseDateTimeFormat);
            return format.format(date);
        }
        return "";
    }
}
