package edu.northwestern.bioinformatics.studycalendar.web.reporting;

import edu.northwestern.bioinformatics.studycalendar.dao.UserDao;
import edu.northwestern.bioinformatics.studycalendar.dao.reporting.ScheduledActivitiesReportFilters;
import edu.northwestern.bioinformatics.studycalendar.dao.reporting.ScheduledActivitiesReportRowDao;
import edu.northwestern.bioinformatics.studycalendar.domain.ActivityType;
import edu.northwestern.bioinformatics.studycalendar.domain.Role;
import edu.northwestern.bioinformatics.studycalendar.domain.ScheduledActivityMode;
import edu.northwestern.bioinformatics.studycalendar.domain.User;
import edu.northwestern.bioinformatics.studycalendar.domain.reporting.ScheduledActivitiesReportRow;
import edu.northwestern.bioinformatics.studycalendar.utils.accesscontrol.AccessControl;
import edu.northwestern.bioinformatics.studycalendar.utils.editors.ControlledVocabularyEditor;
import edu.northwestern.bioinformatics.studycalendar.web.ControllerTools;
import gov.nih.nci.cabig.ctms.editors.DaoBasedEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author John Dzak
 */
@AccessControl(roles = {Role.STUDY_ADMIN, Role.STUDY_COORDINATOR})
public class ScheduledActivitiesReportController extends AbstractCommandController {
    private ScheduledActivitiesReportRowDao dao;
    private ControllerTools controllerTools;
    private UserDao userDao;

    public ScheduledActivitiesReportController() {
        setCommandClass(ScheduledActivitiesReportCommand.class);
    }

    protected Object getCommand(HttpServletRequest request) throws Exception {
        return new ScheduledActivitiesReportCommand(new ScheduledActivitiesReportFilters());
    }

    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        super.initBinder(request, binder);
        binder.registerCustomEditor(ScheduledActivityMode.class, "filters.currentStateMode",
            new ControlledVocabularyEditor(ScheduledActivityMode.class, true));
        binder.registerCustomEditor(ActivityType.class, "filters.activityType",
            new ControlledVocabularyEditor(ActivityType.class, true));
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
        binder.registerCustomEditor(Date.class, "filters.actualActivityDate.start", controllerTools.getDateEditor(false));
        binder.registerCustomEditor(Date.class, "filters.actualActivityDate.stop", controllerTools.getDateEditor(false));
        binder.registerCustomEditor(User.class, "filters.subjectCoordinator", new DaoBasedEditor(userDao));
    }

    protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object oCommand, BindException errors) throws Exception {
        ScheduledActivitiesReportCommand command = (ScheduledActivitiesReportCommand) oCommand;
        return new ModelAndView("reporting/scheduledActivitiesReport", createModel(errors, search(errors, command)));
    }

    private List<ScheduledActivitiesReportRow> search(Errors errors, ScheduledActivitiesReportCommand command) {
        if (errors.hasErrors()) {
            return Collections.emptyList();
        } else {
            return search(command);
        }
    }

    protected List<ScheduledActivitiesReportRow> search(ScheduledActivitiesReportCommand command) {
        return dao.search(command.getFilters());
    }

    @SuppressWarnings({"unchecked"})
    protected Map createModel(BindException errors, List<ScheduledActivitiesReportRow> results) {
        Map<String, Object> model = errors.getModel();
        model.put("modes", ScheduledActivityMode.values());
        model.put("types", ActivityType.values());
        model.put("coordinators", userDao.getAllSubjectCoordinators());
        model.put("results", results);
        model.put("resultSize", results.size());
        return model;
    }

    ////// Bean Setters
    public void setScheduledActivitiesReportRowDao(ScheduledActivitiesReportRowDao dao) {
        this.dao = dao;
    }

    public void setControllerTools(ControllerTools controllerTools) {
        this.controllerTools = controllerTools;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

@@ -959,27 +959,199 @@
 dar.
-web.ControllerTools
+utils.breadcrumbs.DefaultCrumb;%0Aimport edu.northwestern.bioinformatics.studycalendar.web.ControllerTools;%0Aimport edu.northwestern.bioinformatics.studycalendar.web.PscAbstractCommandController
 ;%0Aim
@@ -1902,16 +1902,19 @@
 extends 
+Psc
 Abstract
@@ -2169,24 +2169,70 @@
 and.class);%0A
+        setCrumb(new DefaultCrumb(%22Report%22));%0A
     %7D%0A%0A    p
@@ -3316,32 +3316,46 @@
 erDao));%0A    %7D%0A%0A
+    @Override%0A
     protected Mo
@@ -3372,16 +3372,55 @@
  handle(
+Object oCommand, BindException errors, 
 HttpServ
@@ -3471,47 +3471,8 @@
 onse
-, Object oCommand, BindException errors
 ) th

Fix for bug #438 - added breadcrumb to the report page