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

// Java classes
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.collections.set.UnmodifiableSet;
import org.apache.commons.lang.StringUtils;
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.lookup.RegistryType;

/**
 * @author Muddaiah Ranga
 * @version 3.0
 */
public class RegistryTrait extends AbstractKeyedEntity
{

    private static final long serialVersionUID = -5938910697096303042L;

    /**
     * Type of registry is defined as a type.
     */
    private RegistryType registryType               = null;

    // SSN of the veteran
    private String ssn                              = null;
    
    // Prefix of the person
    private String prefix                           = null;
    
    // First Name of the veteran
    private String firstName                        = null;
    
    // Middle Name of the person
    private String middleName                       = null;
    
    // Last Name of the veteran
    private String lastName                         = null;
    
    // Suffix of the person
    private String suffix                           = null;
    
    // Educational degree of the person
    private String educationalDegree                = null;
    
    // Date of death of the person
    private ImpreciseDate   deathDate               = null;
    
    private Set internalRegistryTraitDetails        = null;

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

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

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getRegistryType()
	 */
    public RegistryType getRegistryType() {
        return registryType;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setRegistryType(gov.va.med.esr.common.model.lookup.RegistryType)
	 */
    public void setRegistryType(RegistryType registryType) {
        this.registryType = registryType;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getSsn()
	 */
    public String getSsn() {
        return ssn;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setSsn(java.lang.String)
	 */
    public void setSsn(String ssn) {
        this.ssn = ssn;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getPrefix()
	 */
    public String getPrefix() {
        return prefix;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setPrefix(java.lang.String)
	 */
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getFirstName()
	 */
    public String getFirstName() {
        return firstName;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setFirstName(java.lang.String)
	 */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getMiddleName()
	 */
    public String getMiddleName() {
        return middleName;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setMiddleName(java.lang.String)
	 */
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getLastName()
	 */
    public String getLastName() {
        return lastName;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setLastName(java.lang.String)
	 */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getSuffix()
	 */
    public String getSuffix() {
        return suffix;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setSuffix(java.lang.String)
	 */
    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getEducationalDegree()
	 */
    public String getEducationalDegree() {
        return educationalDegree;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setEducationalDegree(java.lang.String)
	 */
    public void setEducationalDegree(String educationalDegree) {
        this.educationalDegree = educationalDegree;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getDeathDate()
	 */
    public ImpreciseDate getDeathDate() {
        return deathDate;
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#setDeathDate(gov.va.med.esr.common.infra.ImpreciseDate)
	 */
    public void setDeathDate(ImpreciseDate deathDate) {
        this.deathDate = deathDate;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getRegistryTraitDetails()
	 */
    public Set getRegistryTraitDetails() {
        return UnmodifiableSet.decorate(getInternalRegistryTraitDetails());
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getMilitaryServiceNumbers()
	 */
    public String getMilitaryServiceNumbers() {
        StringBuffer buffer = new StringBuffer();
        if(internalRegistryTraitDetails != null) {
            RegistryTraitDetail rtDetail = null;
            for(Iterator iter=internalRegistryTraitDetails.iterator(); iter.hasNext();) {
                rtDetail = (RegistryTraitDetail)iter.next();
                if(rtDetail != null && StringUtils.isNotBlank(rtDetail.getMilitaryServiceNumber())) {
                    if(buffer.length() > 0) buffer.append(", ");
                    buffer.append(rtDetail.getMilitaryServiceNumber());
                }
            }
        }
        return buffer.toString();
    }

    public Set getMilitaryServiceNumbersAsSet() {
        Set set = new HashSet();
        if(internalRegistryTraitDetails != null) {
            RegistryTraitDetail rtDetail = null;
            for(Iterator iter=internalRegistryTraitDetails.iterator(); iter.hasNext();) {
                rtDetail = (RegistryTraitDetail)iter.next();
                if(rtDetail != null && StringUtils.isNotBlank(rtDetail.getMilitaryServiceNumber())) {
                	set.add(rtDetail.getMilitaryServiceNumber());
                }
            }
        }
        return set;
    }
    
    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#addRegistryTraitDetail(gov.va.med.esr.common.model.registry.RegistryTraitDetail)
	 */
    public void addRegistryTraitDetail(RegistryTraitDetail registryTraitDetail) {
        getInternalRegistryTraitDetails().add(registryTraitDetail);
        registryTraitDetail.setRegistryTrait(this);
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#addAllRegistryTraitDetails(java.util.Set)
	 */
    public void addAllRegistryTraitDetails(Set registryTraitDetails) {
        Validate.notEmpty(registryTraitDetails, "RegistryTraitDetails cannot be null or empty");
        
        // Call addRegistryTraitDetails to handle bidirectional relationship
        for (Iterator i = registryTraitDetails.iterator(); i.hasNext();) {
            Object registryTraitDetail = i.next();
            if (registryTraitDetail instanceof RegistryTraitDetail) {
                this.addRegistryTraitDetail((RegistryTraitDetail) registryTraitDetail);
            }
        }
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#removeRegistryTraitDetail(gov.va.med.esr.common.model.registry.RegistryTraitDetail)
	 */
    public void removeRegistryTraitDetail(RegistryTraitDetail registryTraitDetail) {
        Validate.notNull(registryTraitDetail,"Null Combat Experience Record specified.");
        getInternalRegistryTraitDetails().remove(registryTraitDetail);
        registryTraitDetail.setRegistryTrait(null);
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#getRegistryTraitDetailByEntityKey(gov.va.med.fw.model.EntityKey)
	 */
    public RegistryTraitDetail getRegistryTraitDetailByEntityKey(EntityKey identifier) {
        return (RegistryTraitDetail)getEntityByEntityKey(getRegistryTraitDetails(),identifier);
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#removeRegistryTraitDetailByEntityKey(gov.va.med.fw.model.EntityKey)
	 */
    public RegistryTraitDetail removeRegistryTraitDetailByEntityKey(EntityKey identifier) {
        return (RegistryTraitDetail) removeEntityByEntityKey(getInternalRegistryTraitDetails(),identifier);
    }

    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.model.registry.IRegistryTrait#removeAllRegistryTraitDetails()
	 */
    public void removeAllRegistryTraitDetails() {
        getInternalRegistryTraitDetails().clear();
    }

    private void setInternalRegistryTraitDetails(Set registryTraitDetails) {
        this.internalRegistryTraitDetails = registryTraitDetails;
    }

    private Set getInternalRegistryTraitDetails() {
        if (this.internalRegistryTraitDetails == null) {
            this.internalRegistryTraitDetails = new HashSet();
        }
        return this.internalRegistryTraitDetails;
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.fw.model.AbstractKeyedEntity#buildToString(org.apache.commons.lang.builder.ToStringBuilder)
     */
    protected void buildToString(ToStringBuilder builder) {
        builder.append("registryType", this.registryType);
        builder.append("ssn", this.ssn);
        builder.append("prefix",this.prefix);
        builder.append("firstName", this.firstName);
        builder.append("middleName",this.middleName);
        builder.append("lastName", this.lastName);
        builder.append("suffix",this.suffix);
        builder.append("educationalDegree",this.educationalDegree);
        builder.append("deathDate", this.deathDate);
    }
}