/*******************************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.model.ee;

// Java classes
import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;
import gov.va.med.fw.model.EntityKey;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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

/**
 * Extends from AbstractEnrollment, EnrollmentDetermination BOM defines
 * attributes that are specific to enrollment determination.
 *
 * @author Ghazenfer Mansoor
 * @version 1.0
 */
public class EnrollmentDetermination extends AbstractEnrollment {
    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = -7955554419785801336L;

    private Set internalPrimaryEligibilities = null;

    private Set internalSecondaryEligibilities = null;

    private Set internalOtherEligibilities = null;

    private EGTSetting egtSetting = null;

    public void setIdentifier(Serializable identifier) {
        super.setIdentifier(identifier);
    }

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

    /**
     * Get the Primary Eligibility if exists, null otherwise.
     *
     * @return Eligibility
     */
    public Eligibility getPrimaryEligibility() {
        Set eligibilities = getInternalPrimaryEligibilities();
        if (eligibilities.size() > 0) {
            return (Eligibility) this.internalPrimaryEligibilities.iterator()
                    .next();
        }
        return null;
    }

    /**
     * Set the Primary Eligibility.
     *
     * @param primaryEligibility
     */
    public void setPrimaryEligiblity(Eligibility primaryEligibility) {
        Set eligibilities = getInternalPrimaryEligibilities();
        eligibilities.clear();
        if (primaryEligibility != null) {
            addPrimaryEligibility(primaryEligibility);
        }
    }

    /**
     * Getter for primary eligibilites - For hibernate only.
     */
    private Set getInternalPrimaryEligibilities() {
        if (internalPrimaryEligibilities == null) {
            this.internalPrimaryEligibilities = new HashSet();
        }
        return this.internalPrimaryEligibilities;
    }

    /**
     * Setter for primary eligibilites. For hibernate use only.
     *
     * @param internalPrimaryEligibilities
     */
    private void setInternalPrimaryEligibilities(
            Set internalPrimaryEligibilities) {
        this.internalPrimaryEligibilities = internalPrimaryEligibilities;
    }

    /**
     * Add a given eligibility to the primary eligibility collection.
     *
     * @param primaryEligibility
     */
    private void addPrimaryEligibility(Eligibility primaryEligibility) {
        Validate.notNull(primaryEligibility,
                "Primary eligibility cannot be null");
        getInternalPrimaryEligibilities().add(primaryEligibility);
        primaryEligibility.setPrimary();
        primaryEligibility.setEnrollmentDetermination(this);
    }

    /**
     * Collection of Eligibilities of type Other.
     *
     * @return Set - Set of Eligibility Objects
     */
    public Set getOtherEligibilities() {
        return Collections.unmodifiableSet(getInternalOtherEligibilities());
    }

    /**
     * Getter for other eligibilites - For hibernate only.
     */
    private Set getInternalOtherEligibilities() {
        if (internalOtherEligibilities == null) {
            this.internalOtherEligibilities = new HashSet();
        }
        return this.internalOtherEligibilities;
    }

    /**
     * Setter for other eligibilites. For hibernate use only.
     *
     * @param internalOtherEligibilities
     */
    private void setInternalOtherEligibilities(Set internalOtherEligibilities) {
        this.internalOtherEligibilities = internalOtherEligibilities;
    }

    /**
     * Add a given eligibility to the other eligibility collection.
     *
     * @param otherEligibility
     */
    public void addOtherEligibility(Eligibility otherEligibility) {
        Validate.notNull(otherEligibility, "Other eligibility cannot be null");
        getInternalOtherEligibilities().add(otherEligibility);
        otherEligibility.setOther();
        otherEligibility.setEnrollmentDetermination(this);
    }

