/********************************************************************
 * Copyright © 2004 EDS. All rights reserved
 ********************************************************************/
package gov.va.med.esr.common.builder.entity;

// Java Classes

// Library Classes

// Framework Classes
import gov.va.med.fw.util.builder.Builder;
import gov.va.med.fw.util.builder.BuilderException;

// Common Classes
import gov.va.med.esr.common.model.ee.RatedDisability;
import gov.va.med.esr.common.model.lookup.DiagnosticExtremity;
import gov.va.med.esr.common.model.lookup.Disability;

// Messaging Classes

/**
 * Builds a rated disability from a message and a person if elements in the ZRD
 * segments are present
 * 
 * @author Carlos Ruiz
 * @version 1.0
 */
public class RatedDisabilityBuilder
    extends EntityBuilder
{
    /**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 1492120114974389699L;
	private Builder disabilityBuilder;
	private Builder diagnosticExtremityBuilder;

    /**
     * Default constructor.
     */
    public RatedDisabilityBuilder()
    {
        super();
    }

    public Builder getDisabilityBuilder()
    {
        return this.disabilityBuilder;
    }

    public void setDisabilityBuilder(Builder disabilityBuilder)
    {
        this.disabilityBuilder = disabilityBuilder;
    }
 
    /**
     * @return Returns the diagnosticExtremityBuilder.
     */
    public Builder getDiagnosticExtremityBuilder()
    {
        return diagnosticExtremityBuilder;
    }
    /**
     * @param diagnosticExtremityBuilder The diagnosticExtremityBuilder to set.
     */
    public void setDiagnosticExtremityBuilder(Builder diagnosticExtremityBuilder)
    {
        this.diagnosticExtremityBuilder = diagnosticExtremityBuilder;
    }
    
    /**
     * Build a RatedDisability from RatedDisabilityMetaData
     * 
     * @param metaData
     * @return
     * @throws BuilderException
     */
    public RatedDisability build(RatedDisabilityMetaData metaData)
        throws BuilderException
    {
        RatedDisability input = metaData.getEntity();
        Boolean shouldAdd = super.build((Boolean)null, metaData
            .getServiceConnected());

        if(Boolean.TRUE.equals(shouldAdd))
        {
            RatedDisability output = (input == null) ? new RatedDisability()
                : input;

            this.transfer(output, metaData);

            return this.shouldKeep(output) ? output : null;
        }
        else
        {
            return null;
        }
    }

    private Disability buildDisability(Disability input, String code)
        throws BuilderException
    {
        return super.shouldDelete(code) ? null : (Disability)super
            .build(this.disabilityBuilder, input, code);
    }

    private DiagnosticExtremity buildDiagnosticExtremity(
            DiagnosticExtremity input, String code) throws BuilderException
    {
        return super.shouldDelete(code) ? null : (DiagnosticExtremity) super
                .build(this.diagnosticExtremityBuilder, input, code);
    }    
    
    private boolean shouldKeep(RatedDisability obj)
    {
        return ((obj.getDisability() != null) && (obj.getPercentage() != null));
    }

    private void transfer(
        RatedDisability input,
        RatedDisabilityMetaData metaData) throws BuilderException
    {
        input.setDisability(this
            .buildDisability(input.getDisability(), metaData.getDisability()));
        //No need to set this since it is implied that only SC Rated Diabilities are inlcuded. 
//        input.setServiceConnected(super  
//            .build(input.isServiceConnected(), metaData.getServiceConnected()));
        input.setPercentage(super.build(input.getPercentage(), metaData
            .getPercentage())); 
        input.setDiagnosticExtremity(this
                .buildDiagnosticExtremity(input.getDiagnosticExtremity(), metaData.getDiagnosticExtremity()));
        input.setOriginalEffectiveRatingDate(super.build(input
                .getOriginalEffectiveRatingDate(), metaData
                .getRatedDisabilityOrigEffectiveDate()));
        input.setRatingDate(super.build(input
                .getRatingDate(), metaData
                .getRatedDisabilityCurrentEffectiveDate()));
    }
}