/********************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.ui.demographic.action;

// Java Classes
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.lookup.AddressChangeSource;
import gov.va.med.esr.common.model.lookup.AddressType;
import gov.va.med.esr.common.model.lookup.BadAddressReason;
import gov.va.med.esr.common.model.lookup.ConfidentialAddressCategoryType;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.common.model.lookup.EmailSourceOfChange;
import gov.va.med.esr.common.model.lookup.EmailType;
import gov.va.med.esr.common.model.lookup.PhoneSourceOfChange;
import gov.va.med.esr.common.model.lookup.PhoneType;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.party.ConfidentialAddressCategory;
import gov.va.med.esr.common.model.party.Email;
import gov.va.med.esr.common.model.party.Phone;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.ui.common.action.AddressConversionService;
import gov.va.med.esr.ui.common.service.LookupCacheService;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.fw.conversion.ConversionServiceException;
import gov.va.med.fw.model.lookup.AbstractCode;
import gov.va.med.fw.ui.UIConstants;
import gov.va.med.fw.util.StringUtils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
// Library Classes
// Framework Classes
// ESR Classes

/**
 * The conversion service for the demographic addresses screen.
 *
 * @author Andrew Pach
 * @version 1.0
 */
public class DemographicAddressesConversionService extends AddressConversionService
{
    // The order that the phone types should be displayed on the screen
    private static final List PHONE_TYPE_ORDER = new ArrayList();

    // The order that the email types should be displayed on the screen
    private static final List EMAIL_TYPE_ORDER = new ArrayList();

    /**
     * Default constructor.
     */
    public DemographicAddressesConversionService()
    {
        super();

        // Initialize the phone type order
        PHONE_TYPE_ORDER.add(PhoneType.CODE_HOME);
        PHONE_TYPE_ORDER.add(PhoneType.CODE_BUSINESS);
        PHONE_TYPE_ORDER.add(PhoneType.CODE_MOBILE);
        PHONE_TYPE_ORDER.add(PhoneType.CODE_PAGER);
        PHONE_TYPE_ORDER.add(PhoneType.CODE_FAX);

        // Initialize the email type order
        EMAIL_TYPE_ORDER.add(EmailType.CODE_PRIVATE);
        EMAIL_TYPE_ORDER.add(EmailType.CODE_BUSINESS);
    }

    /**
     * Converts between a Person object that contains the addresses information and the DemographicAddressesForm.
     *
     * @param source the source object
     * @param target the target object
     *
     * @throws gov.va.med.fw.conversion.ConversionServiceException if any errors were encountered during the
     * conversion.
     */
    protected void convertBean(Object source, Object target) throws ConversionServiceException
    {
        Person person = null;
        DemographicAddressesForm form = null;

        if (source instanceof Person)
        {
            person = (Person)source;
            if (target instanceof DemographicAddressesForm)
            {
                form = (DemographicAddressesForm)target;
            }
            else
            {
                throw new ConversionServiceException("Target object is of type " + target.getClass().getName() +
                    " and must be of type DemographicAddressesForm.");
            }

            // Convert from the Person to the form
            convertPersonToForm(person, form);
        }
        else
        {
            if (source instanceof DemographicAddressesForm)
            {
                form = (DemographicAddressesForm)source;
                if (target instanceof Person)
                {
                    person = (Person)target;
                }
                else
                {
                    throw new ConversionServiceException("Target object is of type " + target.getClass().getName() +
                        " and must be of type Person.");
                }

                // Convert from the Form to Person
                convertFormToPerson(form, person);
            }
            else
            {
                throw new ConversionServiceException("Source object is of type " + target.getClass().getName() +
                    " and must be of type Person or DemographicAddressesForm.");
            }
        }
    }

