/*******************************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.rule.parameter;

// Java classes

// Library classes
import java.util.Date;
import java.util.Set;

import org.apache.commons.lang.Validate;

import gov.va.med.fw.rule.RuleException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.builder.BuilderException;

import gov.va.med.esr.common.builder.entity.BooleanBuilder;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.ee.AgentOrangeExposure;
import gov.va.med.esr.common.model.ee.CampLejeuneVerification;
import gov.va.med.esr.common.model.ee.Eligibility;
import gov.va.med.esr.common.model.ee.EnvironmentalContaminationExposure;
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.ee.CampLejeuneVerificationMethod;
import gov.va.med.esr.common.model.lookup.AgentOrangeExposureLocation;
import gov.va.med.esr.common.model.lookup.CampLejeuneChangeSource;
import gov.va.med.esr.common.model.lookup.CampLejeuneVerificationType;
import gov.va.med.esr.common.model.lookup.EligibilityStatus;
import gov.va.med.esr.common.model.lookup.Indicator;
import gov.va.med.esr.common.model.lookup.RadiationExposureMethod;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.system.SystemParameter;
import gov.va.med.esr.common.rule.SpecialFactorInput;
import gov.va.med.esr.common.util.CommonDateUtils;
import gov.va.med.esr.common.model.lookup.EligibilityType;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.esr.service.EEResultInfo;

/**
 * This classs is a facade that provides access to special factor information.
 * Parameter objects are loaded into ILOG working memory for use by rules.
 *
 * @author Vu Le
 * @version 1.0
 */
