/*
 * Created on Jan 22, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package gov.va.med.esr.ui.ee.action;

//Java classes
import gov.va.med.esr.common.model.ee.HealthBenefitPlan;
import gov.va.med.esr.common.model.ee.HealthBenefitProfile;
import gov.va.med.esr.common.model.lookup.DataChangeSource;
import gov.va.med.esr.common.model.lookup.HealthBenefitPlanType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.ui.conversion.UIConversionServiceImpl;
import gov.va.med.fw.conversion.ConversionServiceException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


/**
 * 
 *
 *
 */
public class HealthBenefitPlanConversionService extends UIConversionServiceImpl {
	
	
    
	protected void convertBean(Object source, Object target)
    throws ConversionServiceException
	{
	
		if (source instanceof Person && target instanceof HealthBenefitPlanForm) {
			try {
				convert((Person)source, (HealthBenefitPlanForm)target);
			} catch (Exception ex) {
				throw new ConversionServiceException("Conversion Failed", ex);
           }
		}
	  else if (source instanceof HealthBenefitPlanForm && target instanceof Person) {
		try {
			convert((HealthBenefitPlanForm)source, (Person)target);
		} catch (Exception ex) {
			throw new ConversionServiceException("Conversion Failed", ex);
		}
	   }
	  else 
      {
          throw new ConversionServiceException("Type mismatch: Expecting Person, HealthBenefitPlansForm Received " +
                  source.getClass().getName() + " and " + target.getClass().getName());
      }
	 }
	
	
	 private void convert(Person person, HealthBenefitPlanForm form) throws Exception {
		 
         HealthBenefitProfile hbpProfile = person.getHealthBenefitProfile();
         
         if(hbpProfile != null){
        	 
        	List<HealthBenefitPlan> healthBenefitPlans = new ArrayList<HealthBenefitPlan>(hbpProfile.getHealthBenefitPlans());
        	Collections.sort(healthBenefitPlans);
							
         	int index = 0;
         	
         	for (Iterator iter = healthBenefitPlans.iterator(); iter.hasNext(); ) {
     			HealthBenefitPlan hbp = (HealthBenefitPlan) iter.next();
     			String code = hbp.getPlanType().getCode();
     			boolean isNotEditable = HealthBenefitPlanType.CODE_PRESUMPTIVE.getCode().equalsIgnoreCase(code);
     			
     			// Convert the standard fields	
	     		form.setAssignedHbpCode(index, code);
	     		form.setAssignedHbpDesc(index, hbp.getPlanType().getName());
	     		form.setAssignedHbpInd(index, Boolean.TRUE);
	     		form.setAssignedHbpLastUpdatedDate(index, hbp.getChangeDate().toString());
	     		form.setAssignedHbpEditable(index, Boolean.valueOf(isNotEditable));
	     		index++;
         	}
         }

         
         // Need a full list of health benefit plans
         Collection hbpTypes = this.getLookupCacheService().getFromCache(HealthBenefitPlanType.class.getName());
         
         // fileter down to the available plans
         int j = 0;
         for(Iterator iter= hbpTypes.iterator(); iter.hasNext();) {
        	 HealthBenefitPlanType type = (HealthBenefitPlanType)iter.next();
        	 if (hbpProfile.getHealthBenefitPlanByType(type) == null) {
        		// available
        		String code = type.getCode();
        		boolean isNotEditable = HealthBenefitPlanType.CODE_PRESUMPTIVE.getCode().equalsIgnoreCase(code);
        		form.setHbpCode(j, code); 
	     		form.setHbpDesc(j, type.getName()); 
	     		form.setHbpEditable(j, Boolean.valueOf(isNotEditable));
	     		j++;

        	 }
         }
       }

	 private void convert(HealthBenefitPlanForm form, Person person) 
	    throws Exception {
		 // Add the selected HealthBenefitPlans
		List<HealthBenefitPlanType> addList = new ArrayList<HealthBenefitPlanType>();

		// Process Previoulsy assigned list
		List codeList = form.getAssignedHbpCodeList();
		if (codeList != null && codeList.size() > 0) {
			for (int i = 0; i < codeList.size(); i++) {
				// Check whether this healthcare plan has been checked
				Boolean selected = (Boolean) form.getAssignedHbpInd(i);
				// get the HealthCarePlan from lookup service
				HealthBenefitPlanType planType = (HealthBenefitPlanType) getLookupCacheService()
						.getByCodeFromCache(HealthBenefitPlanType.class,
								form.getAssignedHbpCode(i));
				if (Boolean.TRUE.equals(selected)) {
					addList.add(planType);
				}
			}
		}
	     
	  // Process the previously avilable list
		codeList = form.getHbpCodeList();
		if (codeList != null && codeList.size() > 0) {
			for (int i = 0; i < codeList.size(); i++) {
				// Check whether this healthcare plan has been checked
				Boolean selected = (Boolean) form.getHbpInd(i);
				// get the HealthCarePlan from lookup service
				HealthBenefitPlanType planType = (HealthBenefitPlanType) getLookupCacheService()
						.getByCodeFromCache(HealthBenefitPlanType.class,
								form.getHbpCode(i));
				if (Boolean.TRUE.equals(selected)) {
					addList.add(planType);
				}
			}
		}
		
		// process deletes
		//deleted list is existing list - (add + retained) list
		List<HealthBenefitPlan> deleteList = new ArrayList<HealthBenefitPlan>();
		List<HealthBenefitPlan> originalList = new ArrayList<HealthBenefitPlan>(person.getHealthBenefitProfile().getHealthBenefitPlans());
		
		if (originalList != null && originalList.size()>0) {
			for (int j = 0; j < originalList.size(); j++) {

			HealthBenefitPlan plan = (HealthBenefitPlan)originalList.get(j);
					if (!addList.contains(plan.getPlanType())) {
						deleteList.add(plan);
         }
        person.getHealthBenefitProfile().removeHealthBenefitPlans(deleteList);
			}   
		}
	    
    //Add the selected health benefit plans from the avaiable list
    HealthBenefitProfile hbpProfile = person.getHealthBenefitProfile();
    HealthBenefitPlanType planType;
    HealthBenefitPlan newPlan;
    
    for (Iterator iter3 = addList.iterator(); iter3.hasNext();) {
        planType = (HealthBenefitPlanType)iter3.next();
        if (hbpProfile.getHealthBenefitPlanByType(planType) == null) {
        	 newPlan = new HealthBenefitPlan();
        	 newPlan.setPlanType(planType);
        	 newPlan.setChangeDate(new Date());
        	 newPlan.setChangeSource((DataChangeSource)getLookupCacheService().getByCodeFromCache(DataChangeSource.class,DataChangeSource.CODE_ESR.getCode()));
        	 hbpProfile.addHealthBenefitPlan(newPlan);
        }
    }
 }

}
  