    /**
     * Converts the addresses data from the Person object to the form.
     *
     * @param person The person
     * @param form The form
     *
     * @throws ConversionServiceException If there were any problems converting the person to the form.
     */
    protected void convertPersonToForm(Person person, DemographicAddressesForm form) throws ConversionServiceException
    {
        try
        {
            // Get the contact methods
            ArrayList phones = new ArrayList(person.getPhones());
            ArrayList emails = new ArrayList(person.getEmails());

            // Get the permanent address
            Address address = null;
            
            String addressType = form.getAddressType();
            
            
            if(addressType != null){
	            if(AddressType.CODE_PERMANENT_ADDRESS.getCode().equals(addressType)){
	            	address = person.getPermanentAddress();
	            }else if(AddressType.CODE_TEMPORARY_CORRESPONDENCE_ADDRESS.getCode().equals(addressType)){
	            	address = person.getTemporaryCorrespondenceAddress();
	            }else if(AddressType.CODE_RESIDENTIAL_ADDRESS.getCode().equals(addressType)){
	            	address = person.getResidentialAddress();
	            }else if(AddressType.CODE_CONFIDENTIAL_ADDRESS.getCode().equals(addressType)){
	            	address = person.getConfidentialAddress();
	            }
            }else {
            	//For now Keep the existing code. 
            	address = person.getPermanentAddress();
            }

            // Convert the standard address fields (will set only the country if null)
            convertAddressToForm(address, form);

            // Update country to United States if a country isn't set currently.
            if (StringUtils.isBlank(form.getCountry()))
            {
                form.setCountry(Country.CODE_USA.getName());
            }

            // Default the Source of Change to HEC (per 2763[UC14.22]).
            form.setPermAddrSourceOfUpdate(AddressChangeSource.CODE_HEC.getName());

            // Default the Site of Change to HEC (per 4117[UC14.30.1])
            form.setPermAddrSiteOfUpdate(VAFacility.CODE_HEC.getName());
            
            if (address != null)
            {
            	boolean isAddAPerson = form.isAddAPerson();
                form.setPermAddrCurrent(DateUtils.isDateBetween(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(address.getStartDate()),
                    DateUtils.getEndOfDay(address.getEndDate())));
                form.setPermAddrInFuture(DateUtils.isDateBefore(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(address.getStartDate())));
                form.setPermAddrInPast(DateUtils.isDateAfter(
                    new ImpreciseDate(new Date()), DateUtils.getEndOfDay(address.getEndDate())));

                if (address.getBadAddressReason() != null)
                {
                    form.setPermBadAddressReason(address.getBadAddressReason().getCode());
                }
                
                String strFormat = null;
                //  if (isAddAPerson)
            	//		strFormat = DateUtils.MMDDYYYYHHMMSS_EDIT;
                if (address.getChangeDate() != null)
                {
                    form.setPermAddrLastUpdate(DateUtils.formatWithTime(address.getChangeDate(),strFormat));
                }
                else {
	                if (isAddAPerson){
	                	Date current = DateUtils.getCurrentDateTime();
	              		form.setPermAddrLastUpdate(DateUtils.formatWithTime(current, strFormat));
	                }
                }
                
                if (address.getChangeSource() != null)
                {
                    form.setPermAddrSourceOfUpdate(address.getChangeSource().getCode());
                }
                if (address.getChangeSite() != null)
                {
                    form.setPermAddrSiteOfUpdate(address.getChangeSite().getCode());
                }
            }



            
            // Get the confidential permanent address
            Address confAddress = person.getConfidentialAddress();
            if (confAddress != null)
            {
                form.setConfAddrPresent(true);
                form.setConfAddrCurrent(DateUtils.isDateBetween(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(confAddress.getStartDate()),
                    DateUtils.getEndOfDay(confAddress.getEndDate())));
                form.setConfAddrInFuture(DateUtils.isDateBefore(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(confAddress.getStartDate())));
                form.setConfAddrInPast(DateUtils.isDateAfter(
                    new ImpreciseDate(new Date()), DateUtils.getEndOfDay(confAddress.getEndDate())));
                
                //294730 - Confidential Address to allow view/edit of correspondence types.
                if(person.getConfidentialAddressCategories()!=null){
                	
                    List confAddrCategories = getConfAddrCategories(person);
                    String[] selectedCategory = new String[confAddrCategories.size()];
                    if(confAddrCategories!= null && !confAddrCategories.isEmpty()){
                    	for(int i=0; i<confAddrCategories.size(); i++){
                        	ConfidentialAddressCategoryType catType = (ConfidentialAddressCategoryType) confAddrCategories.get(i);
                        	selectedCategory[i] = catType.getCode();
                        }
                    }           
                    form.setConfAddrCategories(confAddrCategories);  
                    form.setSelectedConfAddrCategories(selectedCategory);
                }
   
          }
            else
            {
                form.setConfAddrPresent(false);
            }

            // Get the temporary address
            Address tempAddress = person.getTemporaryCorrespondenceAddress();
            if (tempAddress != null)
            {
                form.setTempAddrPresent(true);
                form.setTempAddrCurrent(DateUtils.isDateBetween(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(tempAddress.getStartDate()),
                    DateUtils.getEndOfDay(tempAddress.getEndDate())));
                form.setTempAddrInFuture(DateUtils.isDateBefore(
                    new ImpreciseDate(new Date()), DateUtils.getBeginningOfDay(tempAddress.getStartDate())));
                form.setTempAddrInPast(DateUtils.isDateAfter(
                    new ImpreciseDate(new Date()), DateUtils.getEndOfDay(tempAddress.getEndDate())));
            }
            else
            {
                form.setTempAddrPresent(false);
            }

           
            //#294726-Confidential/Temporary addresses need start/end dates
            if (form.getAddressType() != null)
            {
            if(form.getAddressType().equalsIgnoreCase(UIConstants.TEMPORARY_ADDRESS_TYPE)||form.getAddressType().equalsIgnoreCase(UIConstants.CONFIDENTIAL_ADDRESS_TYPE)){
            	if(form.getAddressType().equalsIgnoreCase(UIConstants.TEMPORARY_ADDRESS_TYPE)){
            		if(tempAddress != null){
            		form.setStartDate(DateUtils.format(tempAddress.getStartDate(), null));
                    form.setEndDate(DateUtils.format(tempAddress.getEndDate(), null));
                   
            		}
            	}
            	else if(form.getAddressType().equalsIgnoreCase(UIConstants.CONFIDENTIAL_ADDRESS_TYPE)){
            		if(confAddress != null){
                    form.setStartDate(DateUtils.format(confAddress.getStartDate(), null));
                    form.setEndDate(DateUtils.format(confAddress.getEndDate(), null));
            		}
            	}
            }
            }

            // Iterate through all the known phone types and add them to the form.
            // Note that the getPhones method below will remove the phones of the specified type from the list
            for (Iterator iterator = PHONE_TYPE_ORDER.iterator(); iterator.hasNext();)
            {
                PhoneType.Code code = (PhoneType.Code)iterator.next();
                addPhonesToForm(getPhones(phones, code), form);
            }

            // Add any other unknown phone types left to the form
            addPhonesToForm(phones, form);

            // Iterate through all the known e-mail types and add them to the form.
            // Note that the getEmails method below will remove the e-mails of the specified type from the list
            for (Iterator iterator = EMAIL_TYPE_ORDER.iterator(); iterator.hasNext();)
            {
                EmailType.Code code = (EmailType.Code)iterator.next();
                addEmailsToForm(getEmails(emails, code), form);
            }

            // Add any other unknown email types left to the form
            addEmailsToForm(emails, form);
        }
        catch (Exception ex)
        {
            throw new ConversionServiceException("Unable to convert Person to DemographicAddressesForm.", ex);
        }
    }

