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

import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

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

import gov.va.med.fw.model.AbstractKeyedEntity;
import gov.va.med.fw.model.EntityKey;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.person.Person;

/**
 * @author Commons Team
 * @version 1.0
 */
public class ServiceConnectionAward extends AbstractKeyedEntity {
	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 4493255598010884931L;

	private Person person = null;

	/**
	 * SC Percent is defined as the combined service-connected percentage. Field
	 * may not be deleted as long as service connection is indicated and rated
	 * disabilities exist.
	 */
	private Integer serviceConnectedPercentage = null;

	/**
	 * ServiceConnected Indicator is defined as a code that indicates if this patient
	 * has award for service connect by the VARO due to a service connected condition
	 */
	private Boolean serviceConnectedIndicator = null;

	private ImpreciseDate combinedServiceConnectedPercentageEffectiveDate;

	/**
	 * Unemployable Indicator is defined as a code that indicates if this patient
	 * is rated unemployable by the VARO due to a service connected condition
	 */
	private Boolean unemployable = null;

	/**
	 * Permanent & Total Indicator is defined as a code that indicates if the
	 * patient is permanently and totally disabled determined by VARO due to a
	 * service-connected condition.
	 */
	private Boolean permanentAndTotal = null;

	private Date permanentAndTotalEffectiveDate = null;

	private ImpreciseDate awardDate = null;

	private Set internalRatedDisabilities = null;

	/**
	 * Creates a new ServiceConnectionAward object.
	 */
	public ServiceConnectionAward() {
		super();
	}
	
	public void initDefaults() {
		serviceConnectedIndicator = Boolean.FALSE;
	}

	public Person getPerson() {
		return this.person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

	public Integer getServiceConnectedPercentage() {
		return this.serviceConnectedPercentage;
	}

	public void setServiceConnectedPercentage(Integer serviceConnectedPercentage) {
		this.serviceConnectedPercentage = serviceConnectedPercentage;
	}

	public Boolean getServiceConnectedIndicator() {
		return this.serviceConnectedIndicator;
	}

	public void setServiceConnectedIndicator(Boolean serviceConnectedIndicator) {
		this.serviceConnectedIndicator = serviceConnectedIndicator;
	}

	public ImpreciseDate getCombinedServiceConnectedPercentageEffectiveDate() {
		return this.combinedServiceConnectedPercentageEffectiveDate;
	}

	public void setCombinedServiceConnectedPercentageEffectiveDate(ImpreciseDate date) {
		this.combinedServiceConnectedPercentageEffectiveDate = date;
	}

	public Boolean isUnemployable() {
		return this.unemployable;
	}

	// For copy service
	public Boolean getUnemployable() {
		return this.unemployable;
	}

	public void setUnemployable(Boolean unemployable) {
		this.unemployable = unemployable;
	}

	public Boolean isPermanentAndTotal() {
		return this.permanentAndTotal;
	}

	// For copy service
	public Boolean getPermanentAndTotal() {
		return this.permanentAndTotal;
	}

	public void setPermanentAndTotal(Boolean permanentAndTotal) {
		this.permanentAndTotal = permanentAndTotal;
	}

	public ImpreciseDate getAwardDate() {
		return this.awardDate;
	}

	public void setAwardDate(ImpreciseDate scAwardDate) {
		this.awardDate = scAwardDate;
	}

	/**
	 * @return Returns the permanentAndTotalEffectiveDate.
	 */
	public Date getPermanentAndTotalEffectiveDate() {
		return permanentAndTotalEffectiveDate;
	}

	/**
	 * @param permanentAndTotalEffectiveDate
	 *           The permanentAndTotalEffectiveDate to set.
	 */
	public void setPermanentAndTotalEffectiveDate(
			Date permanentAndTotalEffectiveDate) {
		this.permanentAndTotalEffectiveDate = permanentAndTotalEffectiveDate;
	}

	private Set getInternalRatedDisabilities() {
		if (internalRatedDisabilities == null) {
			this.internalRatedDisabilities = new HashSet();
		}
		return this.internalRatedDisabilities;
	}

	private void setInternalRatedDisabilities(Set internalRatedDisabilities) {
		this.internalRatedDisabilities = internalRatedDisabilities;
	}

	public Set getRatedDisabilities() {
		return Collections.unmodifiableSet(getInternalRatedDisabilities());
	}

	public RatedDisability getRatedDisabilityByEntityKey(EntityKey identifier) {
		return (RatedDisability) getEntityByEntityKey(getRatedDisabilities(),
				identifier);
	}

	public void addRatedDisability(RatedDisability ratedDisability) {
		Validate.notNull(ratedDisability, "Null RatedDisability not allowed.");
		getInternalRatedDisabilities().add(ratedDisability);
		ratedDisability.setServiceConnectionAward(this);
	}

	public void removeRatedDisability(RatedDisability ratedDisability) {
		Validate.notNull(ratedDisability, "Null RatedDisability not allowed.");
		this.getInternalRatedDisabilities().remove(ratedDisability);
		ratedDisability.setServiceConnectionAward(null);
	}

	public RatedDisability removeRatedDisabilityByEntityKey(EntityKey identifier) {
		Validate.notNull(identifier, "Null EntityKey not allowed.");
		return (RatedDisability) removeEntityByEntityKey(
				getInternalRatedDisabilities(), identifier);
	}

	public void removeAllRatedDisability() {
		this.getInternalRatedDisabilities().clear();
	}
   
   public void addAllRatedDisability( Set disabilities ) {
      
      Iterator i = disabilities != null ? disabilities.iterator() : null;
      if (i != null) {
	      while( i.hasNext() ) {
	         Object record = i.next();
	         if( record instanceof RatedDisability ) {
	             this.addRatedDisability( (RatedDisability)record );
	         }
	      }
      }
   }

	/*
	 * (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("serviceConnectedPercentage",
				this.serviceConnectedPercentage);
		builder.append("serviceConnectedIndicator", this.serviceConnectedIndicator);
		builder.append("unemployable", this.unemployable);
		builder.append("permanentAndTotal", this.permanentAndTotal);
		builder.append("awardDate", this.awardDate);
		builder.append("permanentAndTotalEffectiveDate",
				this.permanentAndTotalEffectiveDate);

	}
}