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

// Java Classes
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Libraries Classes
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;

// Framework Classes
import gov.va.med.fw.service.ServiceConfigurationException;
import gov.va.med.fw.validation.ValidationMessages;

// ESR Classes
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.ui.common.action.AddressValidationAction;
import gov.va.med.esr.ui.ApplicationConstants.MessageKeys;
import gov.va.med.esr.ui.common.action.AddressForm;
import gov.va.med.esr.ui.util.SessionManager;

/**
 * This struts action is used to support the demographics addresses page.
 *
 * @author Andrew Pach
 * @version 3.0
 */
public class DemographicAddressesAction extends AddressValidationAction
{
    // Struts forwards
	public static final String FORWARD_DEMOGRAPHIC_ADD_ADDRESSES = "demographicAddAddress";
    public static final String FORWARD_DEMOGRAPHIC_ADDRESSES = "demographicAddresses";
    public static final String FORWARD_DEMOGRAPHIC_OVERVIEW_SUCCESS = "demographicOverview";
    public static final String FORWARD_DEMOGRAPHIC_OVERVIEW_CANCEL = "cancel";
    public static final String FORWARD_DEMOGRAPHIC_ADDRESSES_HISTORY = "demographicAddressesHistory";
    public static final String FORWARD_508_NOTES = "address508Notes";

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

    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet()
    {
    }

    /**
     * Displays the Demographics Addresses page.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward display(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // Get a demographic addresses specific form
        DemographicAddressesForm addressesForm = getAddressesForm(form);

        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        addressesForm.setAddAPerson(isAddAPerson);
        
        // Get the Person object from the cache
        Person person = getSelectedPerson(request);
        
        String addressType = request.getParameter("addressType");

        addressesForm.setAddressType(addressType);

        // Convert all the addresses data to the form
        conversionService.convert(person, addressesForm);

        // Add a message informing the user when a country is null
        validateCountryNull(person.getPermanentAddress(), request);
        
        // Return to the addresses screen
        return mapping.findForward(FORWARD_DEMOGRAPHIC_ADD_ADDRESSES);
        
    }
    
    /**
     * Displays the add Address page.
     * 
    * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     * 
     * @return
     * @throws Exception
     */
    public ActionForward displayAddress(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
        {
    		
    	//this.display(mapping, form, request, response);
    		
    		return mapping.findForward(FORWARD_DEMOGRAPHIC_ADD_ADDRESSES);
        }

    /**
     * Handles an optimistic lock exception by resetting the form and redisplaying the page.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    protected ActionForward handleOptimisticLockException(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
    	form.reset(mapping,request);
    	return display(mapping,form,request,response);
    }

    /**
     * Updates the contact number information.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward update(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        DemographicAddressesForm addressesForm = getAddressesForm(form);

        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        addressesForm.setAddAPerson(isAddAPerson);
        
        // Get the Person object from the cache
        Person person = getSelectedPerson(request);

        // Clone the person to make updates
        Person updatedPerson = (Person)person.clone();

        // Create some action forwards
        ActionForward overviewSuccessForward =
            new ActionForward(mapping.findForward(FORWARD_DEMOGRAPHIC_OVERVIEW_SUCCESS));
        ActionForward demographicAddressesForward = mapping.findForward(FORWARD_DEMOGRAPHIC_ADDRESSES);

        // Perform US extra validation
        if (Country.isUSAddress(addressesForm.getCountry()))
        {
            // Validate the state
            if (!stateValid(addressesForm, AddressForm.class, STATE_FIELD, overviewSuccessForward, request))
            {
                return demographicAddressesForward;
            }

            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(
                addressesForm, AddressForm.class, CITY_FIELD, STATE_FIELD, ZIPCODE_FIELD, request))
            {
                return demographicAddressesForward;
            }
        }

        if ("C".equals(addressesForm.getAddressType()) || "CNF".equals(addressesForm.getAddressType()))
        {
        	/*if ((addressesForm.getStartDate() == null))
        	{
        		addActionMessageForField(request, new ActionMessage(START_DATE_NULL),
        				START_DATE_FIELD);
        		return demographicAddressesForward;
        	}
        	if ((addressesForm.getEndDate() == null))
        	{
        		addActionMessageForField(request, new ActionMessage(START_DATE_NULL),
        				END_DATE_FIELD);
        		return demographicAddressesForward;
        	}*/
        	
        	String startDate = addressesForm.getStartDate();
        	String endDate = addressesForm.getEndDate();
        	if (startDate == null)
			{
				if ((endDate != null) && (endDate.trim().length()>0))
				{
					addActionMessageForField(request,
							new ActionMessage(MessageKeys.ERRORS_INVALID_EMPTY_DATE),START_DATE_FIELD);
				}
			}
			if ((startDate != null) && (startDate.trim().length() == 0))
			{
				if ((endDate != null) && (endDate.trim().length()>0))
				{
					addActionMessageForField(request,
							new ActionMessage(MessageKeys.ERRORS_INVALID_EMPTY_DATE),START_DATE_FIELD);
				}
			}
			if ((startDate != null) && (startDate.trim().length() > 0))
			{
					
				if (endDate == null)
				{
					addActionMessageForField(request,
							new ActionMessage(MessageKeys.ERRORS_INVALID_EMPTY_DATE),END_DATE_FIELD);
			
				}
				if (endDate.trim().length()==0)
				{
					addActionMessageForField(request,
							new ActionMessage(MessageKeys.ERRORS_INVALID_EMPTY_DATE),END_DATE_FIELD);
				
				}
			}
        }
        // Convert the form data onto the updated Person object
        conversionService.convert(addressesForm, updatedPerson);