	/**
     * Converts the form data to the Person object.
     *
     * @param form The form
     * @param person The person
     *
     * @throws ConversionServiceException If there were any problems converting the form to the person.
     */
    protected void convertFormToPerson(DemographicAddressesForm form, Person person) throws ConversionServiceException
    {
        LookupCacheService lookupCacheService = getLookupCacheService();

        try
        {
            //update/add primary address
            Address address = null;
            
            AddressType.Code addressTypeCode = null;
            
            if(form.getAddressType() != null){
            	addressTypeCode = AddressType.Code.getByCode(form.getAddressType());
            }
         
            if(addressTypeCode == null){
            	addressTypeCode = AddressType.CODE_PERMANENT_ADDRESS;
            }
            
            if(AddressType.CODE_PERMANENT_ADDRESS.equals(addressTypeCode)){
            	address = person.getPermanentAddress();
            }else if(AddressType.CODE_TEMPORARY_CORRESPONDENCE_ADDRESS.equals(addressTypeCode)){
            	address = person.getTemporaryCorrespondenceAddress();
            }else if(AddressType.CODE_RESIDENTIAL_ADDRESS.equals(addressTypeCode)){
            	address = person.getResidentialAddress();
            }else if(AddressType.CODE_CONFIDENTIAL_ADDRESS.equals(addressTypeCode)){
            	address = person.getConfidentialAddress();
            	
            }
            
            if (address == null)
            {
            	address = new Address();
            	
            	address.setType((AddressType)lookupCacheService.getByCodeFromCache(AddressType.class,
            			addressTypeCode.getName()));
            	
                person.addAddress(address);
            }
            
           

            // Convert the standard address fields
            convertFormToAddress(form, address);
            
            //#294726-Confidential/Temporary addresses need start/end dates
            if(form.getAddressType().equalsIgnoreCase(UIConstants.TEMPORARY_ADDRESS_TYPE)||form.getAddressType().equalsIgnoreCase(UIConstants.CONFIDENTIAL_ADDRESS_TYPE))
            {
            	if ( (form.getStartDate() != null ) && (form.getStartDate().length() > 0))
            	{
            		address.setStartDate(new ImpreciseDate (form.getStartDate()));
            	}
            	else
            	{
            		address.setStartDate(null);
            	}
            	if ((form.getEndDate() != null) && (form.getEndDate().length()>0))
            	{
            	 address.setEndDate(new ImpreciseDate (form.getEndDate()));
            	}
            	else
            	{
            		address.setEndDate(null);
            	}
            	
             	//#294730 - Confidential Address to allow view/edit of correspondence/category types
            	if(form.getAddressType().equalsIgnoreCase(UIConstants.CONFIDENTIAL_ADDRESS_TYPE)){
            		
            		person.removeAllConfidentialAddressCategories();
            		
            		if(form.getSelectedConfAddrCategories()!=null){
                		
                		String[] categorString = form.getSelectedConfAddrCategories();
                		for(int i=0; i<categorString.length; i++){
                			ConfidentialAddressCategoryType catType = this.getDemographicService().getConfidentialAddressCategoryTypesByCode(categorString[i]);
                			ConfidentialAddressCategory confAddCategory = new ConfidentialAddressCategory();
                			confAddCategory.setType(catType);
                			person.getConfidentialAddressCategories().add(confAddCategory);
                		}	
            		}
            	}
            }
            
            
            
            if (StringUtils.isNotEmpty(form.getPermBadAddressReason()))
            {
                address.setBadAddressReason((BadAddressReason)lookupCacheService.getByCodeFromCache(
                    BadAddressReason.class, form.getPermBadAddressReason()));
            }
            else
            {
                address.setBadAddressReason(null);
            }

            // Change date will be set in the DemographicService so we can use the common transaction timestamp
            // address.setChangeDate(new Date());

            if (StringUtils.isEmpty(form.getPermAddrSourceOfUpdate()))
            {
                // If no change source was entered, default to HEC
                form.setPermAddrSourceOfUpdate(AddressChangeSource.CODE_HEC.getName());
            }
            if (StringUtils.isEmpty(form.getPermAddrSiteOfUpdate()))
            {
                // If no change site was entered, default to HEC
                form.setPermAddrSiteOfUpdate(VAFacility.CODE_HEC.getName());
            }
            address.setChangeSource((AddressChangeSource)lookupCacheService.getByCodeFromCache(
                AddressChangeSource.class, form.getPermAddrSourceOfUpdate()));
            address.setChangeSite((VAFacility)lookupCacheService.getByCodeFromCache(VAFacility.class,
                form.getPermAddrSiteOfUpdate()));

            boolean isAddAPerson = form.isAddAPerson();
            if (isAddAPerson){
            	Date current = DateUtils.getCurrentDateTime(); 
            	String pAddrLastUpdate = form.getPermAddrLastUpdate();
            	// TODO ?? do we need to set last update date without null check ??
            	if (pAddrLastUpdate==null || StringUtils.isEmpty(pAddrLastUpdate))	
            		address.setChangeDate(current);
            	// else {
            		// do nothing last update is not editable
            		// address.setChangeDate(DateUtils.getDate(pAddrLastUpdate));
            	// }
            }
            	
            
            // Update/delete/add phone numbers
            List remainingPhones = new ArrayList();
            List phoneIds = form.getPhoneIdList();
            if (phoneIds != null && !phoneIds.isEmpty())
            {
                for (int i = 0; i < phoneIds.size(); i++)
                {
                    // Only add/keep the phone if the number isn't empty
                    String phoneNumber = form.getPhoneNumber(i);
                    if (StringUtils.isNotBlank(phoneNumber))
                    {
                        Phone phone = null;
                        String phoneId = (String)phoneIds.get(i);

                        // The phone should already be defined on the Person
                        if (StringUtils.isNotEmpty(phoneId))
                        {
                            phone = person.getPhoneByEntityKey(CommonEntityKeyFactory.createPhoneEntityKey(phoneId));
                        }

                        // If the phone isn't associated with the person, create it as a new one
                        if (phone == null)
                        {
                            phone = new Phone();
                        }
                        remainingPhones.add(phone);

                        // Overlay other form data on top of the Phone object.

                        // Phone Number
                        phone.setPhoneNumber(Phone.getFormattedPhone(phoneNumber));

                        // Phone Type
                        if (StringUtils.isNotEmpty(form.getPhoneType(i)))
                        {
                            phone.setType(
                                (PhoneType)lookupCacheService.getByCodeFromCache(PhoneType.class, form.getPhoneType(i)));
                        }

                        // Source of Change
                        if (StringUtils.isEmpty(form.getPhoneSourceOfUpdate(i)))
                        {
                            form.setPhoneSourceOfUpdate(i, PhoneSourceOfChange.CODE_HEC.getName());
                        }
                        phone.setSourceOfChange((PhoneSourceOfChange)lookupCacheService.getByCodeFromCache(
                            PhoneSourceOfChange.class, form.getPhoneSourceOfUpdate(i)));

                        // Site of Change
                        if (StringUtils.isEmpty(form.getPhoneSiteOfUpdate(i)))
                        {
                            form.setPhoneSiteOfUpdate(i, VAFacility.CODE_HEC.getName());
                        }
                        phone.setSiteOfChange((VAFacility)lookupCacheService.getByCodeFromCache(VAFacility.class,
                            form.getPhoneSiteOfUpdate(i)));
                    }
                }

                // Update the phones on the Person
                // get the confidential phone before remove all phones 
                // because it is not set in the form object
                Phone confidentialPhone = person.getConfidentialPhone();
                person.removeAllPhones();
                for (Iterator iterator = remainingPhones.iterator(); iterator.hasNext();)
                {
                    Phone phone = (Phone)iterator.next();
                    person.addPhone(phone);
                }
                
                //add confidential phone back if it is not null
                if (confidentialPhone !=null)
                {
                	person.addPhone(confidentialPhone);
                }
            }

            // Update/delete/add email addresses
            List remainingEmails = new ArrayList();
            List emailIds = form.getEmailIdList();
            if (emailIds != null && !emailIds.isEmpty())
            {
                for (int i = 0; i < emailIds.size(); i++)
                {
                    // Only add/keep the email if the address isn't empty
                    String emailAddress = form.getEmailAddress(i);
                    if (StringUtils.isNotBlank(emailAddress))
                    {
                        Email email = null;
                        String emailId = (String)emailIds.get(i);

                        // The email should already be defined on the Person
                        if (StringUtils.isNotEmpty(emailId))
                        {
                            email = person.getEmailByEntityKey(CommonEntityKeyFactory.createEmailEntityKey(emailId));
                        }

                        // If the phone isn't associated with the person, create it as a new one
                        if (email == null)
                        {
                            email = new Email();
                        }
                        remainingEmails.add(email);

                        // Overlay other form data on top of the Phone object.

                        // Email Address
                        email.setAddress(emailAddress);

                        // Email Type
                        if (StringUtils.isNotEmpty(form.getEmailType(i)))
                        {
                            email.setType((EmailType)lookupCacheService.getByCodeFromCache(EmailType.class,
                                form.getEmailType(i)));
                        }

                        // Source of Change
                        if (StringUtils.isEmpty(form.getEmailSourceOfUpdate(i)))
                        {
                            form.setEmailSourceOfUpdate(i, EmailSourceOfChange.CODE_HEC.getName());
                        }
                        email.setSourceOfChange((EmailSourceOfChange)lookupCacheService.getByCodeFromCache(
                            EmailSourceOfChange.class, form.getEmailSourceOfUpdate(i)));

                        // Site of Change
                        if (StringUtils.isEmpty(form.getEmailSiteOfUpdate(i)))
                        {
                            form.setEmailSiteOfUpdate(i, VAFacility.CODE_HEC.getName());
                        }
                        email.setSiteOfChange((VAFacility)lookupCacheService.getByCodeFromCache(VAFacility.class,
                            form.getEmailSiteOfUpdate(i)));
                    }
                }

                // Update the emails on the Person
                person.removeAllEmails();
                for (Iterator iterator = remainingEmails.iterator(); iterator.hasNext();)
                {
                    Email email = (Email)iterator.next();
                    person.addEmail(email);
                }
            }
        }
        catch (Exception ex)
        {
            throw new ConversionServiceException("Unable to convert DemographicAddressesForm to Person.", ex);
        }
    }

