/**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    Long fileId = pageRequestContext.getLong("fileId");

    StudentFileDAO studentFileDAO = DAOFactory.getInstance().getStudentFileDAO();
    FileTypeDAO fileTypeDAO = DAOFactory.getInstance().getFileTypeDAO();
    List<FileType> fileTypes = fileTypeDAO.listUnarchived();
    Collections.sort(fileTypes, new StringAttributeComparator("getName"));

    pageRequestContext.getRequest().setAttribute("file", studentFileDAO.findById(fileId));
    pageRequestContext.getRequest().setAttribute("fileTypes", fileTypes);
    pageRequestContext.setIncludeJSP("/templates/studentfiles/editfile.jsp");
  }
  /**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    ReportDAO reportDAO = DAOFactory.getInstance().getReportDAO();

    List<Report> reports = reportDAO.listByContextType(ReportContextType.Common);
    Collections.sort(
        reports,
        new Comparator<Report>() {
          @Override
          public int compare(Report o1, Report o2) {
            String s1 = o1.getCategory() == null ? null : o1.getCategory().getName();
            String s2 = o2.getCategory() == null ? null : o2.getCategory().getName();
            int cmp = s1 == null ? 1 : s2 == null ? -1 : s1.compareToIgnoreCase(s2);
            if (cmp == 0) {
              cmp = o1.getName().compareToIgnoreCase(o2.getName());
            }
            return cmp;
          }
        });

    pageRequestContext.getRequest().setAttribute("reports", reports);
    pageRequestContext.setIncludeJSP("/templates/reports/listreports.jsp");
  }
  /**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    SubjectDAO subjectDAO = DAOFactory.getInstance().getSubjectDAO();
    SchoolDAO schoolDAO = DAOFactory.getInstance().getSchoolDAO();
    EducationalTimeUnitDAO educationalTimeUnitDAO =
        DAOFactory.getInstance().getEducationalTimeUnitDAO();

    List<Subject> subjects = subjectDAO.listUnarchived();
    Collections.sort(subjects, new StringAttributeComparator("getName"));

    List<EducationalTimeUnit> timeUnits = educationalTimeUnitDAO.listUnarchived();
    Collections.sort(timeUnits, new StringAttributeComparator("getName"));

    List<School> schools = schoolDAO.listUnarchived();
    Collections.sort(schools, new StringAttributeComparator("getName"));

    String jsonSubjects = new JSONArrayExtractor("name", "id").extractString(subjects);
    String jsonTimeUnits = new JSONArrayExtractor("name", "id").extractString(timeUnits);

    this.setJsDataVariable(pageRequestContext, "subjects", jsonSubjects);
    this.setJsDataVariable(pageRequestContext, "timeUnits", jsonTimeUnits);

    pageRequestContext.setIncludeJSP("/templates/settings/createtransfercredittemplate.jsp");
  }
  /**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    SubjectDAO subjectDAO = DAOFactory.getInstance().getSubjectDAO();
    EducationTypeDAO educationTypeDAO = DAOFactory.getInstance().getEducationTypeDAO();

    List<Subject> subjects = subjectDAO.listUnarchived();
    Collections.sort(subjects, new StringAttributeComparator("getName"));

    List<EducationType> educationTypes = educationTypeDAO.listUnarchived();
    Collections.sort(educationTypes, new StringAttributeComparator("getName"));

    JSONArray jsonSubjects = new JSONArrayExtractor("name", "code", "id").extract(subjects);
    for (int i = 0; i < jsonSubjects.size(); i++) {
      JSONObject jsonStudyProgrammeCategory = jsonSubjects.getJSONObject(i);
      if (subjects.get(i).getEducationType() != null)
        jsonStudyProgrammeCategory.put(
            "educationTypeId", subjects.get(i).getEducationType().getId());
    }
    String jsonEducationTypes = new JSONArrayExtractor("name", "id").extractString(educationTypes);

    this.setJsDataVariable(pageRequestContext, "subjects", jsonSubjects.toString());
    this.setJsDataVariable(pageRequestContext, "educationTypes", jsonEducationTypes);
    pageRequestContext.setIncludeJSP("/templates/settings/subjects.jsp");
  }
  /**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    UserDAO userDAO = DAOFactory.getInstance().getUserDAO();
    StudentDAO studentDAO = DAOFactory.getInstance().getStudentDAO();
    CourseStudentDAO courseStudentDAO = DAOFactory.getInstance().getCourseStudentDAO();
    StudentProjectDAO studentProjectDAO = DAOFactory.getInstance().getStudentProjectDAO();
    StudentProjectModuleDAO studentProjectModuleDAO =
        DAOFactory.getInstance().getStudentProjectModuleDAO();
    GradingScaleDAO gradingScaleDAO = DAOFactory.getInstance().getGradingScaleDAO();
    ProjectAssessmentDAO projectAssessmentDAO = DAOFactory.getInstance().getProjectAssessmentDAO();
    AcademicTermDAO academicTermDAO = DAOFactory.getInstance().getAcademicTermDAO();
    EducationalTimeUnitDAO educationalTimeUnitDAO =
        DAOFactory.getInstance().getEducationalTimeUnitDAO();
    CreditLinkDAO creditLinkDAO = DAOFactory.getInstance().getCreditLinkDAO();
    CourseAssessmentDAO courseAssessmentDAO = DAOFactory.getInstance().getCourseAssessmentDAO();
    TransferCreditDAO transferCreditDAO = DAOFactory.getInstance().getTransferCreditDAO();

    Long studentProjectId = pageRequestContext.getLong("studentproject");
    List<GradingScale> gradingScales = gradingScaleDAO.listUnarchived();

    StudentProject studentProject = studentProjectDAO.findById(studentProjectId);
    List<StudentProjectModule> studentProjectModules =
        studentProjectModuleDAO.listByStudentProject(studentProject);
    List<CourseStudent> courseStudents =
        courseStudentDAO.listByStudent(studentProject.getStudent());

    List<CourseAssessment> allStudentCourseAssessments =
        courseAssessmentDAO.listByStudent(studentProject.getStudent());
    List<TransferCredit> allStudentTransferCredits =
        transferCreditDAO.listByStudent(studentProject.getStudent());
    List<CreditLink> allStudentCreditLinks =
        creditLinkDAO.listByStudent(studentProject.getStudent());

    JSONArray studentProjectModulesJSON = new JSONArray();
    JSONArray courseStudentsJSON = new JSONArray();

    for (CreditLink creditLink : allStudentCreditLinks) {
      switch (creditLink.getCredit().getCreditType()) {
        case CourseAssessment:
          allStudentCourseAssessments.add(((CourseAssessment) creditLink.getCredit()));
          break;

        case TransferCredit:
          allStudentTransferCredits.add(((TransferCredit) creditLink.getCredit()));
          break;
      }
    }

    Collections.sort(
        studentProjectModules,
        new Comparator<StudentProjectModule>() {
          @Override
          public int compare(StudentProjectModule o1, StudentProjectModule o2) {
            return o1.getModule().getName().compareTo(o2.getModule().getName());
          }
        });

    for (StudentProjectModule studentProjectModule : studentProjectModules) {
      JSONArray moduleCourseStudents = new JSONArray();
      JSONArray moduleCredits = new JSONArray();
      boolean hasPassingGrade = false;

      List<CourseStudent> projectCourseCourseStudents =
          courseStudentDAO.listByModuleAndStudent(
              studentProjectModule.getModule(), studentProject.getStudent());

      for (CourseStudent courseStudent : projectCourseCourseStudents) {
        JSONObject courseStudentJson = new JSONObject();
        courseStudentJson.put(
            "courseStudentParticipationType", courseStudent.getParticipationType().getName());
        //        courseStudents.remove(courseStudent);
        moduleCourseStudents.add(courseStudentJson);
      }

      for (CourseAssessment assessment : allStudentCourseAssessments) {
        if (assessment
            .getCourseStudent()
            .getCourse()
            .getModule()
            .getId()
            .equals(studentProjectModule.getModule().getId())) {
          if (assessment.getGrade() != null) {
            JSONObject courseAssessment = new JSONObject();

            courseAssessment.put("creditType", assessment.getCreditType().toString());
            courseAssessment.put("courseName", assessment.getCourseStudent().getCourse().getName());
            courseAssessment.put("gradeName", assessment.getGrade().getName());

            moduleCredits.add(courseAssessment);
            hasPassingGrade = hasPassingGrade || assessment.getGrade().getPassingGrade();
          }
        }
      }

      if ((studentProjectModule.getModule().getCourseNumber() != null)
          && (studentProjectModule.getModule().getCourseNumber() != -1)
          && (studentProjectModule.getModule().getSubject() != null)) {
        for (TransferCredit tc : allStudentTransferCredits) {
          if ((tc.getCourseNumber() != null)
              && (tc.getCourseNumber() != -1)
              && (tc.getSubject() != null)) {
            if (tc.getCourseNumber().equals(studentProjectModule.getModule().getCourseNumber())
                && tc.getSubject().equals(studentProjectModule.getModule().getSubject())) {
              if (tc.getGrade() != null) {
                JSONObject transferCredit = new JSONObject();

                transferCredit.put("creditType", tc.getCreditType().toString());
                transferCredit.put("courseName", tc.getCourseName());
                transferCredit.put("gradeName", tc.getGrade().getName());

                moduleCredits.add(transferCredit);
                hasPassingGrade = hasPassingGrade || tc.getGrade().getPassingGrade();
              }
            }
          }
        }
      }

      JSONObject obj = new JSONObject();

      obj.put("projectModuleId", studentProjectModule.getId().toString());
      obj.put("projectModuleOptionality", studentProjectModule.getOptionality().toString());
      obj.put(
          "projectModuleAcademicTermId",
          studentProjectModule.getAcademicTerm() != null
              ? studentProjectModule.getAcademicTerm().getId().toString()
              : "");
      obj.put("projectModuleHasPassingGrade", hasPassingGrade ? "1" : "0");
      obj.put("moduleId", studentProjectModule.getModule().getId());
      obj.put("moduleName", studentProjectModule.getModule().getName());

      obj.put("moduleCourseStudents", moduleCourseStudents);
      obj.put("moduleCredits", moduleCredits);

      studentProjectModulesJSON.add(obj);
    }

    List<Student> students =
        studentDAO.listByAbstractStudent(studentProject.getStudent().getAbstractStudent());
    Collections.sort(
        students,
        new Comparator<Student>() {
          @Override
          public int compare(Student o1, Student o2) {
            /**
             * Ordering study programmes as follows 1. studies that have start date but no end date
             * (ongoing) 2. studies that have no start nor end date 3. studies that have ended 4.
             * studies that are archived 5. other
             */
            int o1class =
                (o1.getArchived())
                    ? 4
                    : (o1.getStudyStartDate() != null && o1.getStudyEndDate() == null)
                        ? 1
                        : (o1.getStudyStartDate() == null && o1.getStudyEndDate() == null)
                            ? 2
                            : (o1.getStudyEndDate() != null) ? 3 : 5;
            int o2class =
                (o2.getArchived())
                    ? 4
                    : (o2.getStudyStartDate() != null && o2.getStudyEndDate() == null)
                        ? 1
                        : (o2.getStudyStartDate() == null && o2.getStudyEndDate() == null)
                            ? 2
                            : (o2.getStudyEndDate() != null) ? 3 : 5;

            if (o1class == o2class) {
              // classes are the same, we try to do last comparison from the start dates
              return ((o1.getStudyStartDate() != null) && (o2.getStudyStartDate() != null))
                  ? o2.getStudyStartDate().compareTo(o1.getStudyStartDate())
                  : 0;
            } else return o1class < o2class ? -1 : o1class == o2class ? 0 : 1;
          }
        });

    List<EducationalTimeUnit> educationalTimeUnits = educationalTimeUnitDAO.listUnarchived();
    Collections.sort(educationalTimeUnits, new StringAttributeComparator("getName"));

    List<AcademicTerm> academicTerms = academicTermDAO.listUnarchived();
    Collections.sort(
        academicTerms,
        new Comparator<AcademicTerm>() {
          public int compare(AcademicTerm o1, AcademicTerm o2) {
            return o1.getStartDate() == null
                ? -1
                : o2.getStartDate() == null ? 1 : o1.getStartDate().compareTo(o2.getStartDate());
          }
        });

    List<ProjectAssessment> assessments = projectAssessmentDAO.listByProject(studentProject);
    Collections.sort(
        assessments,
        new Comparator<ProjectAssessment>() {
          @Override
          public int compare(ProjectAssessment o1, ProjectAssessment o2) {
            return o2.getDate().compareTo(o1.getDate());
          }
        });

    Collections.sort(
        courseStudents,
        new Comparator<CourseStudent>() {
          @Override
          public int compare(CourseStudent o1, CourseStudent o2) {
            return o1.getCourse().getName().compareTo(o2.getCourse().getName());
          }
        });

    for (CourseStudent courseStudent : courseStudents) {
      CourseAssessment courseAssessment = courseAssessmentDAO.findByCourseStudent(courseStudent);
      Grade grade = courseAssessment != null ? courseAssessment.getGrade() : null;

      JSONObject obj = new JSONObject();

      String courseName = courseStudent.getCourse().getName();
      if (!StringUtils.isEmpty(courseStudent.getCourse().getNameExtension()))
        courseName = courseName + " (" + courseStudent.getCourse().getNameExtension() + ")";

      obj.put("courseName", courseName);

      if (courseStudent.getParticipationType() != null) {
        obj.put("participationType", courseStudent.getParticipationType().getName());
      }
      if (courseStudent.getCourse().getBeginDate() != null) {
        obj.put("courseBeginDate", courseStudent.getCourse().getBeginDate().getTime());
      }
      if (courseStudent.getCourse().getEndDate() != null) {
        obj.put("courseEndDate", courseStudent.getCourse().getEndDate().getTime());
      }

      obj.put("gradeName", grade != null ? grade.getName() : "");

      if (courseStudent.getOptionality() != null) {
        obj.put("optionality", courseStudent.getOptionality().toString());
      }
      obj.put("moduleId", courseStudent.getCourse().getModule().getId().toString());
      obj.put("courseId", courseStudent.getCourse().getId().toString());
      obj.put("courseStudentId", courseStudent.getId().toString());

      courseStudentsJSON.add(obj);
    }

    Map<Long, String> verbalAssessments = new HashMap<Long, String>();

    for (ProjectAssessment pAss : assessments) {
      // Shortened descriptions
      String description = pAss.getVerbalAssessment();
      if (description != null) {
        description = StringEscapeUtils.unescapeHtml(description.replaceAll("\\<.*?>", ""));
        description = description.replaceAll("\\n", "");

        verbalAssessments.put(pAss.getId(), description);
      }
    }

    /* Tags */

    StringBuilder tagsBuilder = new StringBuilder();
    Iterator<Tag> tagIterator = studentProject.getTags().iterator();
    while (tagIterator.hasNext()) {
      Tag tag = tagIterator.next();
      tagsBuilder.append(tag.getText());
      if (tagIterator.hasNext()) tagsBuilder.append(' ');
    }

    pageRequestContext.getRequest().setAttribute("projectAssessments", assessments);
    pageRequestContext.getRequest().setAttribute("verbalAssessments", verbalAssessments);
    pageRequestContext.getRequest().setAttribute("studentProject", studentProject);
    pageRequestContext.getRequest().setAttribute("students", students);
    pageRequestContext
        .getRequest()
        .setAttribute("optionalStudiesLengthTimeUnits", educationalTimeUnits);
    pageRequestContext.getRequest().setAttribute("academicTerms", academicTerms);
    pageRequestContext.getRequest().setAttribute("users", userDAO.listAll());
    pageRequestContext.getRequest().setAttribute("gradingScales", gradingScales);
    pageRequestContext.getRequest().setAttribute("tags", tagsBuilder.toString());

    setJsDataVariable(
        pageRequestContext, "studentProjectModules", studentProjectModulesJSON.toString());
    setJsDataVariable(pageRequestContext, "courseStudents", courseStudentsJSON.toString());

    pageRequestContext.setIncludeJSP("/templates/projects/editstudentproject.jsp");
  }
  /**
   * Processes the page request.
   *
   * <p>In parameters - person
   *
   * <p>Page parameters - person - Person object - contactEntries - List of StudentContactLogEntry
   * objects
   *
   * @param pageRequestContext pageRequestContext
   */
  public void process(PageRequestContext pageRequestContext) {
    StudentGroupContactLogEntryDAO logEntryDAO =
        DAOFactory.getInstance().getStudentGroupContactLogEntryDAO();
    StudentGroupContactLogEntryCommentDAO entryCommentDAO =
        DAOFactory.getInstance().getStudentGroupContactLogEntryCommentDAO();
    StudentGroupDAO studentGroupDAO = DAOFactory.getInstance().getStudentGroupDAO();

    Long studentGroupId = pageRequestContext.getLong("studentgroup");

    StudentGroup studentGroup = studentGroupDAO.findById(studentGroupId);

    pageRequestContext.getRequest().setAttribute("studentGroup", studentGroup);

    final Map<Long, List<StudentGroupContactLogEntryComment>> contactEntryComments =
        new HashMap<Long, List<StudentGroupContactLogEntryComment>>();
    List<StudentGroupContactLogEntry> contactLogEntries =
        logEntryDAO.listByStudentGroup(studentGroup);

    // Populate comments for each entry to lists

    for (int j = 0; j < contactLogEntries.size(); j++) {
      StudentGroupContactLogEntry entry = contactLogEntries.get(j);

      List<StudentGroupContactLogEntryComment> listComments = entryCommentDAO.listByEntry(entry);

      Collections.sort(
          listComments,
          new Comparator<StudentGroupContactLogEntryComment>() {
            public int compare(
                StudentGroupContactLogEntryComment o1, StudentGroupContactLogEntryComment o2) {
              Date d1 = o1.getCommentDate();
              Date d2 = o2.getCommentDate();

              int val = d1 == null ? d2 == null ? 0 : 1 : d2 == null ? -1 : d1.compareTo(d2);

              if (val == 0) return o1.getId().compareTo(o2.getId());
              else return val;
            }
          });

      contactEntryComments.put(entry.getId(), listComments);
    }

    // Now we can sort entries based on date of entry and/or dates of the comments on the entry

    Collections.sort(
        contactLogEntries,
        new Comparator<StudentGroupContactLogEntry>() {

          private Date getDateForEntry(StudentGroupContactLogEntry entry) {
            Date d = entry.getEntryDate();

            List<StudentGroupContactLogEntryComment> comments =
                contactEntryComments.get(entry.getId());

            for (int i = 0; i < comments.size(); i++) {
              StudentGroupContactLogEntryComment comment = comments.get(i);

              if (d == null) {
                d = comment.getCommentDate();
              } else {
                if (d.before(comment.getCommentDate())) d = comment.getCommentDate();
              }
            }

            return d;
          }

          public int compare(StudentGroupContactLogEntry o1, StudentGroupContactLogEntry o2) {
            Date d1 = getDateForEntry(o1);
            Date d2 = getDateForEntry(o2);

            int val = d1 == null ? d2 == null ? 0 : 1 : d2 == null ? -1 : d2.compareTo(d1);

            if (val == 0) return o2.getId().compareTo(o1.getId());
            else return val;
          }
        });

    pageRequestContext.getRequest().setAttribute("contactEntries", contactLogEntries);
    pageRequestContext.getRequest().setAttribute("contactEntryComments", contactEntryComments);

    pageRequestContext.setIncludeJSP("/templates/students/managestudentgroupcontactentries.jsp");
  }
  @Override
  public void processForm(PageRequestContext requestContext) {
    PluginRepositoryDAO pluginRepositoryDAO = DAOFactory.getInstance().getPluginRepositoryDAO();
    PluginDAO pluginDAO = DAOFactory.getInstance().getPluginDAO();

    PluginManager pluginManager = PluginManager.getInstance();

    List<PluginRepository> pluginRepositories = pluginRepositoryDAO.listAll();
    List<Plugin> plugins = pluginDAO.listAll();
    List<PluginBean> pluginBeans = new ArrayList<PluginsViewController.PluginBean>(plugins.size());
    for (Plugin plugin : plugins) {
      String status = "";
      boolean loaded =
          pluginManager.isLoaded(plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion());
      boolean deletable = false;

      if (loaded) {
        if (plugin.getEnabled())
          status =
              Messages.getInstance()
                  .getText(
                      requestContext.getRequest().getLocale(),
                      "system.plugins.pluginsTableStatusLoaded");
        else
          status =
              Messages.getInstance()
                  .getText(
                      requestContext.getRequest().getLocale(),
                      "system.plugins.pluginsTableStatusUnloadOnRestart");
      } else {
        if (plugin.getEnabled())
          status =
              Messages.getInstance()
                  .getText(
                      requestContext.getRequest().getLocale(),
                      "system.plugins.pluginsTableStatusLoadOnRestart");
        else
          status =
              Messages.getInstance()
                  .getText(
                      requestContext.getRequest().getLocale(),
                      "system.plugins.pluginsTableStatusNotLoaded");
        deletable = true;
      }

      PluginBean pluginBean =
          new PluginBean(
              plugin.getId(),
              plugin.getGroupId(),
              plugin.getArtifactId(),
              plugin.getVersion(),
              plugin.getEnabled(),
              deletable,
              status);
      pluginBeans.add(pluginBean);
    }

    requestContext.getRequest().setAttribute("repositories", pluginRepositories);
    requestContext.getRequest().setAttribute("plugins", pluginBeans);
    /**
     * Messages.getInstance().getText(requestContext.getRequest().getLocale(),
     * "system.plugins.pluginsTableStatusNotLoaded");
     * Messages.getInstance().getText(requestContext.getRequest().getLocale(),
     * "system.plugins.pluginsTableStatusUnloadOnRestart");
     * Messages.getInstance().getText(requestContext.getRequest().getLocale(),
     * "system.plugins.pluginsTableStatusLoaded");
     */
    requestContext.setIncludeJSP("/templates/system/plugins.jsp");
  }