/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

====================================================================== */
package org.bodington.spring.easyedit;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

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

import org.bodington.server.EasyEditorSession;
import org.bodington.server.events.UserEventSetup;
import org.bodington.server.realm.User;
import org.bodington.server.resources.Resource;
import org.bodington.spring.Utils;
import org.bodington.util.html.HtmlFilterFactory;
import org.bodington.util.html.nodevisitors.ReportingVisitor;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractFormController;

public class EditController extends AbstractFormController
{

    private String editView;
    private String lockedView;
    private String saveView;
    private String cancelView;
    private String cancelParameter;

    /**
     * @return the cancelParameter
     */
    public String getCancelParameter()
    {
        return cancelParameter;
    }

    /**
     * @param cancelParameter the cancelParameter to set
     */
    public void setCancelParameter(String cancelParameter)
    {
        this.cancelParameter = cancelParameter;
    }

    /**
     * @return the canelView
     */
    public String getCancelView()
    {
        return cancelView;
    }

    /**
     * @param canelView the canelView to set
     */
    public void setCancelView(String canelView)
    {
        this.cancelView = canelView;
    }

    public EditController() {
        setCommandClass(EditCommand.class);
    }
    
    /**
     * @return the editView
     */
    public String getEditView()
    {
        return editView;
    }

    /**
     * @param editView the editView to set
     */
    public void setEditView(String editView)
    {
        this.editView = editView;
    }

    /**
     * @return the lockedView
     */
    public String getLockedView()
    {
        return lockedView;
    }

    /**
     * @param lockedView the lockedView to set
     */
    public void setLockedView(String lockedView)
    {
        this.lockedView = lockedView;
    }

    /**
     * @return the saveView
     */
    public String getSaveView()
    {
        return saveView;
    }

    /**
     * @param saveView the saveView to set
     */
    public void setSaveView(String saveView)
    {
        this.saveView = saveView;
    }
    
    protected boolean isCancelled(HttpServletRequest request)
    {
        return request.getParameter(cancelParameter) != null;
    }

    protected ModelAndView processFormSubmission(HttpServletRequest request,
        HttpServletResponse response, Object command, BindException errors)
        throws Exception
    {
        EasyEditorSession session = (EasyEditorSession)Utils.getSession(request);
        EditCommand editCommand = (EditCommand)command;
        
        if (isCancelled(request))
        {
            Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                "easyedit.cancelled", "Edit Cancelled"));
            session.breakLock();
            return new ModelAndView(cancelView);
        }
        
        if (errors.hasErrors())
        {
            return showForm(request, response, errors);
        }
        
        if (session.update(editCommand.getText()))
        {
            Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                "easyedit.saved", "Edit Saved"));
            User user = Utils.getUser(request);
            Resource resource = Utils.getResource(request);
            UserEventSetup userEvents = UserEventSetup.findOrCreate(user);
            if (userEvents.containsResource(resource))
            {
            	if (!editCommand.isNotify())
            	{
            		userEvents.removeResource(resource);
                    Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                            "easyedit.notify.remove", "No more notifications."));
            	}
            }
            else
            {
            	if (editCommand.isNotify())
            	{
            		userEvents.addResource(resource);
                    Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                            "easyedit.notify.add", "You will get notifications."));
            	}
            		
            }
            return new ModelAndView(saveView, errors.getModel());
        }
        else
        {
            Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                "easyedit.locked",
                new Object[]{session.getLocker(), session.getExpire()}));
            return showForm(request, errors, editView);
        }
    }
    
    protected Object formBackingObject(HttpServletRequest request) throws Exception{
        Resource resource = Utils.getResource(request);
        User user = Utils.getUser(request);
        UserEventSetup userEvents = UserEventSetup.findOrCreate(user);
        EditCommand command = new EditCommand();
        command.setText(resource.getIntroduction());
        command.setNotify(userEvents.containsResource(resource));
        return command;
    }
    
    protected ModelAndView showForm(HttpServletRequest request,
        HttpServletResponse response, BindException errors) throws Exception
    {
        EasyEditorSession session = (EasyEditorSession)Utils.getSession(request);
        if (session.lock()) {
            ModelAndView modelView = new ModelAndView(editView, errors.getModel());
            Map refData = referenceData(request,formBackingObject(request), errors);
            if (refData != null) 
            {
                modelView.addAllObjects(refData);
            }
            modelView.addObject("expiresIn", new Long(session.getExpire()
                .getTime()
                - System.currentTimeMillis()));
            Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                "easyedit.lock",
                new Object[]{session.getExpire()}));
            return modelView;
        } else {
            Utils.saveMessage(request, getMessageSourceAccessor().getMessage(
                "easyedit.locked",
                new Object[]{session.getLocker(), session.getExpire()}));
            return showForm(request, errors, lockedView);
            
        }
    }

}
