/*
 * MonetaryBenefitAward.java Copyright 2004, Veterans Health Administration All
 * rights reserved.
 */

// Generated 11/26/2004 10:24:04 AM

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

// ----------------------------------------------------------------------------
// Import java classes
// ----------------------------------------------------------------------------
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// import java.io.Serializable;

// ----------------------------------------------------------------------------
// Import third party library classes
// ----------------------------------------------------------------------------
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.Validate;

// ----------------------------------------------------------------------------
// Import Framework classes
// ----------------------------------------------------------------------------
import gov.va.med.fw.model.AbstractKeyedEntity;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.lookup.MonetaryBenefitType;
import gov.va.med.esr.common.model.person.Person;


/**
 * @author Commons Team
 * @hibernate.mapping auto-import="true" default-cascade="all"
 * @hibernate.class table="VBA_FACTORS" where="T_VBA_FACTOR_TYPE = '01'"
 */
public class MonetaryBenefitAward extends AbstractKeyedEntity {

	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 5924196356299399292L;

    /**
     * @hibernate.many-to-one class="gov.va.med.esr.common.model.person.Person"
     *                        not-null="true" insert="true" update="false"
     * @hibernate.column name="PARTY_ID"
     */
    private Person person;

    /**
     * Currently only capturing the total check amount. Total Check Amount is
     * defined as a total dollar amount for A&A, Housebound, Pension, and/or
     * Disability payments from the VA Format is a dollar amount 0-99999. Null is
     * a valid value for this attribute as it is applied to eligibility
     * determinations.
     * 
     * @hibernate.property insert="true" update="true"
     *                     column="MONETARY_BENEFIT_AWARD_AMT"
     */
    private BigDecimal checkAmount = null;

    /**
     * @hibernate.set lazy="true" inverse="true" cascade="all"
     *                where="T_VBA_FACTOR_TYPE = '01'"
     * @hibernate.collection-key column="VBA_FACTOR_ID"
     * @hibernate.collection-one-to-many class="MonetaryBenefit"
     */
    private Set internalMonetaryBenefits = null;

	/**
	 * Creates a new MonetaryBenefitAward object.
	 */
	public MonetaryBenefitAward() {
		super();
	}

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

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

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

	public BigDecimal getCheckAmount() {
		return this.checkAmount;
	}

	public void setCheckAmount(BigDecimal checkAmount) {
		this.checkAmount = checkAmount;
	}

	/**
	 * Unmodifiable
	 * 
	 * @return
	 */
	public Set getMonetaryBenefits() {
		return Collections.unmodifiableSet(getInternalMonetaryBenefits());
	}
	
	public boolean containsMonetaryBenefits() {
		Set mbs = getInternalMonetaryBenefits();
		return mbs != null && mbs.size() > 0 ? true : false;
	}
    
	private Set getInternalMonetaryBenefits() {
		if (internalMonetaryBenefits == null) {
			this.internalMonetaryBenefits = new HashSet();
		}
		return this.internalMonetaryBenefits;
	}

	private void setInternalMonetaryBenefits(Set internalMonetaryBenefits) {
		this.internalMonetaryBenefits = internalMonetaryBenefits;
	}

	public void addMonetaryBenefit(MonetaryBenefit monetaryBenefit) {
		Validate.notNull(monetaryBenefit, "Monetary Benefit cannot be null");
        //If it already exists do not add
        if (getMonetaryBenefitByType(monetaryBenefit.getType()) == null) {
        	//setMonetaryBenefitAward(this) before add to the set, 
        	//to avoid stack overflow error
        	monetaryBenefit.setMonetaryBenefitAward(this);
            getInternalMonetaryBenefits().add(monetaryBenefit);
           
        }
	}

	public void removeAllMonetaryBenefits() {
		this.getInternalMonetaryBenefits().clear();
	}

	public void removeMonetaryBenefit(MonetaryBenefit monetaryBenefit) {
		Validate.notNull(monetaryBenefit, "Monetary Benefit cannot be null");
		getInternalMonetaryBenefits().remove(monetaryBenefit);
	}
    