public class SpecialFactorInputParameter extends BaseParameter implements
        SpecialFactorInput {

    private static final long serialVersionUID = -1946680451967672718L;

	private static final String CL_ERROR_REASON_NOT_SUPPORT = "ES data on file does not support CL eligibility.";

	private static final String CL_ERROR_REASON_UPDATE_INELIGIBLE = "ES CL eligibility updated with CLEAR ineligibility.";

	private static final String VOA_CLE_CANNOT_BE_DETERMINED = "Veteran CL Eligibility cannot be determined";

    /**
     * A default constructor
     */
    public SpecialFactorInputParameter() {
        super();
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#isPartOfShadFile()
     */
    public boolean isPartOfShadFile() {
        return (this.getIncomingPerson().getShad() != null
                && this.getIncomingPerson().getShad().getShadIndicator() != null && this
                .getIncomingPerson().getShad().getShadIndicator().toBoolean() != null) ? this
                .getIncomingPerson().getShad().getShadIndicator().toBoolean()
                .booleanValue()
                : false;
    }

    // CR 9803 & CCR 10023
    public boolean isPartOfShadFile(Person person) {
        return (person != null && person.getShad() != null && person.getShad().getShadIndicator() != null &&
        		person.getShad().getShadIndicator().toBoolean() != null) ?
        				person.getShad().getShadIndicator().toBoolean().booleanValue() : false;
	}

	/**
     *
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getAgentOrangeExposure()
     */
    public AgentOrangeExposure getAgentOrangeExposure() {
        return (AgentOrangeExposure) this.getSpecialFactor(
                AgentOrangeExposure.class, this.getIncomingPerson());
    }

    /**
     *
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#setResultAgentOrangeExposure(gov.va.med.esr.common.model.ee.AgentOrangeExposure)
     */
    public void setResultAgentOrangeExposure(AgentOrangeExposure exposure)
            throws RuleException {
        if (exposure == null) {
            try {
                AgentOrangeExposure aoe = this.getResultPerson()
                        .getAgentOrangeExposure();
                if (aoe != null) {
                    Indicator ind = (Indicator) this.getLookupService()
                            .getByCode(Indicator.class, Indicator.NO.getCode());
                    aoe.setAgentOrangeExposureIndicator(ind);
                    aoe.setLocation(null);
                }
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }
        } else {
            try {
                String ind = (exposure.getLocation() != null) ? Indicator.YES
                        .getCode() : Indicator.NO.getCode();
                Indicator indicator = (Indicator) this.getLookupService()
                        .getByCode(Indicator.class, ind);
                exposure.setAgentOrangeExposureIndicator(indicator);
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }

            this.updateSpecialFactor(exposure, this.getResultPerson());
        }
    }

    /**
     *
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getEnvironmentalContaminationExposure()
     */
    public EnvironmentalContaminationExposure getEnvironmentalContaminationExposure() {
        return (EnvironmentalContaminationExposure) this.getSpecialFactor(
                EnvironmentalContaminationExposure.class, this
                        .getIncomingPerson());
    }

    /**
     *
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#setResultEnvironmentalContaminants(gov.va.med.esr.common.model.ee.EnvironmentalContaminationExposure)
     */
    public void setResultEnvironmentalContaminants(
            EnvironmentalContaminationExposure exposure) throws RuleException {

        if (exposure == null) {
            try {
                EnvironmentalContaminationExposure envc = this
                        .getResultPerson()
                        .getEnvironmentalContaminationExposure();
                if (envc != null) {
                    Indicator ind = (Indicator) this.getLookupService()
                            .getByCode(Indicator.class, Indicator.NO.getCode());
                    envc.setEnvironmentalContaminationExposureIndicator(ind);
                }
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }
        } else {
            this.updateSpecialFactor(exposure, this.getResultPerson());
        }
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getRadiationExposure()
     */
    public RadiationExposure getRadiationExposure() {
        return (RadiationExposure) this.getSpecialFactor(
                RadiationExposure.class, this.getIncomingPerson());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#setResultRadiationExposure(gov.va.med.esr.common.model.ee.RadiationExposure)
     */
    public void setResultRadiationExposure(RadiationExposure exposure)
            throws RuleException {
        if (exposure == null) {
            try {
                RadiationExposure rad = this.getResultPerson()
                        .getRadiationExposure();
                if (rad != null) {
                    Indicator ind = (Indicator) this.getLookupService()
                            .getByCode(Indicator.class, Indicator.NO.getCode());
                    rad.setRadiationExposureIndicator(ind);
                    rad.setExposureMethod(null);
                }
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }
        } else {
            try {
                String ind = (exposure.getExposureMethod() != null) ? Indicator.YES
                        .getCode()
                        : Indicator.NO.getCode();
                Indicator indicator = (Indicator) this.getLookupService()
                        .getByCode(Indicator.class, ind);
                exposure.setRadiationExposureIndicator(indicator);
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }
            this.updateSpecialFactor(exposure, this.getResultPerson());
        }
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getAgentOrangeLocation()
     */
    public AgentOrangeExposureLocation getAgentOrangeLocation() {
        AgentOrangeExposure agentorange = this.getAgentOrangeExposure();
        return (agentorange != null) ? agentorange.getLocation() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#setResultAgentOrangeLocation(gov.va.med.esr.common.model.lookup.AgentOrangeExposureLocation)
     */
    public void setResultAgentOrangeLocation(
            AgentOrangeExposureLocation location) {
        Person onFile = this.getResultPerson();
        AgentOrangeExposure exposure = this.getResultAgentOrange();
        if (exposure == null)
            onFile.addSpecialFactor((exposure = new AgentOrangeExposure()));
        exposure.setLocation(location);

    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getRadiationExposureMethod()
     */
    public RadiationExposureMethod getRadiationExposureMethod() {
        RadiationExposure exposure = this.getRadiationExposure();
        return (exposure != null) ? exposure.getExposureMethod() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#setResultRadiationExposureMethod(gov.va.med.esr.common.model.lookup.RadiationExposureMethod)
     */
    public void setResultRadiationExposureMethod(RadiationExposureMethod method) {
        Person onFile = this.getResultPerson();
        RadiationExposure exposure = this.getResultRadiationExposure();
        if (exposure == null)
            onFile.addSpecialFactor((exposure = new RadiationExposure()));
        exposure.setExposureMethod(method);
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineAgentOrange()
     */
    public AgentOrangeExposure getPristineAgentOrange() {
        return (AgentOrangeExposure) this.getSpecialFactor(
                AgentOrangeExposure.class, this.getPristinePerson());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineAgentOrangeLocation()
     */
    public AgentOrangeExposureLocation getPristineAgentOrangeLocation() {
      AgentOrangeExposure agentorange = this.getPristineAgentOrange();
      return (agentorange != null) ? agentorange.getLocation() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineRadiationExposure()
     */
    public RadiationExposure getPristineRadiationExposure() {
        return (RadiationExposure) this.getSpecialFactor(
                RadiationExposure.class, this.getPristinePerson());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineRadiationExposureMethod()
     */
    public RadiationExposureMethod getPristineRadiationExposureMethod() {
      RadiationExposure exposure = this.getPristineRadiationExposure();
      return (exposure != null) ? exposure.getExposureMethod() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultAgentOrange()
     */
    public AgentOrangeExposure getResultAgentOrange() {
        return (AgentOrangeExposure) this.getSpecialFactor(
                AgentOrangeExposure.class, this.getResultPerson());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultAgentOrangeLocation()
     */
    public AgentOrangeExposureLocation getResultAgentOrangeLocation() {
    	// CCR 10023 need to fix null pointers
    	  return this.getResultAgentOrange() != null ? this.getResultAgentOrange().getLocation() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultRadiationExposure()
     */
    public RadiationExposure getResultRadiationExposure() {
        return (RadiationExposure) this.getSpecialFactor(
                RadiationExposure.class, this.getResultPerson());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultRadiationExposureMethod()
     */
    public RadiationExposureMethod getResultRadiationExposureMethod() {
    	// CCR 10023 need to fix null pointers
    	  return this.getResultRadiationExposure() != null ? this.getResultRadiationExposure().getExposureMethod() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getAgentOrangeExposureIndicator()
     */
    public Boolean getAgentOrangeExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getIncomingPerson()
                .getAgentOrangeExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getEnvironmentalContaminationExposureIndicator()
     */
    public Boolean getEnvironmentalContaminationExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getIncomingPerson()
                .getEnvironmentalContaminationExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineAgentOrangeIndicator()
     */
    public Boolean getPristineAgentOrangeIndicator() {
        return convertSFIndicatorToBoolean(this.getPristinePerson()
                .getAgentOrangeExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineRadiationExposureIndicator()
     */
    public Boolean getPristineRadiationExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getPristinePerson()
                .getRadiationExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getPristineEnvironmentalContaminationExposureIndicator()
     */
    public Boolean getPristineEnvironmentalContaminationExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getPristinePerson()
                .getEnvironmentalContaminationExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getRadiationExposureIndicator()
     */
    public Boolean getRadiationExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getIncomingPerson()
                .getRadiationExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultAgentOrangeIndicator()
     */
    public Boolean getResultAgentOrangeIndicator() {
        return convertSFIndicatorToBoolean(this.getResultPerson()
                .getAgentOrangeExposure());
    }

    /**
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getResultRadiationExposureIndicator()
     */
    public Boolean getResultRadiationExposureIndicator() {
        return convertSFIndicatorToBoolean(this.getResultPerson()
                .getRadiationExposure());
    }

    /**
     * Updates a special factor in the specific veteran
     *
     * @param factor
     *            A factor to set
     * @param person
     *            A veteran to set a new factor
     */
    private void updateSpecialFactor(SpecialFactor factor, Person person)
            throws RuleException {
        Validate.notNull(factor, "A special factor cannot be null");
        Validate.notNull(person, "A veteran must not be null");

        try {
            this.getMergeRuleService().mergeSpecialFactor(factor, person);
        } catch (ServiceException e) {
            throw new RuleException("Failed to update special factor", e);
        }
    }

    private Boolean convertSFIndicatorToBoolean(SpecialFactor sf) {
        return (sf != null && sf.getSpecialFactorIndicator() != null) ? sf
                .getSpecialFactorIndicator().toBoolean() : null;
    }

    /**
     * Returns the specicial factor from a veteran
     *
     * @param type
     *            A type to update
     * @param person
     *            A veteran to get a factor
     * @return SpecialFactor A special factor in the specified veteran
     */
    private SpecialFactor getSpecialFactor(Class type, Person person) {

        Validate.notNull(type, "A special factor class type must not be null");
        Validate.notNull(person, "A veteran must not be null");

        return person.getSpecialFactorByType(type);
    }

    /*
     *  Agent Orange Special Treatment Authority Indicator
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getAOTreatmentAuthorityIndicator()
     */
    public Boolean getAOTreatmentAuthorityIndicator() throws ServiceException {
        return getSystemParameterService().getAOTreatmentAuthorityIndicator();
     }

    /*
     *  Agent Orange Special Treatment Authority Expiration Date
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getAOTreatmentAuthorityExpirationDate()
     */
    public Date getAOTreatmentAuthorityExpirationDate()  throws ServiceException {
        return getSystemParameterService().getAOTreatmentAuthorityExpirationDate();
    }

    /*
     * SW Asia Conditions Special Treatment Authority Indicator
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getECTreamentAuthorityIndicator()
     */
    public Boolean getECTreamentAuthorityIndicator() throws ServiceException {
        return getSystemParameterService().getECTreamentAuthorityIndicator();
   }

    /*
     * SW Asia Conditions Special Treatment Authority Expiration Date
     * @see gov.va.med.esr.common.rule.SpecialFactorInput#getECTreatmentAuthorityExpirationDate()
     */
    public Date getECTreatmentAuthorityExpirationDate() throws ServiceException {
        return getSystemParameterService().getECTreatmentAuthorityExpirationDate();
    }
    public boolean isRadiationExposureMethodChnged(){
    	RadiationExposureMethod  pristinREM= getPristineRadiationExposureMethod();
    	RadiationExposureMethod  resultREM=getResultRadiationExposureMethod();
    	if(this.isEqual(pristinREM, resultREM)){
    		return false;
    	}
    	else{
    		return true;
    	}


    }
    public boolean isAgentOrangeLocationChnged(){
    	AgentOrangeExposureLocation  pristineAgentOrangeLocation=getPristineAgentOrangeLocation();
    	AgentOrangeExposureLocation  resultAgentOrangeLocation=getResultAgentOrangeLocation() ;
    	if(this.isEqual(pristineAgentOrangeLocation, resultAgentOrangeLocation)){
        	return false;
        	}
        	else{
        		return true;
        	}
    }
  //CLV//
    public CampLejeuneVerification getCampLejeuneVerification()
    {
    	  return (CampLejeuneVerification) this.getSpecialFactor(
    			  CampLejeuneVerification.class, this.getIncomingPerson());
    }
    public CampLejeuneVerification getPristineCampLejeuneVerification(){
    	  return (CampLejeuneVerification) this.getSpecialFactor(
    			  CampLejeuneVerification.class, this.getPristinePerson());
    }
    public CampLejeuneVerification getResultCampLejeuneVerification(){
    	  return (CampLejeuneVerification) this.getSpecialFactor(
    			  CampLejeuneVerification.class, this.getResultPerson());
    }
    public void    setResultCampLejeuneVerification(CampLejeuneVerification clv) throws RuleException {


    		if (clv == null) {       //For VOA null means No, For CLEAR No means yes
    			/*try {
            	CampLejeuneVerification clvnew = this.getResultPerson().getCampLejeuneVerification();

                //if (clvnew != null) {
                    //Indicator ind = (Indicator) this.getLookupService()
                     //       .getByCode(Indicator.class, Indicator.NO.getCode());
                   // clvnew.setSpecialFactorIndicator(ind);
                //}
            } catch (Exception ex) {
                new RuleException("Indicator code NO not found", ex);
            }*/
    		} else {
    			this.updateSpecialFactor(clv, this.getResultPerson());


    		}

    }
    //CCR13815
	public void setErrorReasonNotSupport()
	{
		//this.getSendingFacility().setErrorReason(CL_ERROR_REASON_NOT_SUPPORT);
        EEResultInfo info = this.getBaseData() != null ? this.getBaseData().getEEResultInfo() : null;
        if (info != null) {
               info.setCLVErrorReason(CL_ERROR_REASON_NOT_SUPPORT);
        }

	}
	public void setErrorReasonUpdatedIneligible()
	{
		//this.getSendingFacility().setErrorReason(CL_ERROR_REASON_UPDATE_INELIGIBLE);
        EEResultInfo info = this.getBaseData() != null ? this.getBaseData().getEEResultInfo() : null;
        if (info != null) {
               info.setCLVErrorReason(CL_ERROR_REASON_UPDATE_INELIGIBLE);
        }
	}

	//Originally added in CCR13810; 228571 remove call to set error reason in singleton, replace with call to getEEResultInfo
	public void setErrorReasonVOACLENotDetermined() {
           EEResultInfo info = this.getBaseData() != null ? this.getBaseData().getEEResultInfo() : null;
           if (info != null) {
                  info.setCLVErrorReason(VOA_CLE_CANNOT_BE_DETERMINED);
           }
    }

    public void   setResultCampLejeuneVerificationForCLEAR(CampLejeuneVerification clv) throws RuleException {


		if (clv == null) {       //For VOA null means No, For CLEAR No means yes

		} else {
			//ImpreciseDate imcomingDate=clv.getRegistrationDate();
			CampLejeuneVerification resultCLV = getResultCampLejeuneVerification();
			if(resultCLV!=null && resultCLV.getSpecialFactorIndicator()!=null)
			{
				ImpreciseDate outputDate= resultCLV.getRegistrationDate();
				ImpreciseDate incomingDate=clv.getRegistrationDate();

				if (outputDate != null) {
					if(incomingDate!=null && CommonDateUtils.isDateAfter(incomingDate, outputDate))
					{
						clv.setRegistrationDate(outputDate);
					}
					else if (incomingDate==null)
					{
						clv.setRegistrationDate(outputDate);
					}
				} else {
					//CCR13860: if incoming is null, the result date is null too
					clv.setRegistrationDate(new ImpreciseDate(new Date()));
				}
			}

			//now copy the incoming values to the result values
			//BUT: since this methods is at the end of ilog rules, the resultPerson already has CLV indicator set by ilog rules,
			//don't let the incoming CLV indicator merged into the result indicator, set it back after the update (merge)
			Indicator resultIndicator = (resultCLV == null) ? null:resultCLV.getSpecialFactorIndicator();
			this.updateSpecialFactor(clv, this.getResultPerson());

			this.getResultPerson().getCampLejeuneVerification().setSpecialFactorIndicator(resultIndicator); //set it back

		}

}
    public void    setResultCampLejeuneVerificationForMS(CampLejeuneVerification clv) throws RuleException {

    	if(isIgnoreInOn()==false)
    	{
    		if (clv == null) {       //For VOA null means No, For CLEAR No means yes

    		} else {
    			this.updateSpecialFactor(clv, this.getResultPerson());
    		}
    	}
    }

    public Boolean getCampLejeuneIndicator(){
    	 //return type could be null
    	return convertSFIndicatorToBoolean(this.getIncomingPerson()
                .getCampLejeuneVerification());
    }
    public Boolean getPristineCampLejeuneIndicator(){
    	return convertSFIndicatorToBoolean(this.getPristinePerson()
                .getCampLejeuneVerification());
    }
    public Boolean getResultCampLejeuneIndicator(){
    	return convertSFIndicatorToBoolean(this.getResultPerson()
                .getCampLejeuneVerification());
    }
    public void  setResultCampLejeuneIndicator(Boolean id) throws RuleException{
     //setSpecialFactorIndicator(null);
     //STD_YESNOCODE, unknown means NULL?????
    	try{
    	        Person onFile = this.getResultPerson();
    	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	        if (clv == null)
    	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
    	        if(id== null)
    	        {
    	        	//clv.setSpecialFactorIndicator(getLookupService().getIndicatorByCode(Indicator.UNKNOWN));
    	        	clv.setSpecialFactorIndicator(null);
    	        }
    	        else if(id.booleanValue())
    	        {
    	        	clv.setSpecialFactorIndicator(this.getLookupService().getIndicatorByCode(Indicator.YES));
    	        }
    	        else
    	        {
    	        	clv.setSpecialFactorIndicator(this.getLookupService().getIndicatorByCode(Indicator.NO));
    	        }
    	}
    	catch (Exception ex) {
            new RuleException("Indicator code NO not found", ex);
    	}

    }

    public CampLejeuneVerificationType getCampLejeuneVerificationType() throws UnknownLookupTypeException, UnknownLookupCodeException{
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	if(clv==null)
    	{
    		return null;
    	}
    	else
    	{
    		if(isCampLejeuneVerificationMethodBlank()!= true)
    		{
    			return null;
    		}



    		CampLejeuneVerificationType clvtype = (CampLejeuneVerificationType)this.getLookupService().getByCode(CampLejeuneVerificationType.class,CampLejeuneVerificationType.VERIFICATION_OTHER.getCode());

    		clv.setVerificationType(clvtype);
    		return clv.getVerificationType();
    	}
    	//return (clv!=null)? clv.getVerificationType(): null;
    	/*CampLejeuneVerificationType cmpt = new CampLejeuneVerificationType();
    	if(isCampLejeuneVerificationMethodBlank()!= true)
    	{
    		return null;
    	}
    	else
    	{
    		return cmpt;
    	}*/

    }
    public CampLejeuneVerificationType getPristineCampLejeuneVerificationType(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null)? clv.getVerificationType(): null;
    }
    public CampLejeuneVerificationType getResultCampLejeuneVerificationType(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null)? clv.getVerificationType(): null;
    }
    public void  setResultCampLejeuneVerificationType(CampLejeuneVerificationType clvtype){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        	clv.setVerificationType(clvtype);
    }

    /////////////////////////////////////13629////////////////////////////////////////////////////////
    public boolean isCampLejeuneVerificationMethodBlank()
    {
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null && clv.getInternalCampLejeuneVerificationMethods()!=null && clv.getInternalCampLejeuneVerificationMethods().size()>0)? true: false;
    }
    public Set getCampLejeuneVerificationMethods(){
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null && clv.getInternalCampLejeuneVerificationMethods()!=null && clv.getInternalCampLejeuneVerificationMethods().size()>0)? clv.getInternalCampLejeuneVerificationMethods(): null;

    }
    public Set getPristineCampLejeuneVerificationMethods(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null && clv.getInternalCampLejeuneVerificationMethods()!=null)? clv.getInternalCampLejeuneVerificationMethods(): null;

    }
    public Set getResultCampLejeuneVerificationMethods(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null && clv.getInternalCampLejeuneVerificationMethods()!=null)? clv.getInternalCampLejeuneVerificationMethods(): null;

    }

    public void  setResultCampLejeuneVerificationMethods(Set<CampLejeuneVerificationMethod> clvmethods){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        ///Have to get clv from person//
	        clv = this.getResultCampLejeuneVerification();
	        if(clv.getInternalCampLejeuneVerificationMethods()!=null && clv.getInternalCampLejeuneVerificationMethods().size()>0)
	        	clv.removeAllCampLejeuneVerificationMethods();
	        if (clv != null)
	        {
	        	for(CampLejeuneVerificationMethod clvm: clvmethods)
	        	{
	        		clv.addCampLejeuneVerificationMethod(clvm);
	        		//clv.setInternalCampLejeuneVerificationMethods(clvmethods);
	        	}
	        }
    }
    ////////////////////////////////////13629/////////////////////////////////////////////////////////

    public CampLejeuneChangeSource getCampLejeuneChangeSource(){
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSource(): null;
    }
    public CampLejeuneChangeSource getPristineCampLejeuneChangeSource(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSource(): null;
    }
    public CampLejeuneChangeSource getResultCampLejeuneChangeSource(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSource(): null;
    }
    public void  setResultCampLejeuneChangeSource(CampLejeuneChangeSource clvsource){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        	clv.setChangeSource(clvsource);
    }

    public VAFacility getCampLejeuneChangeSite(){
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSite(): null;
    }

    public VAFacility getPristineCampLejeuneChangeSite(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSite(): null;
    }
    public VAFacility getResultCampLejeuneChangeSite(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeSite(): null;
    }
    public void  setResultCampLejeuneChangeSite(VAFacility clvsite){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        	clv.setChangeSite(clvsite);
    }

    public Date getCampLejeuneChangeDate(){
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeDate(): null;
    }
    public Date getPristineCampLejeuneChangeDate(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeDate(): null;
    }
    public Date getResultCampLejeuneChangeDate(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null)? clv.getChangeDate(): null;
    }//onfile
    public void  setResultCampLejeuneChangeDate(Date clvdate){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        	clv.setChangeDate(clvdate);
    }

    public String getCampLejeuneComments(){
    	CampLejeuneVerification clv = this.getCampLejeuneVerification();
    	return (clv!=null)? clv.getComments(): null;
    }
    public String getPristineCampLejeuneComments(){
    	CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
    	return (clv!=null)? clv.getComments(): null;
    }
    public String getResultCampLejeuneComments(){
    	CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
    	return (clv!=null)? clv.getComments(): null;
    }
    public void  setResultCampLejeuneChangeDate(String comments){
    	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));
	        	clv.setComments(comments);
    }

    public void  setResultCLRegDateToIncomingCLRegDate(){
   	 Person onFile = this.getResultPerson();
	        CampLejeuneVerification clv = this.getResultCampLejeuneVerification();
	        if (clv == null)
	            onFile.addSpecialFactor((clv = new CampLejeuneVerification()));

	        CampLejeuneVerification clvIn = this.getCampLejeuneVerification();
	        if (clvIn == null) {
	        	clv.setRegistrationDate(new ImpreciseDate(new Date()));
	        } else {
	        	clv.setRegistrationDate(clvIn.getRegistrationDate());
	        }
   }

   //IsCurrentCLBlank: CamplejeuneVerification null OR CLV Indiator is Null or (CLV Indicator is Yes or No)
   public boolean isCurrentCLBlank()
   {
	   Person onFile = this.getPristinePerson();
       CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
       if (clv == null ||clv.getSpecialFactorIndicator()==null||((!clv.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode())) && (!clv.getSpecialFactorIndicator().getCode().equals(Indicator.NO.getCode()))))
       {
    	   return true;
       }
       else
       {
    	   return false;
       }

   }
   public boolean isInComingCLYesBlank()
   {
       CampLejeuneVerification clv = this.getCampLejeuneVerification();
       if (clv == null ||clv.getSpecialFactorIndicator() == null||
    		   Indicator.YES.getCode().equals(clv.getSpecialFactorIndicator().getCode()) )
       {
    	   return true;
       }

         return false;
   }

  public void updateCLVByCurrent() throws RuleException
  {

	  CampLejeuneVerification clv = this.getPristineCampLejeuneVerification();
	  if(clv==null)
	  {
		  clv = new CampLejeuneVerification();
		  clv.setSpecialFactorIndicator(null);
	  }
	  this.updateSpecialFactor(clv, this.getResultPerson());
	  /////////////OR//////////////////////////

	 /* CampLejeuneVerification clvr = this.getResultCampLejeuneVerification();
	  if(clvr ==null)
	  {
		  clvr = new CampLejeuneVerification();
	  }

	 clvr.setSpecialFactorIndicator(clv.getSpecialFactorIndicator());
	  clvr.setVerificationType(clv.getVerificationType());
	  if(clv.getInternalCampLejeuneVerificationMethods()!=null)
	  {
		  Set<CampLejeuneVerificationMethod> clvms = clv.getInternalCampLejeuneVerificationMethods();
		  clvr.removeAllCampLejeuneVerificationMethods();
		  for(CampLejeuneVerificationMethod clvm: clvms)
		  {
			  clvr.addCampLejeuneVerificationMethod(clvm);
			  //clv.setInternalCampLejeuneVerificationMethods(clvmethods);
		  }
	  }
	  else
	  {
		  clvr.removeAllCampLejeuneVerificationMethods();
	  }
	  clvr.setChangeDate(clv.getChangeDate());
	  clvr.setChangeSite(clv.getChangeSite());
	  clvr.setChangeSource(clv.getChangeSource());

	  //////////////OR///////////////////////
	  //setResultCampLejeuneVerification(clv);
*/
  }

  public void UpdateResultChangeSiteToHEC()  throws UnknownLookupTypeException, UnknownLookupCodeException
  {
	  VAFacility vafac = (VAFacility)this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
	  setResultCampLejeuneChangeSite(vafac);
  }

  public void UpdateResultChangeSourceToVOA() throws UnknownLookupTypeException, UnknownLookupCodeException
  {
	  CampLejeuneChangeSource clcs = (CampLejeuneChangeSource)this.getLookupService().getByCode(CampLejeuneChangeSource.class,CampLejeuneChangeSource.CODE_VOA.getCode());
	  setResultCampLejeuneChangeSource(clcs);
  }

  public  boolean IsEligibilityNonVeteran()
  {
	  //incoming.getReceivedPrimaryEligibility();
	  /*
	   * Humanitarian Emergency
		Sharing Agreement
		TRICARE
		Allied Veteran
		CHAMPVA
		Employee
		Collateral of Vet
		Other Federal Agency

	   */
	  Eligibility code = this.getIncomingPerson().getEnrollmentDetermination().getPrimaryEligibility();
	  if (code != null && code.getType()!=null &&
			  (code.getType().getCode().equals(EligibilityType.ALLIED_VETERAN.getCode())
					  || code.getType().getCode().equals(EligibilityType.OTHER_FEDERAL_AGENCY.getCode())
					  || code.getType().getCode().equals(EligibilityType.COLLATERAL_OF_VETERAN.getCode())
					  || code.getType().getCode().equals(EligibilityType.CHAMPVA.getCode())
					  || code.getType().getCode().equals(EligibilityType.EMPLOYEE.getCode())
					  || code.getType().getCode().equals(EligibilityType.SHARING_AGREEMENT.getCode())
					  || code.getType().getCode().equals(EligibilityType.TRICARE_CHAMPUS.getCode())
				      || code.getType().getCode().equals(EligibilityType.HUMANTARIAN_EMERGENCY.getCode())
			  ))
	  {
		  return true;
	  }
	  else
	  {
		  return false;
	  }

  }

  public boolean IsCurrentCEligibilityVerified()
  {
	  if(this.getResultPerson().getEligibilityVerification().getEligibilityStatus().getCode().equals(EligibilityStatus.CODE_VERIFIED.getCode()))
	  {
		  return true;
	  }
	  else
	  {
		  return false;
	  }
  }


  public void setVistaCLV() throws RuleException,UnknownLookupTypeException, UnknownLookupCodeException
  {
         Person onFile = this.getResultPerson();
         CampLejeuneVerification campLejeuneVerification = onFile.getCampLejeuneVerification();

         campLejeuneVerification.setSpecialFactorIndicator(this.getLookupService().getIndicatorByCode(Indicator.NO));
         campLejeuneVerification.setChangeSite(this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode()));
         campLejeuneVerification.setChangeSource(this.getLookupService().getCampLejeuneChangeSourceByCode(CampLejeuneChangeSource.CODE_HEC.getCode()));
      campLejeuneVerification.setRegistrationDate(null);
      campLejeuneVerification.setComments(null);
      campLejeuneVerification.removeAllCampLejeuneVerificationMethods();

  }


  public void setChangeSiteSourceHEC() throws RuleException,UnknownLookupTypeException, UnknownLookupCodeException
  {

	  UpdateResultChangeSiteToHEC();
	  CampLejeuneChangeSource clcs = (CampLejeuneChangeSource)this.getLookupService().getByCode(CampLejeuneChangeSource.class,CampLejeuneChangeSource.CODE_HEC.getCode());
	  setResultCampLejeuneChangeSource(clcs);

  }
  public boolean isFromVOA()
  {
	  CampLejeuneVerification clv = this.getCampLejeuneVerification();
	  if(clv!=null && clv.getChangeSource()!=null)
	  {
		  if(clv.getChangeSource().getCode().equals(CampLejeuneChangeSource.CODE_VOA.getCode()))
		  {
			  return true;
		  }
		  else
		  {
			  return false;
		  }
	  }
	  else
	  {
		  return false;
	  }
  }

  public boolean isFromVista()
  {
	  //ORU-Z07,ORF-Z07
	 return this.isMessageFromVista();
  }

  public boolean isFromClear()
  {
	  if (this.getCampLejeuneVerification() != null && this.getCampLejeuneVerification().getChangeSource() != null)
		  return CampLejeuneChangeSource.CODE_CLEAR.getCode().equals(this.getCampLejeuneVerification().getChangeSource().getCode());

	  return false;
  }

  public void setNotSupportErrorReason() {
	  //this.getSendingFacility().setErrorReason("ES data on file does not support CL eligibility.");
      EEResultInfo info = this.getBaseData() != null ? this.getBaseData().getEEResultInfo() : null;
      if (info != null) {
             info.setCLVErrorReason(CL_ERROR_REASON_NOT_SUPPORT);
      }
  }

  public void setUpdatedIneligibleErrorReason() {
	  //this.getSendingFacility().setErrorReason("ES CL eligibility updated with CLEAR ineligibility.");
      EEResultInfo info = this.getBaseData() != null ? this.getBaseData().getEEResultInfo() : null;
      if (info != null) {
             info.setCLVErrorReason(CL_ERROR_REASON_UPDATE_INELIGIBLE);
      }
  }

  public boolean isIgnoreInOn() throws RuleException
  {
	  CampLejeuneVerification clvIn = this.getCampLejeuneVerification();
	  CampLejeuneVerification clvOn = this.getResultCampLejeuneVerification();
	  return isIgnore(clvIn,clvOn);
  }

  public boolean isIgnorePOn() throws RuleException
  {
	  CampLejeuneVerification clvIn = this.getPristineCampLejeuneVerification();
	  CampLejeuneVerification clvOn = this.getResultCampLejeuneVerification();
	  return isIgnore(clvIn,clvOn);
  }
  public boolean isIgnore(CampLejeuneVerification clvIn,CampLejeuneVerification clvOn) throws RuleException
  {

	  boolean iSSame=false;

	  try {
	  if ((clvIn == null ||clvIn.getSpecialFactorIndicator()==null||((!clvIn.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode())) && (!clvIn.getSpecialFactorIndicator().getCode().equals(Indicator.NO.getCode()))))
	       &&
	       (clvOn == null ||clvOn.getSpecialFactorIndicator()==null||((!clvOn.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode())) && (!clvOn.getSpecialFactorIndicator().getCode().equals(Indicator.NO.getCode())))))

	  {
		  return true;
	  }
	  else if(clvIn == null ||clvIn.getSpecialFactorIndicator()==null||((!clvIn.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode())) && (!clvIn.getSpecialFactorIndicator().getCode().equals(Indicator.NO.getCode()))))
	  {
		  //return false;
		  clvIn.setSpecialFactorIndicator(this.getLookupService().getIndicatorByCode(Indicator.NO));
	  }
	  else if(clvOn == null ||clvOn.getSpecialFactorIndicator()==null||((!clvOn.getSpecialFactorIndicator().getCode().equals(Indicator.YES.getCode())) && (!clvOn.getSpecialFactorIndicator().getCode().equals(Indicator.NO.getCode()))))
	  {
		  return false;
	  }
	  if((clvIn.getSpecialFactorIndicator()!=null && clvOn.getSpecialFactorIndicator()!=null) &&(!clvIn.getSpecialFactorIndicator().getCode().equals(clvOn.getSpecialFactorIndicator().getCode())))
	  {
		  return false;
	  }
	  /*else if(clvIn.getSpecialFactorIndicator()!=null && clvOn.getSpecialFactorIndicator()==null)
	  {
		  return false;
	  }
	  else if(clvIn.getSpecialFactorIndicator()==null && clvOn.getSpecialFactorIndicator()!=null)
	  {
		  return false;
	  }*/
	  if((clvIn.getChangeDate()!=null && clvOn.getChangeDate()!=null)&&clvIn.getChangeDate().compareTo(clvOn.getChangeDate())!=0)
	  {
		  return false;
	  }
	  else if(clvIn.getChangeDate()!=null && clvOn.getChangeDate()==null)
	   {
		  return false;
		}
	  else if(clvIn.getChangeDate()==null && clvOn.getChangeDate()!=null)
	   {
		  return false;
		}

	  if((clvIn.getComments()!=null && clvOn.getComments()!=null) &&(!clvIn.getComments().equals(clvOn.getComments())))
	  {
		  return false;
	  }
	  else if((clvIn.getComments()!=null && clvOn.getComments()==null))
	  {
		  return false;
	   }
	  else if((clvIn.getComments()==null && clvOn.getComments()!=null))
	  {
		  return false;
	  }
	  if(clvIn.getInternalCampLejeuneVerificationMethods().size()!=clvOn.getInternalCampLejeuneVerificationMethods().size())
	  {
		  return false;
	  }
	  for(CampLejeuneVerificationMethod clvmIn : clvIn.getInternalCampLejeuneVerificationMethods())
	  {

		  for(CampLejeuneVerificationMethod clvmOn : clvOn.getInternalCampLejeuneVerificationMethods())
		  {
			  if(clvmIn.getVerificationType().getCode().equals(clvmOn.getVerificationType().getCode()))
			  {
				  iSSame=true;
			  }
		  }
		  if(iSSame==false)
		  {
			  return false;
		  }
		  else
		  {
			  iSSame=false;
		  }
	  }
	  return true;
	  }
	  catch (Exception ex) {
          new RuleException("Indicator code NO not found", ex);
  	}
	  return true;
  }

    //CLV//

  public boolean isPersonJustAdded() {
	  return this.getIncomingPerson().isJustAdded();
  }

}