    /**
     * Gets a list of phone number of the given type.  Also removes the phones from the passed in phones list.
     *
     * @param phones the list of contact methods
     * @param phoneType The type of phones to return
     *
     * @return The list of Phone objects. An empty list will be returned if no phones of the given type are found.
     */
    protected List getPhones(List phones, PhoneType.Code phoneType)
    {
        ArrayList phoneList = new ArrayList();

        // Search through all the contacts
        if (phones != null)
        {
            for (Iterator iter = phones.iterator(); iter.hasNext();)
            {
                // Check the phone type
                Phone phone = (Phone)iter.next();
                if ((phone.getType() != null) && (phone.getType().getCode().equals(phoneType.getName())))
                {
                    phoneList.add(phone);
                    iter.remove();
                }
            }
        }

        // Return the list of phones
        return phoneList;
    }

    
    /**
     * Gets a list of email addresses of the given type.  Also removes the emails from the passed in e-mail list.
     *
     * @param emails the list of contact methods
     * @param emailType The type of email addresses to return
     *
     * @return The list of ElectronicAddress objects. An empty list will be returned if no email addresses of the given
     *         type are found.
     */
    protected List getEmails(List emails, EmailType.Code emailType)
    {
        ArrayList emailList = new ArrayList();

        // Search through all the contacts
        if (emails != null)
        {
            for (Iterator iter = emails.iterator(); iter.hasNext();)
            {
                // Check the email address type
                Email emailAddress = (Email)iter.next();
                if ((emailAddress.getType() != null) && (emailAddress.getType().getCode().equals(emailType.getName())))
                {
                    emailList.add(emailAddress);
                    iter.remove();
                }
            }
        }

        // Return the list of email addresses
        return emailList;
    }