    public MonetaryBenefit getMonetaryBenefitByType(MonetaryBenefitType type) {
        Validate.notNull(type,"MonetaryBenefitType connot be null");
        return getMonetaryBenefitByType(type.getCode());
    }
    
    public MonetaryBenefit getMonetaryBenefitByType(MonetaryBenefitType.Code type) {
        Validate.notNull(type,"MonetaryBenefitType connot be null");
        return getMonetaryBenefitByType(type.getCode());
    }

    public void removeMonetaryBenefitByType(MonetaryBenefitType type) {
        Validate.notNull(type,"MonetaryBenefitType connot be null");
        MonetaryBenefit monetaryBenefit = getMonetaryBenefitByType(type);
        if (monetaryBenefit != null) 
            removeMonetaryBenefit(monetaryBenefit);        
    }
    
    public void removeMonetaryBenefitByType(MonetaryBenefitType.Code type) {
        Validate.notNull(type,"MonetaryBenefitType connot be null");
        MonetaryBenefit monetaryBenefit = getMonetaryBenefitByType(type.getCode());
        if (monetaryBenefit != null) 
            removeMonetaryBenefit(monetaryBenefit);
    }
    
    public MonetaryBenefit getAidAndAttendance() {
        return getMonetaryBenefitByType(MonetaryBenefitType.CODE_AID_AND_ATTENDANCE);
    }
    
    public MonetaryBenefit getHouseBound() {
        return getMonetaryBenefitByType(MonetaryBenefitType.CODE_HOUSEBOUND);
    }
    
    public MonetaryBenefit getVAPension() {
        return getMonetaryBenefitByType(MonetaryBenefitType.CODE_VA_PENSION);
    }
    
    public MonetaryBenefit getDisabilityCompensation() {
        return getMonetaryBenefitByType(MonetaryBenefitType.CODE_DISABILITY_COMPENSATION);
    }
    public void setAidAndAttendance(MonetaryBenefit monetaryBenefit) {
        if (monetaryBenefit == null) {
            removeMonetaryBenefitByType(MonetaryBenefitType.CODE_AID_AND_ATTENDANCE);
        } else {
            addMonetaryBenefit(monetaryBenefit);
        }
    }
    
    public void setHouseBound(MonetaryBenefit monetaryBenefit) {
        if (monetaryBenefit == null){
            removeMonetaryBenefitByType(MonetaryBenefitType.CODE_HOUSEBOUND);
        }else {
            addMonetaryBenefit(monetaryBenefit);
        }
    }
    
    public void setVAPension(MonetaryBenefit monetaryBenefit) {
        if (monetaryBenefit == null)
            removeMonetaryBenefitByType(MonetaryBenefitType.CODE_VA_PENSION);
        else {
            addMonetaryBenefit(monetaryBenefit);
        }
    }
    
    public void setDisabilityCompensation(MonetaryBenefit monetaryBenefit) {
        if (monetaryBenefit == null){
            removeMonetaryBenefitByType(MonetaryBenefitType.CODE_DISABILITY_COMPENSATION);
        }else {
            addMonetaryBenefit(monetaryBenefit);
        }
    }
    
    private MonetaryBenefit getMonetaryBenefitByType(String typeCode) {
        if(StringUtils.isNotEmpty(typeCode)) {
            for(Iterator iter=getInternalMonetaryBenefits().iterator(); iter.hasNext();) {
                MonetaryBenefit mBenefit = (MonetaryBenefit)iter.next();
                String type = (mBenefit != null && mBenefit.getType() != null) ? mBenefit.getType().getCode() : null;
                if(StringUtils.equals(type,typeCode)) {
                    return mBenefit;
                }
            }
        }
        return null;
    } 

	/**
	 * (non-Javadoc)
	 * 
	 * @see gov.va.med.fw.model.AbstractKeyedEntity#buildToString(org.apache.commons.lang.builder.ToStringBuilder)
	 */
	protected void buildToString(ToStringBuilder builder) {
		super.buildToString(builder.append("checkAmount", this.checkAmount));
	}
}
