/**
 * Copyright (c) 2006 Red Hat, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Component of: Red Hat Application Server
 * 
 * Initial Developers: Greg Lapouchnian
 *                     Patrick Smith
 *
 */

package olstore.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import olstore.domain.logic.OlstoreFacade;
import olstore.dto.AddressValue;
import olstore.dto.UserValue;

import org.springframework.validation.BindException;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

/**
 * Controller class used for editing a user's profile.
 */
public class EditUserController extends SimpleFormController {

    // olstore instance injected by Spring.
    private OlstoreFacade olstore;

    /**
     * Creates a new form object with default values set, such as
     * what command class to use as the backing object, and which views to use.
     */
    public EditUserController() {
            setSessionForm(true);
            setValidateOnBinding(false);
            setCommandClass(UserForm.class);
            setFormView("editUser");
            setSuccessView("editUser");
    }

    /**
     * Spring injection method for setting the olstore bean instance.
     * @param olstore the instance of olstore injected via spring.
     */
    public void setOlstore(OlstoreFacade olstore) {
        this.olstore = olstore;
    }

    /**
     * Returns the backing object that this form will use.
     * 
     * @param request the HttpServletRequest
     * @return this form's backing object.
     */
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
            String user = request.getRemoteUser();
            
            // Supply the form backing object UserForm with the User and Address DTOs
            UserValue userValue = olstore.getUser(user);
            AddressValue addressValue = new AddressValue();
            addressValue.setStreet1(userValue.getAddress().getStreet1());
            addressValue.setStreet2(userValue.getAddress().getStreet2());
            addressValue.setCity(userValue.getAddress().getCity());
            addressValue.setProvince(userValue.getAddress().getProvince());
            addressValue.setPostalCode(userValue.getAddress().getPostalCode());
            addressValue.setCountry(userValue.getAddress().getCountry());
   
            return new UserForm(userValue, addressValue);
    }

    /**
     * Validation method to handle the command's fields.
     * 
     * @param request the HttpServletRequest.
     * @param command the backing object for this form.
     * @param errors the errors to report when validation fails.
     */
    protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors)
                    throws Exception {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "user.fname", "FNAME_REQUIRED", "First name is required.");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "user.lname", "LNAME_REQUIRED", "Last name is required.");
        // TODO 
    }

    /**
     * Returns the map model to use for this form's view.
     * 
     * @param request the HttpServletRequest.
     * @return a model to be used on this form's view.
     */
    protected Map referenceData(HttpServletRequest request) throws Exception {
        Map model = ControllerHelper.initModel(request, olstore);
        model.put("page_title", "Edit Your Information - Olstore");
        model.put("allUsers", this.olstore.getAllUsers());
        return model;
    }

    /**
     * Handles the submission of this form.
     * 
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param command this forms backing object.
     * @param errors this form's errors as reported via validation.
     * @return a new model and view to represent this form.
     */
    protected ModelAndView onSubmit(
                    HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
                    throws Exception {
        // supply the errors to the view inside the model map
        Map model = errors.getModel();
        // add the reference data once again so it will continue to be displayed
        model.putAll(referenceData(request));
        
        UserForm userForm = (UserForm) command;
        try {
            if(userForm.getUser().getFriendsListSelected() == null) {
                userForm.getUser().setFriendsListSelected(new String[] {});
            }
        
           this.olstore.saveUser(userForm.getUser(), userForm.getAddress(), userForm.getUser().getUsername());
        }
        catch (Exception ex) {            
            model.put("error", "There was an error trying to save your account information.");
            return showForm(request, response, errors, model);
        }
            
        model.put("message", "Your information has been successfully updated.");
        model.put("command", formBackingObject(request));
        return new ModelAndView("editUser", model);
    }
}