package gov.va.med.esr.common.model.person;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;

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.lookup.ApplicationMethod;
import gov.va.med.esr.common.model.lookup.ApplicationStatus;
import gov.va.med.esr.common.model.lookup.Gender;
import gov.va.med.esr.common.model.lookup.SelfIdentifiedGenderIdentity;
import gov.va.med.fw.model.AbstractKeyedEntity;

public class EnrollmentApplication extends AbstractKeyedEntity {

	/**
	 * New class or Add a Person. Corresponds to the database table Enrollment_Application
	 */
	private static final long serialVersionUID = -1438723888583757286L;

	private ApplicationMethod applicationMethod;
	private ApplicationStatus applicationStatus;
	private BigDecimal personId;
	private Date applicationDate;
	private Date signatureDate;
	private String lastName;
	private String firstName;
	private String middleName;
	private Date dateOfBirth;
	private String ssn;
	private Gender gender = null;
	private SelfIdentifiedGenderIdentity sigi = null;
	private String icn;
	private Set internalApplicationInProcesses = null;

    private int hashValue = 0;

	public EnrollmentApplication() {
		super();
	}

	public Date getApplicationDate() {
		return applicationDate;
	}

	public void setApplicationDate(Date applicationDate) {
		this.applicationDate = applicationDate;
	}

	public ApplicationMethod getApplicationMethod() {
		return applicationMethod;
	}

	public void setApplicationMethod(ApplicationMethod applicationMethod) {
		this.applicationMethod = applicationMethod;
	}

	public ApplicationStatus getApplicationStatus() {
		return applicationStatus;
	}

	public void setApplicationStatus(ApplicationStatus applicationStatus) {
		this.applicationStatus = applicationStatus;
	}

	public String getIcn() {
		return icn;
	}

	public void setIcn(String icn) {
		this.icn = icn;
	}

	public Date getDateOfBirth() {
		return dateOfBirth;
	}
	public void setDateOfBirth(Date dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public Gender getGender() {
		return gender;
	}

	public SelfIdentifiedGenderIdentity getSigi() {
		return sigi;
	}

	public void setSigi(SelfIdentifiedGenderIdentity sigi) {
		this.sigi = sigi;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}
	public BigDecimal getPersonId() {
		return this.personId;
	}

	public void setPersonId(BigDecimal personId) {
		this.personId = personId;
	}

	public Date getSignatureDate() {
		return signatureDate;
	}

	public void setSignatureDate(Date signatureDate) {
		this.signatureDate = signatureDate;
	}

	public String getSsn() {
		return ssn;
	}

	public void setSsn(String ssn) {
		this.ssn = ssn;
	}


	   private Set getInternalApplicationInProcesses() {
	      if( internalApplicationInProcesses == null ) {
	         this.internalApplicationInProcesses = new HashSet();
	      }
	      return this.internalApplicationInProcesses;
	   }

	   private void setInternalApplicationInProcesses(Set internalApplicationInProcesses) {
	      this.internalApplicationInProcesses = internalApplicationInProcesses;
	   }

	   public ApplicationInProcess getApplicationInProcess() {
	      Set aips = getInternalApplicationInProcesses();
	      if( aips.size() > 0 ) {
	         return (ApplicationInProcess)aips.iterator().next();
	      }
	      return null;
	   }

	   public void setApplicationInProcess(ApplicationInProcess applicationInProcess) {
	      Set aips = getInternalApplicationInProcesses();
	      aips.clear();
	      if( applicationInProcess != null ) {
	         aips.add(applicationInProcess);
	         applicationInProcess.setEnrollmentApplication(this);
	      }
	   }


	   public boolean equals(Object rhs)
	   {

	       if (rhs == null)
	           return false;
	       if (rhs == this)
	    	   return true;
	       if (rhs.getClass() != getClass())
	           return false;


	       EnrollmentApplication that = (EnrollmentApplication) rhs;
	       if (isEqual(this.getIdentifier(), that.getIdentifier()) &&
	    		   isEqual(this.icn,that.icn) &&
	    		   isEqual(this.ssn,that.ssn) &&
	    		   isEqual(this.personId,that.personId) &&
	    		   isEqual(this.applicationStatus,that.applicationStatus)  &&
	    		   isEqual(this.internalApplicationInProcesses,that.internalApplicationInProcesses))
	       {
	           return true;
	       }

	       return false;
	   }

	   private boolean isEqual(Object a, Object b)
	   {
		   if (a == null)
		   {
			   return (b == null) ? true : false;
		   } else
		   {
			   return (b == null) ? false : a.equals(b);
		   }
	   }

	   /**
	    * Implementation of the hashCode method conforming to the Bloch pattern with
	    * the exception of array properties (these are very unlikely primary key types).
	    * @return int
	    */
	   public int hashCode()
	   {
	       if (this.hashValue == 0)
	       {
	           int result = 17;
	           int idValue = this.getIdentifier() == null ? 0 : this.getIdentifier().hashCode();
	           result = result * 37 + idValue;
	           result = result * 37 + this.icn.hashCode();
	           result = result * 37 + this.ssn.hashCode();
	           if (this.personId != null)
	           {
	        	   result = result * 37 + personId.hashCode();
	           }
	           result = result * 37 + this.applicationStatus.hashCode();
	           if (this.internalApplicationInProcesses != null)
	           {
	        	   result = result * 37 + internalApplicationInProcesses.hashCode();
	           }
	           this.hashValue = result;
	       }
	       return this.hashValue;
	   }


	/*
	 * (non-Javadoc)
	 *
	 * @see gov.va.med.fw.model.AbstractKeyedEntity#buildToString(org.apache.commons.lang.builder.ToStringBuilder)
	 */
	protected void buildToString(ToStringBuilder builder) {
		super.buildToString(builder);
		builder.append("applicationMethod", this.applicationMethod);
		builder.append("applicationStatus", this.applicationStatus);
		builder.append("personId",this.personId);
		builder.append("applicationDate", this.applicationDate);
		builder.append("signatureDate",this.signatureDate);
		builder.append("lastName",	this.lastName);
		builder.append("firstName",	this.firstName);
		builder.append("middleName",	this.middleName);
		builder.append("dateOfBirth",	this.dateOfBirth);
		builder.append("ssn",	this.ssn);
		builder.append("gender",	this.gender);
	}

}
