/*
 * Created on Feb 1, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package gov.va.med.esr.common.builder.comms;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import gov.va.med.esr.common.model.comms.CommsLogEntry;
import gov.va.med.esr.common.model.ee.EGTSetting;
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.financials.IncomeTest;
import gov.va.med.esr.common.model.financials.IncomeTestStatus;
import gov.va.med.esr.common.model.financials.IncomeThreshold;
import gov.va.med.esr.common.model.lookup.ComLetterTemplateType;
import gov.va.med.esr.common.model.lookup.IncomeTestType;
import gov.va.med.esr.common.model.lookup.MeansTestStatus;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.util.LetterFormatHelper;
import gov.va.med.esr.service.FinancialsHelperService;

public class EnrollTransmission extends GeneralTransmission {
	private boolean isEgtSet = false;

	private EnrollmentDetermination currentEnrollmentDetermination = null;
    
     //Commented unused method CR 8110
	//private EnrollmentDetermination priorEnrollmentDetermination = null;
    
    private String mostRecentNonNullPriorityLevel = null;

	private EGTSetting egt = null;

	private boolean isPrimaryVaFacilitySet = false;

	private boolean isPreferredFacilitySet = false;

	// --------------------------------------------------------------------
	// Constructor(s)
	// --------------------------------------------------------------------

	// / <summary>
	// / Creates a new EnrollmentTransmission object.
	// / </summary>

	// NEED this one for workflow when ready
	// public EnrollTransmission(Person veteran, WorkflowCase workflowCase)
	public EnrollTransmission(Person veteran, BigDecimal workflowCaseId) {
		super(veteran, null, workflowCaseId);
	}

	public EnrollTransmission() {
		super();
	}

	// --------------------------------------------------------------------
	// implement inherited method from super class- GeneralTransmissions
	// --------------------------------------------------------------------

	public boolean validate() {
		return super.validate();
	}

	public String externalizeAsXML() {
		return super.externalizeAsXml();
	}

	// --------------------------------------------------------------------
	// Properties
	// --------------------------------------------------------------------

	/*
	 * For Enrollment letters, SSN to use: The letter shall find SSN in the
	 * following order: SSA verified SSN (02) and site SSN (01). The letter
	 * shall use a pseudo SSN (03) automatically without user intervention if a
	 * SSN can not be found, The letter shall fail the rule
	 * 'isRequiredFieldsMissing()' if a pseudo SSN is still not found. The
	 * system shall not log the rule failure.
	 *
	 */
	public String getVeteranSsn() {
		veteranSsn = super.getVeteranSsn();
		if (veteranSsn != null)
			veteranSsn = FormatSSN(veteranSsn);
		else {
			// veteranSSN = GetVeteranOtherSSN();
			// TODO: since I don't know how to get other ssns for a person,
			// just get the pesudo ssn for now
			// veteranSsn = vet.getPseudoSsn(); //person no longer has pseudo
			// ssn
		}

		return getString(veteranSsn);
	}


	// / <summary>
	// / properties for TodaysDate + 14
	// / <\summary>
	public String getTodayPlus14() {
		if (todaysDatePlus14 == null)
			todaysDatePlus14 = LetterFormatHelper.addDays(todayDt, 14, sdf);
		return getString(todaysDatePlus14);
	}

	public void setTodayPlus14(String todayPlus14) {
		todaysDatePlus14 = todayPlus14;
	}

	// / <summary>
	// / properties for TodaysDate + 21
	// / <\summary>
	public String getTodayPlus21() {
		if (todaysDatePlus21 == null)
			todaysDatePlus21 = LetterFormatHelper.addDays(todayDt, 21, sdf);
		return getString(todaysDatePlus21);
	}

	public void setTodayPlus21(String todayPlus21) {
		todaysDatePlus21 = todayPlus21;
	}

	// / <summary>
	// / properties for TodaysDate + 30
	// / <\summary>
	public String getTodayPlus30() {
		if (todaysDatePlus30 == null)
			todaysDatePlus30 = LetterFormatHelper.addDays(todayDt, 30, sdf);
		return getString(todaysDatePlus30);
	}

	public void setTodayPlus30(String todayPlus30) {
		todaysDatePlus30 = todayPlus30;
	}

	// / <summary>
	// / properties for TodaysDate + 40
	// / <\summary>
	public String getTodayPlus40() {
		if (todaysDatePlus40 == null)
			todaysDatePlus40 = LetterFormatHelper.addDays(todayDt, 40, sdf);
		return getString(todaysDatePlus40);
	}

	public void setTodayPlus40(String todayPlus40) {
		todaysDatePlus40 = todayPlus40;
	}

	// / <summary>
	// / properties for TodaysDate + 60
	// / <\summary>
	public String getTodayPlus60() {
		if (todaysDatePlus60 == null)
			todaysDatePlus60 = LetterFormatHelper.addDays(todayDt, 60, sdf);
		return getString(todaysDatePlus60);
	}

	public void setTodayPlus60(String todayPlus60) {
		todaysDatePlus60 = todayPlus60;
	}

	// / <summary>
	// / properties for TodaysDate + 70
	// / <\summary>
	public String getTodayPlus70() {
		if (todaysDatePlus70 == null)
			todaysDatePlus70 = LetterFormatHelper.addDays(todayDt, 70, sdf);
		return getString(todaysDatePlus70);
	}

	public void setTodayPlus70(String todayPlus70) {
		todaysDatePlus70 = todayPlus70;
	}

	/*
	 * Letter Log Dates
	 */
	public String getLetter601C60DayDate() {
		if (letter601C60DayDate == null) {
			if (logs != null && logs.size() > 0) {
				CommsLogEntry entry = getLatestMailingEntryForForm(
						ComLetterTemplateType.FORM_NUMBER_601C.getCode(), logs);
				if (entry != null)
					letter601C60DayDate = LetterFormatHelper.addDays(entry
							.getModifiedOn(), 60, sdf);
			}
		}
		return getString(letter601C60DayDate);
	}

	public void setLetter601C60DayDate(String dt) {
		this.letter601C60DayDate = dt;
	}

	public String getLetter624A30DayDate() {
		if (letter624A30DayDate == null) {
			if (logs != null && logs.size() > 0) {
				CommsLogEntry entry = getLatestMailingEntryForForm(
						ComLetterTemplateType.FORM_NUMBER_624A.getCode(), logs);
				if (entry != null)
					letter624A30DayDate = LetterFormatHelper.addDays(entry
							.getModifiedOn(), 30, sdf);
			}
		}
		return getString(letter624A30DayDate);
	}

	public void setLetter624A30DayDate(String dt) {
		this.letter624A30DayDate = dt;
	}

	public String getLetter624A60DayDate() {
		if (letter624A60DayDate == null) {
			if (logs != null && logs.size() > 0) {
				CommsLogEntry entry = getLatestMailingEntryForForm(
						ComLetterTemplateType.FORM_NUMBER_624A.getCode(), logs);
				if (entry != null)
					letter624A60DayDate = LetterFormatHelper.addDays(entry
							.getModifiedOn(), 60, sdf);
			}
		}
		return getString(letter624A60DayDate);
	}

	public void setLetter624A60DayDate(String dt) {
		this.letter624A60DayDate = dt;
	}

	public String getLetter625A30DayDate() {
		if (letter625A30DayDate == null) {
			if (logs != null && logs.size() > 0) {
				CommsLogEntry entry = getLatestMailingEntryForForm(
						ComLetterTemplateType.FORM_NUMBER_625A.getCode(), logs);
				if (entry != null)
					letter625A30DayDate = LetterFormatHelper.addDays(entry
							.getModifiedOn(), 30, sdf);
			}
		}
		return getString(letter625A30DayDate);
	}

	public void setLetter625A30DayDate(String dt) {
		this.letter625A30DayDate = dt;
	}

	public String getLetter625A60DayDate() {
		if (letter625A60DayDate == null) {
			if (logs != null && logs.size() > 0) {
				CommsLogEntry entry = this.getLatestMailingEntryForForm(
						ComLetterTemplateType.FORM_NUMBER_625A.getCode(), logs);
				if (entry != null)
					letter625A60DayDate = LetterFormatHelper.addDays(entry
							.getModifiedOn(), 60, sdf);
			}
		}
		return getString(letter625A60DayDate);
	}

	public void setLetter625A60DayDate(String dt) {
		this.letter625A60DayDate = dt;
	}

	private CommsLogEntry getLatestMailingEntryForForm(String formNumber,
			List logLst) {
		if (formNumber == null || formNumber.length() == 0 || logLst == null
				|| logLst.size() == 0)
			return null;

		CommsLogEntry entry = null;

		for (int i = 0; i < logLst.size(); i++) {
			entry = (CommsLogEntry) logLst.get(i);
			if (entry.getFormNumber() != null
					&& entry.getFormNumber().equals(formNumber))
				return entry;
		}
		return null;
	}

	protected EnrollmentDetermination getCurrentEnrollmentDetermination() {
		if (vet == null)
			return null;
		if(this.currentEnrollmentDetermination == null)
			this.currentEnrollmentDetermination = vet.getEnrollmentDetermination();
		return this.currentEnrollmentDetermination;
	}

	/*
	 * For Enroll case, a workload case is not needed DEF-3083: but a rep can
	 * select a vet from workload screen. The workload id will be in session but
	 * no rep assigned to the vet. Must override base class to avoid throwing an
	 * exception in such situation
	 *
	 */

	/***************************************************************************
	 * Workload related: - workload status/activity code - Application User
	 * Phone number *
	 **************************************************************************/
	/*
	 * protected void setWorkloadRelatedProperties() { if (!isWorkloadSet)
	 * super.setWorkloadRelatedProperties(); if
	 * (this.getCurrentRepresentativeTelephone() == null) { //TODO: get phone
	 * number and name from the session /* AppUser appuser =
	 * workloadStatus.getAppUser(); currentRepPhoneNumber =
	 * appuser.getAppUserPhoneNumber(); currentRepresentative =
	 * appuser.getAppUserGivenName() + " " + appuser.getAppUserFamilyName();
	 */
	/*
	 * }
	 *
	 * isWorkloadSet = true; }
	 */

	// / <summary>
	// / effective change date
	// / </summary>
	public String getEffectiveChangeDate() {
		if (effectiveDateOfChange == null)
			if (getCurrentEnrollmentDetermination() != null
					&& currentEnrollmentDetermination.getEffectiveDate() != null)
				effectiveDateOfChange = sdf.format(currentEnrollmentDetermination
						.getEffectiveDate());
		return getString(effectiveDateOfChange);
	}

	public void setEffectiveChangeDate(String dt) {
		this.effectiveDateOfChange = dt;
	}

	private EGTSetting getEgt() {
		if (isEgtSet)
			return egt;

		if (getCurrentEnrollmentDetermination() != null)
			egt = getCurrentEnrollmentDetermination().getEgtSetting();

		isEgtSet = true;

		return egt;
	}

	public String getEgtEffectiveDate() {
		if (getEgt() != null)
			if (egt.getEffectiveDate() != null)
				return sdf.format(egt.getEffectiveDate());
			else {
				// egt is null, and egt has not been set, get it!
				if (!isEgtSet) {
					egt = getEgt();
					if (egt != null && egt.getEffectiveDate() != null)
						return sdf.format(egt.getEffectiveDate());
				}
			}
		return EMPTY_STRING;
	}

	public void setEgtEffectiveDate(String dt) {
		this.egtEffectiveDate = dt;
	}

	public String getEgtSetting() {
		// valid values: 1,2,3,4,5,6,7a,7c,8a,8c
		// old format: 1,2,3,4,5,6,7(a),7(c),8(a),8(c)
		if (egtSetting == null) {
			if (getEgt() != null) {
				String priority = egt.getPriorityGroup().getCode();
				if (priority != null && priority.length() > 0) {
					egtSetting = priority.replaceAll("0", "");
					if (egt.getPrioritySubGroup() != null) {
						String subGrpDesc = egt.getPrioritySubGroup()
								.getDescription();
						if (subGrpDesc != null && subGrpDesc.length() > 0)
							egtSetting += getSubGroupCode(subGrpDesc);
					}
				}
			}
		}
		return getString(egtSetting);
	}

	// return the alphebet code of priority sub-group code
	private String getSubGroupCode(String subGrpDesc) {
		// the description is like "Enrollment Priority sub-Group 'e'"
		// want to return just "e"
		// valid values are:a, c, g, e
		if(StringUtils.isBlank(subGrpDesc))
			return EMPTY_STRING;

		if(subGrpDesc.indexOf("'") > -1) {
			return subGrpDesc.substring(subGrpDesc.indexOf("'") + 1, subGrpDesc
					.indexOf("'") + 2);
		}

		return subGrpDesc;
	}

	public void setEgtSetting(String egtSetting) {
		this.egtSetting = egtSetting;
	}

	public String getEgtType() {
		if (egtType == null) {
			if (egt != null && egt.getType() != null)
				egtType = egt.getType().getName();
		}
		return getString(egtType);
	}

	public void setEgpType(String type) {
		this.egtType = type;
	}

	// / <summary>
	// / Eligibility table's ELIGIBLE_INDICATOR_CODE column
	// / </summary>
	public String getEligibilityCode() {
		if (eligibilityCode == null
				&& getCurrentEnrollmentDetermination() != null) {
			Eligibility elig = currentEnrollmentDetermination.getPrimaryEligibility();
			if (elig != null && elig.getType() != null)
				eligibilityCode = elig.getType().getCode();
		}
		return getString(eligibilityCode);
	}

	public void setEligibilityCode(String code) {
		eligibilityCode = code;
	}

	public String getEnrollmentApplicationDate() {
		if (enrollmentApplicationDate == null) {
			//
			if (vet.getApplication() != null
					&& vet.getApplication().getApplicationDate() != null)
				enrollmentApplicationDate = sdf.format(vet.getApplication()
						.getApplicationDate());
			/*
			 * OLD C# Code EligibilityFactors eligibilityFactors =
			 * EligibilityFactorsBroker.GetBrokerInstance().GetEligFactorsByIdWForeignKeys
			 * (VeteranEnrollment.ObjectId); if ( eligibilityFactors != null &&
			 * eligibilityFactors.EligibilityFactorForeignKeys != null ) {
			 * String applicationId =
			 * eligibilityFactors.EligibilityFactorForeignKeys.ApplicationId; if (
			 * applicationId != null && applicationId.Length > 0 )
			 * enrollmentApplicationDate =
			 * ((Application)ApplicationBroker.GetBrokerInstance
			 * ().GetObjectById (applicationId)).ApplicationDt.ToString
			 * (VHADateTimeFormat.MMSDDSYYYY); }
			 */
		}
		return getString(enrollmentApplicationDate);
	}

	public void setEnrollmentApplicationDate(String dt) {
		enrollmentApplicationDate = dt;
	}

	// / <summary>
	// / description of enrollment category code
	// / </summary> EnrollmentDetermination.getStatus().getEnrollmentCategory()

	public String getEnrollmentCategoryCode() {
		if (enrollmentCategoryCode == null) {
			if (getCurrentEnrollmentDetermination() != null
					&& currentEnrollmentDetermination != null
					&& currentEnrollmentDetermination.getEnrollmentStatus() != null)
				enrollmentCategoryCode = currentEnrollmentDetermination
						.getEnrollmentStatus().getCode();
			else
				enrollmentCategoryCode = EMPTY_STRING;
		}

		return enrollmentCategoryCode;

	}

	public void setEnrollmentCategoryCode(String code) {
		this.enrollmentCategoryCode = code;
	}

	public String getEnrollmentEndDate() {
		if (enrollmentEndDate == null) {
			if (getCurrentEnrollmentDetermination() != null
					&& currentEnrollmentDetermination.getEndDate() != null)
				enrollmentEndDate = sdf.format(currentEnrollmentDetermination
						.getEndDate());
		}
		return getString(enrollmentEndDate);
	}

	public void setEnrollmentEndDate(String dt) {
		enrollmentEndDate = dt;
	}

    /*** Commented unused method CR 8110
	public String getPriorEnrollmentPriorityLevel() {
		if(priorEnrollmentPriorityLevel != null) // cached
			return priorEnrollmentPriorityLevel;
		if(getPriorEnrollmentDetermination() == null)
			return getString(null);

		if(getPriorEnrollmentDetermination().getPriorityGroup() != null) {
			// note this uses SDS code
			priorEnrollmentPriorityLevel = getPriorEnrollmentDetermination().getPriorityGroup().getCode();
		}

		if(getPriorEnrollmentDetermination().getPrioritySubGroup() != null) {
			// note this uses SDS description
			priorEnrollmentPriorityLevel += getSubGroupCode(getPriorEnrollmentDetermination().getPrioritySubGroup().getDescription());
		}
		return getString(priorEnrollmentPriorityLevel);
	}
    ****/

	// / <summary>
	// / enrollment priority level
	// / </summary>
	public String getCurrentEnrollmentPriorityLevel() {
		if(currentEnrollmentPriorityLevel != null) // cached
			return currentEnrollmentPriorityLevel;
		if(getCurrentEnrollmentDetermination() == null)
			return getString(null);

		if(getCurrentEnrollmentDetermination().getPriorityGroup() != null) {
			// note this uses SDS code
			currentEnrollmentPriorityLevel = getCurrentEnrollmentDetermination().getPriorityGroup().getCode();
		}

		if(getCurrentEnrollmentDetermination().getPrioritySubGroup() != null) {
			// note this uses SDS description
			currentEnrollmentPriorityLevel += getSubGroupCode(getCurrentEnrollmentDetermination().getPrioritySubGroup().getDescription());
		}
		return getString(currentEnrollmentPriorityLevel);
	}

	// TODO: get VISN
	// / <summary>
	// / VeteranVISN: va reginal network where the prrferred facility belongs to
	// / using lookup table to find right facility based on
	// PreferredFacilityNumber
	// / </summary>
	public String getVisn() {

		/*
		 *
		 * get { if (vetVISN == null && PreferredFacilityNumber != null ) {
		 * vetVISN = facilities[PreferredFacilityNumber].VISN.ToString(); }
		 *
		 * return vetVISN; } set { this.vetVISN = value; }
		 */
		return EMPTY_STRING;
	}

	// / <summary>
	// / This year is used to determine copay rate, medical deductable, and
	// income year property threshold
	// / It's always current year -1
	// / </summary>
	public String getCurrentIncomeThresholdYear() {
		// current year -1
		if (currentIncomeThresholdYear == null)
			currentIncomeThresholdYear = getIncomeYear();

		return getString(currentIncomeThresholdYear);
	}

	public void setCurrentIncomeThresholdYear(String yr) {
		currentIncomeThresholdYear = yr;
	}

	/*
	 * IncomeThresholds related
	 */

	private IncomeTestStatus getIncomeTestStatus(String type,
			Set incomeTestStatuses) {
		if (type == null || incomeTestStatuses == null
				|| incomeTestStatuses.size() == 0)
			return null;

		IncomeTestStatus status = null;
		Iterator iter = incomeTestStatuses.iterator();
		while (iter.hasNext()) {
			status = (IncomeTestStatus) iter.next();
			if (status.getType().getCode().equals(type))
				return status;
		}

		return null;
	}

	public String getMTDateTimeCompleted() {
		if (mtDateTimeCompleted == null && getLocalIncomeTest() != null
				&& getLocalIncomeTest().getStatuses() != null) {
			// mtDateTimeCompleted = LocalIncomeTest.GS_CompletedDate.ToString
			// (VHADateTimeFormat.MMSDDSYYYY);
			// mtDateTimeCompleted = getLocalIncomeTest()
			IncomeTestStatus status = getIncomeTestStatus(
					IncomeTestType.CODE_MEANS_TEST.getCode(),
					getLocalIncomeTest().getStatuses());
			if (status != null && status.getCompletedDate() != null)
				mtDateTimeCompleted = sdf.format(status.getCompletedDate());
		}
		return getString(mtDateTimeCompleted);
	}

	public void setMTDateTimeCompleted(String value) {
		mtDateTimeCompleted = value;
	}

	private String getRxCopayRequiredText() {
		// if ( rxCopayRequiredText == null && LocalIncomeTest != null &&
		// localIncomeTest.GS_MeansTest != null)
		// rxCopayRequiredText = IncomeTest.TranslateFinancialTestStatus
		// (localIncomeTest.GS_MeansTest.GS_Status);
		if (rxCopayRequiredText == null && getLocalIncomeTest() != null)
			rxCopayRequiredText = getLocalIncomeTest()
					.getIncomeVerificationStatus().getDescription();

		return getString(rxCopayRequiredText);
	}

	private void setRxCopayRequiredText(String value) {
		rxCopayRequiredText = value;
	}

	private String getMTCopayRequiredText() {
		// if ( mtCopayRequiredText == null && LocalIncomeTest != null &&
		// localIncomeTest.GS_MeansTest != null )
		// mtCopayRequiredText = IncomeTest.TranslateFinancialTestStatus
		// (localIncomeTest.GS_MeansTest.GS_Status);
		if (mtCopayRequiredText == null && getLocalIncomeTest() != null)
			mtCopayRequiredText = getLocalIncomeTest()
					.getIncomeVerificationStatus().getDescription();

		return getString(mtCopayRequiredText);
	}

	private void setMTCopayRequiredText(String value) {
		mtCopayRequiredText = value;
	}

	private String getGMTCopayRequiredText() {
		if (gmtCopayRequiredText == null && getLocalIncomeTest() != null)
			// gmtCopayRequiredText = IncomeTest.TranslateFinancialTestStatus
			// (localIncomeTest.GS_MeansTest.GS_Status);
			gmtCopayRequiredText = getLocalIncomeTest()
					.getIncomeVerificationStatus().getDescription();

		return getString(gmtCopayRequiredText);
	}

	private void setGMTCopayRequiredText(String value) {
		gmtCopayRequiredText = value;
	}

	/***************************************************************************
	 * PimaryVACareFacility: the site that conducts the Means Test *
	 **************************************************************************/
	// / <summary>
	// / name of the site that conducts the Means Test.
	// / </summary>
	public String getPrimaryVACareFacilityName() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityName);
	}

	public void setPrimaryVACareFacilityName(String value) {
		primaryVACareFacilityName = value;
	}

	// / <summary>
	// / site number of the site that conducts the Means Test.
	// / </summary>
	public String getPrimaryVACareFacilityNumber() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityNumber);
	}

	public void setPrimaryVACareFacilityNumber(String value) {
		primaryVACareFacilityNumber = value;
	}

	private void initPrimaryVAFacility(IncomeTest incomeTest) {
		if (isPrimaryVaFacilitySet || isHistoricalCopy())
			return;

		if (incomeTest == null || incomeTest.getSiteConductingTest() == null) {
			isPrimaryVaFacilitySet = true;
			return;
		}

		VAFacility facility = incomeTest.getSiteConductingTest();

		primaryVACareFacilityName = facility.getName();
		primaryVACareFacilityNumber = facility.getStationNumber();

		VAFacility.VAFacilityAddress addr = facility.getStreetAddress();

		if (addr != null) {
			primaryVACareFacilityAddrLine1 = addr.getLine1();
			primaryVACareFacilityAddrLine2 = addr.getLine2();
			primaryVACareFacilityAddrCity = addr.getCity();
			primaryVACareFacilityAddrState = addr.getState().getCode();
			primaryVACareFacilityAddrZip = addr.getZipCode();
			primaryVACareFacilityAddrCountry = addr.getState().getCountry()
					.getShortName(); // or getCode()?

			// set the combined address lines
			if (primaryVACareFacilityAddrLine1 != null
					&& primaryVACareFacilityAddrLine1.length() > 0)
				primaryVACareFacilityAddr = primaryVACareFacilityAddrLine1;
			if (primaryVACareFacilityAddrLine2 != null
					&& primaryVACareFacilityAddrLine2.length() > 0)
				primaryVACareFacilityAddr += primaryVACareFacilityAddrLine2
						+ "\n";
			if (addr.getLine3() != null && addr.getLine3().length() > 0)
				primaryVACareFacilityAddr += addr.getLine3() + "\n";
		}
		isPrimaryVaFacilitySet = true;
	}

	/*
	 * PrimaryVACareFacilityAddress
	 */
	public String getPrimaryVACareFacilityAddr() {
		initPrimaryVAFacility(getLocalIncomeTest());
		return getString(primaryVACareFacilityAddr);
	}

	public void setPrimaryVACareFacilityAddr(String value) {
		primaryVACareFacilityAddr = value;
	}

	public String getPrimaryVACareFacilityAddrLine1() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrLine1);
	}

	public void setPrimaryVACareFacilityAddrLine1(String value) {
		primaryVACareFacilityAddrLine1 = value;
	}

	public String getPrimaryVACareFacilityAddrLine2() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrLine2);
	}

	public void setPrimaryVACareFacilityAddrLine2(String value) {
		primaryVACareFacilityAddrLine2 = value;
	}

	public String getPrimaryVACareFacilityAddrCity() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrCity);
	}

	public void setPrimaryVACareFacilityAddrCity(String value) {
		primaryVACareFacilityAddrCity = value;
	}

	public String getPrimaryVACareFacilityAddrState() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrState);
	}

	public void setPrimaryVACareFacilityAddrState(String value) {
		primaryVACareFacilityAddrState = value;
	}

	public String getPrimaryVACareFacilityAddrZip() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrZip);
	}

	public void setPrimaryVACareFacilityAddrZip(String value) {
		primaryVACareFacilityAddrZip = value;
	}

	public String getPrimaryVACareFacilityAddrCountry() {
		initPrimaryVAFacility(getLocalIncomeTest());

		return getString(primaryVACareFacilityAddrCountry);
	}

	public void setPrimaryVACareFacilityAddrCountry(String value) {
		primaryVACareFacilityAddrCountry = value;
	}

	/***************************************************************************
	 * PreferredFacility related properties *
	 **************************************************************************/
	// / <summary>
	// / ???
	// / Veteran Preferred Facility Name
	// / </summary>
	public String getPreferredFacility() {
		initPreferredFacility(vet);

		return getString(preferredFacility);
	}

	public void setPreferredFacility(String facility) {
		this.preferredFacility = facility;
	}

	// / <summary>
	// / Preferred facility number
	// / </summary>
	public String getPreferredFacilityNumber() {
		initPreferredFacility(vet);

		return getString(preferredFacilityNumber);

	}

	public void setPreferredFacilityNumber(String num) {
		preferredFacilityNumber = num;
	}

	private void initPreferredFacility(Person person) {
		if (isPreferredFacilitySet || isHistoricalCopy() || person == null)
			return;

		VAFacility facility = person.getMostRecentPreferredFacility();

		if (facility == null) {
			isPreferredFacilitySet = true;
			return;
		}

		preferredFacility = facility.getName(); // set the name
		preferredFacilityNumber = facility.getStationNumber(); // set the
																// number

		// ArrayList addrLst = new ArrayList();

		// no need for I3: get facility address
		/*
		 * Set contacts = facility.getContactMethods();
		 *
		 * if( contacts != null ) { for( Iterator i=contacts.iterator();
		 * i.hasNext(); ) { Object contactObj = i.next(); if (contactObj
		 * instanceof Address) addrLst.add(contactObj); } }
		 *
		 * Address addrToUse =
		 * gov.va.med.esr.comms.common.MailingAddressHelper.selectAddressForMailing(addrLst);
		 *
		 * if (addrToUse != null) { preferredFacilityAddrLine1 =
		 * addrToUse.getLine1(); preferredFacilityAddrLine2 =
		 * addrToUse.getLine2(); preferredFacilityAddrCity =
		 * addrToUse.getCity(); preferredFacilityAddrState =
		 * addrToUse.getPostalCode(); preferredFacilityAddrZip =
		 * addrToUse.getZipCode(); preferredFacilityAddrCountry =
		 * addrToUse.getCountry();
		 *
		 * //set the combined address lines if (preferredFacilityAddrLine1 !=
		 * null && preferredFacility.length() > 0) preferredFacilityAddr =
		 * preferredFacilityAddrLine1; if (preferredFacilityAddrLine2 != null &&
		 * preferredFacilityAddrLine2.length() > 0) preferredFacilityAddr +=
		 * preferredFacilityAddrLine2 + "\n"; if (addrToUse.getLine3() != null &&
		 * addrToUse.getLine3().length() > 0) preferredFacilityAddr +=
		 * addrToUse.getLine3() + "\n"; }
		 */
		isPreferredFacilitySet = true;

	}

	public String getPreferredFacilityAddr() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddr);
	}

	public void setPreferredFacilityAddr(String value) {
		preferredFacilityAddr = value;
	}

	public String getPreferredFacilityAddrLine1() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrLine1);
	}

	public void setPreferredFacilityAddrLine1(String value) {
		preferredFacilityAddrLine1 = value;
	}

	public String getPreferredFacilityAddrLine2() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrLine2);
	}

	public void setPreferredFacilityAddrLine2(String value) {
		preferredFacilityAddrLine2 = value;
	}

	public String getPreferredFacilityAddrCity() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrCity);
	}

	public void setPreferredFacilityAddrCity(String value) {
		preferredFacilityAddrCity = value;
	}

	public String getPreferredFacilityAddrState() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrState);
	}

	public void setPreferredFacilityAddrState(String value) {
		preferredFacilityAddrState = value;
	}

	public String getPreferredFacilityAddrZip() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrZip);
	}

	public void setPreferredFacilityAddrZip(String value) {
		preferredFacilityAddrZip = value;
	}

	public String getPreferredFacilityAddrCountry() {
		initPreferredFacility(vet);

		return getString(preferredFacilityAddrCountry);
	}

	public void setPreferredFacilityAddrCountry(String value) {
		preferredFacilityAddrCountry = value;
	}

	public boolean isRxCopayNonExempt() {
		if (this.isHistoricalCopy())
			return isRxCopayNonExempt;

		return isIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST, MeansTestStatus.MT_STATUS_NON_EXEMPT);
	}

	public void setRxCopayNonExempt(boolean value) {
		isRxCopayNonExempt = value;
	}

	public boolean isMTCopayRequired() {
		if (this.isHistoricalCopy())
			return isMTCopayRequired;

		boolean result = isIncomeTestStatus(IncomeTestType.CODE_MEANS_TEST,  MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED);
		if(!result) {
			// last check....see if Pending rules apply
			if(this.isIncomeTestStatus(IncomeTestType.CODE_MEANS_TEST, MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION) &&
					this.getLocalIncomeTest() != null &&
					this.getLocalIncomeTest().getGmtThresholdAmount() != null &&
					this.getLocalIncomeTest().getThresholdA() != null &&
					this.getLocalIncomeTest().getGmtThresholdAmount().doubleValue() <= this.getLocalIncomeTest().getThresholdA().doubleValue())
				result = true;
		}
		return result;
	}

	public void setMTCopayRequired(boolean value) {
		isMTCopayRequired = value;
	}

	public void setGMTCopayRequired(boolean value) {
		isGMTCopayRequired = value;
	}

	public boolean isGMTCopayRequired() {
		if (this.isHistoricalCopy())
			return isGMTCopayRequired;

		boolean result = isIncomeTestStatus(IncomeTestType.CODE_MEANS_TEST, MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED);
		if(!result) {
			// last check....see if Pending rules apply
			if(this.isIncomeTestStatus(IncomeTestType.CODE_MEANS_TEST, MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION) &&
					this.getLocalIncomeTest() != null &&
					this.getLocalIncomeTest().getGmtThresholdAmount() != null &&
					this.getLocalIncomeTest().getThresholdA() != null &&
					this.getLocalIncomeTest().getGmtThresholdAmount().doubleValue() > this.getLocalIncomeTest().getThresholdA().doubleValue())
				result = true;
		}
		return result;
	}

	private boolean isIncomeTestStatus(IncomeTestType.Code itType, MeansTestStatus.Code meansTestStatus) {
		boolean result = false;

		IncomeTest target = getLocalIncomeTest();
		if(target != null && itType != null && meansTestStatus != null) {
			IncomeTestStatus status = target.getIncomeTestStatus(itType);
			if(status != null && status.getStatus() != null && status.getStatus().getCode().equals(meansTestStatus.getCode()))
				result = true;
		}
		return result;
	}

	// / <summary>
	// / ???
	// / </summary>
	// TODO: veteran psuedo ssn, or move to subclass
	/*
	 * public String getVeteranPseudoSSN() {
	 *
	 * if (veteranPseudoSSN == null) { SSNBroker ssnBkr =
	 * SSNBroker.GetBrokerInstance(); ICollection pseudoSSNs =
	 * ssnBkr.GetVeteranSsnByType(vetId, SSN.SSN_TYPE_PSEUDO_SSN); if
	 * (pseudoSSNs != null && pseudoSSNs.Count > 0) { String ssnNum = null;
	 * foreach (SSN ssn in pseudoSSNs) { ssnNum = ssn.Ssn; if (ssnNum != null &&
	 * ssnNum.Length > 0) { veteranPseudoSSN = ssnNum; break; } } } }
	 *
	 * return veteranPseudoSSN; } public void setVeteranPseudoSSN(String psuSSN) {
	 * veteranPseudoSSN = psuSSN; }
	 */
	// / <summary>
	// / local use only
	// / </summary>

	public IncomeTest getLocalIncomeTest() {
		if (isIncomeTestSet || isHistoricalCopy() || vet == null)
			return localIncomeTest;

		localIncomeTest = vet.getIncomeTest(new Integer(this.getIncomeYear()));
		isIncomeTestSet = true;

		return localIncomeTest;
	}

	public void setLocalIncomeTest(IncomeTest incomeTest) {
		isIncomeTestSet = true;

		if(incomeTest == null) {
			localIncomeTest = null;
			setIncomeYear(null);
		} else {
			localIncomeTest = incomeTest;
			setIncomeYear(incomeTest.getIncomeYear() != null ? incomeTest.getIncomeYear().toString() : null);
		}
	}

	private IncomeThreshold getIncomeThreshold() {

		return this.incomeThreshold;
	}

	public void setIncomeThreshold(IncomeThreshold incomeThreshold) {

		this.incomeThreshold = incomeThreshold;
	}

	public String getMedicationCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getMedicationCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getFirst90daysHospitalCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getNinetyDayHospitalCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getAdditional90DaysHospitalCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getAdd90DayHospitalDeductible(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getOutpatientPreventiveCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getOutpatientPreventiveCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getGmtInpatientFirst90DayCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getGmtInpatient90DayCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getGmtInpatientAdd90DayCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getGmtInpatientAdd90DayCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getGmtPerDiem() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getGmtInpatientPerDiem(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getOutpatientCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getOutpatientCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getInpatientPerDiem() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getInpatientPerDiem(), 2, BigDecimal.ROUND_DOWN);
	}

	public String getSpecialCopay() {
		if (incomeThreshold == null)
			return "";

		return LetterFormatHelper.ToDollarAmount(incomeThreshold
				.getOutpatientSpecialtyCopay(), 2, BigDecimal.ROUND_DOWN);
	}

	/*
	 * protected IncomeThreshold getLocalIncomeThresholds() { if
	 * (localIncomeThresholds == null && CurrentIncomeThresholdYear != null &&
	 * !isHistoricalCopy()) localIncomeThresholds =
	 * (IncomeThreshold)IncomeThresholdBroker.GetBrokerInstance ().GetObjectById
	 * (CurrentIncomeThresholdYear); return localIncomeThresholds; }
	 */

	// provide function for fiscal year.
	// if 10/1/currentYear <= currentYear < 01/01/(currentYear+1) then
	// fiscalYear = currentYear + 1;
	// else
	// fiscalYear = currentYear;
	private int getCurrentFiscalYear() {
		Date today = new Date();
		int currentFiscalYear = cal.get(GregorianCalendar.YEAR);
		Date date1 = new GregorianCalendar(currentFiscalYear, Calendar.OCTOBER,
				1).getTime();// Oct First, current year
		Date date2 = new GregorianCalendar(currentFiscalYear + 1,
				Calendar.JANUARY, 1).getTime();// Jan First, next year

		if (today.compareTo(date1) >= 0 && today.compareTo(date2) < 0)
			currentFiscalYear += 1;
		return currentFiscalYear;
	}

	private EGTSetting getLocalEgtSetting() {
		if (localEgtSetting == null && !isHistoricalCopy()
				&& getCurrentEnrollmentDetermination() != null)
			localEgtSetting = getCurrentEnrollmentDetermination()
					.getEgtSetting();
		return localEgtSetting;
	}

	/**
	 * @return Returns the financialsHelperService.
	 */
	public FinancialsHelperService getFinancialsHelperService() {
		return financialsHelperService;
	}

	/**
	 * @param financialsHelperService
	 *            The financialsHelperService to set.
	 */
	public void setFinancialsHelperService(
			FinancialsHelperService financialsHelperService) {
		this.financialsHelperService = financialsHelperService;
	}


	// --------------------------------------------------------------------
	// Non-static attributes
	// --------------------------------------------------------------------

	private EGTSetting localEgtSetting;

	// private VHA.Enrollment.Business.Person.EligibilityEnrollment.Enrollment
	// veteranEnrollment;

	// private IncomeThreshold localIncomeThresholds;
	private IncomeTest localIncomeTest;

	private Address localPimaryVAFacilityAddress;

	private Address localPreferredFacilityAddress;

	private String todaysDatePlus14;

	private String todaysDatePlus21;

	private String todaysDatePlus30;

	private String todaysDatePlus40;

	private String todaysDatePlus60;

	private String todaysDatePlus70;

	// letter days
	private String letter601C60DayDate;

	private String letter624A30DayDate;

	private String letter624A60DayDate;

	private String letter625A30DayDate;

	private String letter625A60DayDate;

	private String effectiveDateOfChange;

	private String egtEffectiveDate;

	private String egtType;

	private String egtSetting;

	private String eligibilityCode;

	private String enrollmentApplicationDate;

	private String enrollmentCategoryCode;

	private String enrollmentEndDate;

	private String currentEnrollmentPriorityLevel;
	private String priorEnrollmentPriorityLevel;

	private String veteranErrorMessage;

	private String rxCopayRequiredText;

	private String gmtCopayRequiredText;

	private String mtCopayRequiredText;

	private String mtDateTimeCompleted;

	private String primaryVACareFacilityNumber = null;

	// / <summary>
	// / finance information
	// / </summary>
	// private String calculatedAs20PctDeductible;
	// private String calculatedAs20PctAdditional90DaysHospitalDeductable;
	// private String calculatedAs20Pct90DaysHospitalCopay;

	private IncomeThreshold incomeThreshold;

	private String currentIncomeThresholdYear;

	private String specialCopay;

	private String primiaryCopay;

	private String additional90DaysHospitalCopay;

	private String additional90DaysHospitalMedicareDeductible;

	private String medicareDeductible;

	private String additional90DaysHospitalCopay_20percent;

	private String additional90DaysHospitalMedicareDeductible_20percent;

	private String medicareDeductible_20percent;

	private String rxCopayRate;

	private String incomeYearPropertyThreshold;

	private String primaryVACareFacilityAddrLine1;

	private String primaryVACareFacilityAddrLine2;

	private String primaryVACareFacilityAddrCity;

	private String primaryVACareFacilityAddrState;

	private String primaryVACareFacilityAddrZip;

	private String primaryVACareFacilityAddrCountry;

	private String primaryVACareFacilityAddr;

	private String primaryVACareFacilityName;

	private String preferredFacilityAddrLine1;

	private String preferredFacilityAddrLine2;

	private String preferredFacilityAddrCity;

	private String preferredFacilityAddrState;

	private String preferredFacilityAddrZip;

	private String preferredFacilityAddrCountry;

	private String preferredFacility;

	private String preferredFacilityNumber;

	private String preferredFacilityAddr;

	private FinancialsHelperService financialsHelperService;

	// / <summary>
	// / rule information
	// / </summary>
	/*
	 * private EligibilityEntry eligibilityEntry = null; private EnrollmentEntry
	 * enrollmentEntry = null; private MeansTestEntry meansTestEntry = null;
	 * private PurpleHeartEntry purpleHeartEntry = null; private
	 * PriorityLevelEntry priorityLevelEntry = null;
	 */
	// for historical RX, MT, GMT copay required texts
	private boolean isIncomeTestSet = false;

	private boolean isRxCopayNonExempt;

	private boolean isMTCopayRequired;

	private boolean isGMTCopayRequired;

	/**
	 * @return Returns the priorEnrollmentDetermination.
	 */
    
    /*** Commented unused method CR 8110
	public EnrollmentDetermination getPriorEnrollmentDetermination() {
		return priorEnrollmentDetermination;
	}
    ***/

	/**
	 * @param priorEnrollmentDetermination The priorEnrollmentDetermination to set.
	 */
    
    /** Commented unused method CR 8110
	public void setPriorEnrollmentDetermination(
			EnrollmentDetermination priorEnrollmentDetermination) {
		this.priorEnrollmentDetermination = priorEnrollmentDetermination;
	}
    ****/

	/**
	 * @param currentEnrollmentDetermination The currentEnrollmentDetermination to set.
	 */
	public void setCurrentEnrollmentDetermination(
			EnrollmentDetermination currentEnrollmentDetermination) {
		this.currentEnrollmentDetermination = currentEnrollmentDetermination;
	}

    public String getMostRecentNonNullPriorityLevel() {
        return mostRecentNonNullPriorityLevel;
    }

    public void setMostRecentNonNullPriorityLevel(
            String mostRecentNonNullPriorityLevel) {
        this.mostRecentNonNullPriorityLevel = mostRecentNonNullPriorityLevel;
    }
}