    /**
     * Adds the list of phones to the form.
     *
     * @param phones The list of Phone objects.
     * @param form The form to add the phones to.
     */
    protected void addPhonesToForm(List phones, DemographicAddressesForm form)
    {
       	LookupCacheService lookupCacheService = getLookupCacheService();

        for (Iterator iterator = phones.iterator(); iterator.hasNext();)
        {
            Phone phone = (Phone)iterator.next();
       
            PhoneType code = phone.getType();
            if (code == null) {
            	try {
            		//Default it to HOME
            		phone.setType((PhoneType)lookupCacheService.getByCodeFromCache(PhoneType.class, "1"));
            	} catch(Exception ex) {
            		new ConversionServiceException("Unable to convert Person to DemographicAddressesForm.", ex);
            	}      
            }
            	
            // Confidential Phone is shown in the confidential address section, so
            // do not add it here
            if (PhoneType.CODE_CONFIDENTIAL.getCode().equals(phone.getType().getCode())) {
                continue;
            }
            
            // Add the phone.
            // Default the Source of Change to HEC (per 2763[UC14.22]).
            // Default the Site of Change to HEC (per 4117[UC14.30.1])
            String phoneID = null;
            if (phone.getEntityKey() == null )
            	phoneID = "";
            else
            	phoneID = phone.getEntityKey().getKeyValueAsString();       
            	
            form.addPhone(phoneID, phone.getType().getCode(),
                    phone.getFormattedPhone(), PhoneSourceOfChange.CODE_HEC.getName(),
                    VAFacility.CODE_HEC.getName(), phone.getChangeDate() == null ? "" :
                    DateUtils.formatWithTime(phone.getChangeDate(), null));
            /*
            form.addPhone(phone.getEntityKey().getKeyValueAsString(), phone.getType().getCode(),
                phone.getFormattedPhone(), PhoneSourceOfChange.CODE_HEC.getName(),
                VAFacility.CODE_HEC.getName(), phone.getChangeDate() == null ? "" :
                DateUtils.formatWithTime(phone.getChangeDate(), null));
                */
        }
    }

