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


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.VAFacility;

import java.util.Date;

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

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


import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.fw.util.StringUtils;

public class CampLejeuneVerification extends SpecialFactor {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2578203019462583585L;


	
    private CampLejeuneChangeSource   changeSource;
    private VAFacility         changeSite;
    private Set<CampLejeuneVerificationMethod> internalCampLejeuneVerificationMethods	= null;  
    private CampLejeuneVerificationType	verificationType;  //  TODO Delete verificationType: CAMP LEJEUNE Multiple Selection of Verification Methods	
    private String comments;
    private Date changeDate_h;
    
    
	/**
	 * Creates a new CampLejeuneVerification object.
	 */
	public CampLejeuneVerification() {
		super();
		changeDate_h = new Date();
	}

	// ----------------------------------------------------------------------------
	// Public method(s)
	// ----------------------------------------------------------------------------
	

    
	public CampLejeuneChangeSource getChangeSource() {
		return changeSource;
	}

	public void setChangeSource(CampLejeuneChangeSource changeSource) {
		this.changeSource = changeSource;
	}

	public VAFacility getChangeSite() {
		return changeSite;
	}

	public void setChangeSite(VAFacility changeSite) {
		this.changeSite = changeSite;
	}

	
	public CampLejeuneVerificationType getVerificationType() {
		return verificationType;
	}

	public void setVerificationType(CampLejeuneVerificationType verificationType) {
		this.verificationType = verificationType;
	}  

		
	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}
	
	public Date getChangeDate() {
		if(this.getRegistrationDate()!= null)
		{
			return this.getRegistrationDate().getDate();
		}
		else
			return null;
	}

	public void setChangeDate(Date changeDate) {
		if(changeDate!=null)
		{
			this.setRegistrationDate(new ImpreciseDate(changeDate));
			this.changeDate_h=changeDate;
		}
	}
	
	public Set<CampLejeuneVerificationMethod> getInternalCampLejeuneVerificationMethods() {
		if (internalCampLejeuneVerificationMethods == null)
			internalCampLejeuneVerificationMethods = new HashSet();
		
		return internalCampLejeuneVerificationMethods;
	}

	public void setInternalCampLejeuneVerificationMethods(
			Set<CampLejeuneVerificationMethod> internalCampLejeuneVerificationMethods) {
		this.internalCampLejeuneVerificationMethods = internalCampLejeuneVerificationMethods;
	}

  /**
	 * Unmodifiable
	 * 
	 * @return
	 */
	// TODO CAMP LEJEUNE Multiple Selection of Verification Methods	
	public Set<CampLejeuneVerificationMethod> getCampLejeuneVerificationMethods() {
		return Collections.unmodifiableSet(getInternalCampLejeuneVerificationMethods());
	}
	


	public void addCampLejeuneVerificationMethod(CampLejeuneVerificationMethod method) {
		Validate.notNull(method, "CampLejeuneVerificationMethod cannot be null");
        //If it already exists do not add
        if (getCampLejeuneMethodByType(method.getVerificationType()) == null) {
        	//setSpecialFactor(this) before add to the set, 
        	//to avoid stack overflow error
        	method.setSpecialFactor(this);
        	 getInternalCampLejeuneVerificationMethods().add(method);          
        }
	}

	
    
    public CampLejeuneVerificationMethod getCampLejeuneMethodByType(CampLejeuneVerificationType methodType) {
        Validate.notNull(methodType,"CampLejeuneVerificationType cannot be null");
        return getCampLejeuneMethodByType(methodType.getCode());
    }
    
    public CampLejeuneVerificationMethod getCampLejeuneMethodByType(String typeCode) {
        if(StringUtils.isNotEmpty(typeCode)) {
            for(Iterator<CampLejeuneVerificationMethod> iter= getInternalCampLejeuneVerificationMethods().iterator(); iter.hasNext();) {
            	CampLejeuneVerificationMethod clMethod = (CampLejeuneVerificationMethod)iter.next();
                String methodType = (clMethod != null && clMethod.getVerificationType() != null) ?clMethod.getVerificationType().getCode() : null;
                if(StringUtils.equals(methodType,typeCode)) {
                    return clMethod;
                }
            }
        }
        return null;
    }   



	public Date getChangeDate_h() {
		return changeDate_h;
	}

	public void setChangeDate_h(Date changeDate_h) {
		this.changeDate_h = changeDate_h;
	}
	
	public void removeAllCampLejeuneVerificationMethods() {
		for(CampLejeuneVerificationMethod meth: getInternalCampLejeuneVerificationMethods()) {
			meth.setSpecialFactor(null);
		}
		this.getInternalCampLejeuneVerificationMethods().clear();
		
	}

	public void removeCampLejeuneVerificationMethod(CampLejeuneVerificationMethod campLejeuneVerMethod) {
		Validate.notNull(campLejeuneVerMethod, "CampLejeuneVerificationMethod cannot be null");
		removeCampLejeuneVerificationMethodByType(campLejeuneVerMethod.getVerificationType());
			
	}
	
	 public void removeCampLejeuneVerificationMethodByType(CampLejeuneVerificationType verificationType) {
	        Validate.notNull(verificationType,"CampLejeuneVerificationType connot be null");
	        CampLejeuneVerificationMethod veriMethod = getCampLejeuneMethodByType(verificationType);
	        if (veriMethod != null) {
	        	veriMethod.setSpecialFactor(null);
	        	internalCampLejeuneVerificationMethods.remove(veriMethod);
	       
	        }
	    }  
	
		protected void buildToString(ToStringBuilder builder) {
			super.buildToString(builder);
			builder.append("changeSource", this.changeSource);		
			builder.append("changeSite", this.changeSite);		
			builder.append("internalCampLejeuneVerificationMethods", this.internalCampLejeuneVerificationMethods);		
			builder.append("verificationType", this.verificationType);		
			builder.append("comments", this.comments);
	        builder.append("changeDate_h", this.changeDate_h);
		}

}