    public void removeCLFromOtherEligibilities() {
        List eList = new ArrayList();
        for (Iterator iter = getInternalOtherEligibilities().iterator(); iter
                .hasNext();) {
            Eligibility e = (Eligibility) iter.next();
            if (!"CL".equals(e.getFactor().getCode())) {
                eList.add(e);
            } else {
                e.setEnrollmentDetermination(null);
            }
        }
        getInternalOtherEligibilities().clear();
        getInternalOtherEligibilities().addAll(eList);
    }
    /**
     * Remove the given eligibility from a Other collection, if exists.
     *
     * @param otherEligibility
     */
    public void removeOtherEligibility(Eligibility otherEligibility) {
        Validate.notNull(otherEligibility, "Other eligibility cannot be null");
        List eList = new ArrayList();
        for (Iterator iter = getInternalOtherEligibilities().iterator(); iter
                .hasNext();) {
            Eligibility e = (Eligibility) iter.next();
            if ((otherEligibility.getEntityKey() != null
                    && e.getEntityKey() != null && !otherEligibility
                    .getEntityKey().equals(e.getEntityKey()))
                    || (otherEligibility != e) || (!otherEligibility.equals(e))) {
                eList.add(e);
            }
        }
        getInternalOtherEligibilities().clear();
        getInternalOtherEligibilities().addAll(eList);
        otherEligibility.setEnrollmentDetermination(null);
    }

    /**
     * Collection of Eligibilities of type Secondary.
     *
     * @return Set - Set of Eligibility Objects
     */
    public Set getSecondaryEligibilities() {
        return Collections.unmodifiableSet(getInternalSecondaryEligibilities());
    }

    /**
     * Getter for secondary eligibilites - For hibernate only.
     */
    private Set getInternalSecondaryEligibilities() {
        if (this.internalSecondaryEligibilities == null) {
            this.internalSecondaryEligibilities = new HashSet();
        }
        return this.internalSecondaryEligibilities;
    }

    /**
     * Setter for secondary eligibilites. For hibernate use only.
     *
     * @param internalSecondaryEligibilities
     */
    private void setInternalSecondaryEligibilities(
            Set internalSecondaryEligibilities) {
        this.internalSecondaryEligibilities = internalSecondaryEligibilities;
    }

    /**
     * Add a given eligibility to the secondary eligibility collection.
     *
     * @param secondaryEligibility
     */
    public void addSecondaryEligibility(Eligibility secondaryEligibility) {
        Validate.notNull(secondaryEligibility,
                "Secondary eligibility cannot be null");
        getInternalSecondaryEligibilities().add(secondaryEligibility);
        secondaryEligibility.setSecondary();
        secondaryEligibility.setEnrollmentDetermination(this);

    }

    /**
     * Remove the given eligibility from a secondary collection, if exists.
     *
     * @param secondaryEligibility
     */
    public void removeSecondaryEligibility(Eligibility secondaryEligibility) {
        Validate.notNull(secondaryEligibility,
                "Secondary eligibility cannot be null");

        List eList = new ArrayList();
        for (Iterator iter = getInternalSecondaryEligibilities().iterator(); iter
                .hasNext();) {
            Eligibility e = (Eligibility) iter.next();
            if ((secondaryEligibility.getEntityKey() != null
                    && e.getEntityKey() != null && !secondaryEligibility
                    .getEntityKey().equals(e.getEntityKey()))
                    || (secondaryEligibility != e)
                    || (!secondaryEligibility.equals(e))) {
                eList.add(e);
            }
        }
        getInternalSecondaryEligibilities().clear();
        getInternalSecondaryEligibilities().addAll(eList);
        secondaryEligibility.setEnrollmentDetermination(null);
    }

    /**
     * Get EGTSetting from this enrollment.
     *
     * @return EGTSetting
     */
    public EGTSetting getEgtSetting() {
        return this.egtSetting;
    }

    /**
     * Set EGTSetting for this enrollment.
     *
     * @param egtSetting
     */
    public void setEgtSetting(EGTSetting egtSetting) {
        this.egtSetting = egtSetting;
    }

    /*
     * (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("egtSetting", this.egtSetting);
    }


}