        if (!isAddAPerson)
        // Call service layer here
        	updatedPerson = getDemographicService().updateContactInformation(updatedPerson);

        // Store updated person in the cache
        updateSelectedPerson(request, updatedPerson);

        // Return to the overview screen
        return overviewSuccessForward;

    }

    /**
     * Resets the data to its original state.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward reset(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        DemographicAddressesForm addressesForm = getAddressesForm(form);
        addressesForm.reset(mapping, request);
        return display(mapping, form, request, response);
    }

    /**
     * Cancels screen by going back to the demographics overview page.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward cancel(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        return mapping.findForward(FORWARD_DEMOGRAPHIC_OVERVIEW_CANCEL);
    }

    /**
     * Updates the contact number information.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward addPhoneNumber(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        DemographicAddressesForm addressesForm = getAddressesForm(form);
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        addressesForm.setAddAPerson(isAddAPerson);
        addressesForm.addNewPhone();
        addressesForm.setAddPhoneType(addressesForm.getPhoneIdList().size() - 1);
        return mapping.findForward(FORWARD_DEMOGRAPHIC_ADD_ADDRESSES);
    }

    /**
     * Updates the contact number information.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward addEmailAddress(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        DemographicAddressesForm addressesForm = getAddressesForm(form);
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        addressesForm.setAddAPerson(isAddAPerson);
        addressesForm.addNewEmail();
        addressesForm.setAddEmailType(addressesForm.getEmailIdList().size() - 1);
        return mapping.findForward(FORWARD_DEMOGRAPHIC_ADD_ADDRESSES);
    }

    /**
     * Checks to ensure the passed in ActionForm is not null and of the correct type.
     *
     * @param form The struts form to check
     *
     * @return The passed in form type-casted to a DemographicAddressesForm
     * @throws ServiceConfigurationException if the form is null or of an incorrect type.
     */
    protected DemographicAddressesForm getAddressesForm(ActionForm form) throws ServiceConfigurationException
    {
        DemographicAddressesForm addressesForm =
            (form instanceof DemographicAddressesForm) ? (DemographicAddressesForm)form : null;
        if (addressesForm == null)
        {
            throw new ServiceConfigurationException("DemographicAddressesForm not properly configured.");
        }
        return addressesForm;
    }

    /**
     * Cancels this page and goes to the view 508 notes page.
     *
     * @param mapping Struts action mapping for this action
     * @param form Struts form bean for this action
     * @param request The Http Request
     * @param response The Http Response
     *
     * @return A struts action forward for where we will go next.
     * @throws Exception If there are any errors during processing.
     */
    public ActionForward goto508Notes(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        return mapping.findForward(FORWARD_508_NOTES);
    }
    
    /**
     * Initialize and get the Struts lookup dispatch method map hashmap.
     *
     * @return the method map
     * @see org.apache.struts.actions.LookupDispatchAction#getKeyMethodMap()
     */
    protected Map getKeyMethodMap()
    {
        Map map = new HashMap();
        map.put("button.cancel", "cancel");
        map.put("button.update", "update");
        map.put("button.reset", "reset");
        map.put("button.addPhoneNumber", "addPhoneNumber");
        map.put("button.addEmailAddress", "addEmailAddress");
        map.put("button.viewAddress508Notes", "goto508Notes");
        map.put("text.subMenu.addresses", "display");
        map.put("text.addAddressLink", "displayAddress");
        
        return map;
    }
}