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

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

// Library Classes

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

// Common Classes
import gov.va.med.esr.common.builder.entity.metaData.ServiceConnectionAwardMetaDataFromZSP;
import gov.va.med.esr.common.model.ee.RatedDisability;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.person.Person;

// Messaging Classess

/**
 * Class that builds the application from a message.
 * 
 * @author Carlos Ruiz
 * @version 1.0
 */
public class ServiceConnectionAwardBuilder extends EntityBuilder
{
    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = -7003304469715578443L;

    private Builder ratedDisabilityBuilder;

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

    public Builder getRatedDisabilityBuilder()
    {
        return this.ratedDisabilityBuilder;
    }

    public void setRatedDisabilityBuilder(Builder ratedDisabilityBuilder)
    {
        this.ratedDisabilityBuilder = ratedDisabilityBuilder;
    }

    public ServiceConnectionAward build(Person person, HL7Message message)
            throws BuilderException, InvalidMessageException
    {

        ServiceConnectionAward award = person.getServiceConnectionAward();
        ServiceConnectionAwardMetaData metaData = new ServiceConnectionAwardMetaDataFromZSP(
                message.getZSPSegment(), message.getZRDSegments());
        metaData.setEntity(award);

        return this.build(metaData);
    }

    public ServiceConnectionAward build(ServiceConnectionAwardMetaData metaData)
            throws BuilderException
    {
        ServiceConnectionAward input = metaData.getEntity();
        Boolean shouldAdd = super.build((Boolean) null, metaData
                .getServiceConnected());

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

            this.transfer(output, metaData);

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

    private void buildRatedDisabilities(ServiceConnectionAward input,
            RatedDisabilityMetaData[] metaData) throws BuilderException
    {
        Set toAdd = new HashSet();

        for (int index = 0; index < ((metaData == null) ? 0 : metaData.length); index++)
        {
            this.processRatedDisability(toAdd, metaData[index]);
        }

        input.removeAllRatedDisability();

        for (Iterator i = toAdd.iterator(); i.hasNext();)
        {
            input.addRatedDisability((RatedDisability) i.next());
        }
    }

    private RatedDisability buildRatedDisability(RatedDisability input,
            RatedDisabilityMetaData metaData) throws BuilderException
    {
        if (metaData == null)
        {
            return null;
        }

        metaData.setEntity(input);
        return (RatedDisability) this.ratedDisabilityBuilder.build(metaData);

    }
    private boolean shouldKeep(ServiceConnectionAward obj)
    {
        return ((obj.getServiceConnectedPercentage() != null) && !super
                .isEmpty(obj.getRatedDisabilities()));
    }

    private void processRatedDisability(Set toAdd,
            RatedDisabilityMetaData metaData) throws BuilderException
    {

        RatedDisability value = this.buildRatedDisability(null, metaData);

        if (value != null)
        {
            toAdd.add(value);
        }
    }

    private void transfer(ServiceConnectionAward input,
            ServiceConnectionAwardMetaData metaData) throws BuilderException
    {
        input.setServiceConnectedIndicator(super.build(input.getServiceConnectedIndicator(), 
                metaData.getServiceConnected())); 
        input.setAwardDate(super.build(input.getAwardDate(), metaData
                .getAwardDate()));
        input.setPermanentAndTotal(super.build(input.isPermanentAndTotal(), 
                metaData.getPermanentAndTotal()));
        input.setPermanentAndTotalEffectiveDate(super.build(input
                .getPermanentAndTotalEffectiveDate(), metaData
                .getPermanentAndTotalEffectiveDate()));
        input.setServiceConnectedPercentage(super.build(input
                .getServiceConnectedPercentage(), metaData
                .getServiceConnectedPercentage()));
        input.setUnemployable(super.build(input.isUnemployable(), metaData
                .getUnemployable())); 
        input.setCombinedServiceConnectedPercentageEffectiveDate(
                super.build(
                        input.getCombinedServiceConnectedPercentageEffectiveDate(),
                        metaData.getCombinedSCPercentEffectiveDate()));

        this.buildRatedDisabilities(input, metaData.getRatedDisabilities());
    }
    
}