    /**
     * Adds the list of email addresses to the form.
     *
     * @param emailAddresses The list of ElectronicAddress objects.
     * @param form The form to add the email addresses to.
     */
    protected void addEmailsToForm(List emailAddresses, DemographicAddressesForm form)
    {
       	LookupCacheService lookupCacheService = getLookupCacheService();
        
        for (Iterator iterator = emailAddresses.iterator(); iterator.hasNext();)
        {
            Email email = (Email)iterator.next();

            // Add the email. Test
            // Default the Source of Change to HEC (per 2763[UC14.22]).
            // Default the Site of Change to HEC (per 4117[UC14.30.1])
            String emailID = null;
            if (email.getEntityKey() == null )
            	emailID = "";
            else
            	emailID = email.getEntityKey().getKeyValueAsString();
                      
            EmailType code = email.getType();
            if (code == null) {
            	try {
            		email.setType((EmailType)lookupCacheService.getByCodeFromCache(EmailType.class, "1"));
            	} catch(Exception ex) {
            		new ConversionServiceException("Unable to convert Person to DemographicAddressesForm.", ex);
            	}
            }
            
            form.addEmail(emailID, email.getType().getCode(),
                    email.getAddress(), EmailSourceOfChange.CODE_HEC.getName(),
                    VAFacility.CODE_HEC.getName(), email.getChangeDate() == null ? "" :
                    DateUtils.formatWithTime(email.getChangeDate(), null));
            /*
            form.addEmail(email.getEntityKey().getKeyValueAsString(), email.getType().getCode(),
                email.getAddress(), EmailSourceOfChange.CODE_HEC.getName(),
                VAFacility.CODE_HEC.getName(), email.getChangeDate() == null ? "" :
                DateUtils.formatWithTime(email.getChangeDate(), null));
                */
        }
    }
    
    
    /**
     * Get the list of ConfidentialAddressCategoryType's
     * @param person
     * @return
     */
    private List getConfAddrCategories(Person person) {
        // Create a list for Confidential Address Categories
        Set categoriesSource = person.getConfidentialAddressCategories();
        List categoriesTarget = new ArrayList();
        
        if (categoriesSource != null && categoriesSource.size() > 0) {            
            Object catArray[] = categoriesSource.toArray();

            for (int i=0; i < catArray.length; i++) {
                categoriesTarget.add(((ConfidentialAddressCategory)catArray[i]).getType());
            }
        }
        return categoriesTarget;
    }

}