/**
   * 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) {
    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 processSend(PageRequestContext requestContext) {
    PluginDAO pluginDAO = DAOFactory.getInstance().getPluginDAO();
    PluginRepositoryDAO pluginRepositoryDAO = DAOFactory.getInstance().getPluginRepositoryDAO();

    Long pluginsRowCount = requestContext.getLong("pluginsTable.rowCount");
    for (int i = 0; i < pluginsRowCount; i++) {
      String colPrefix = "pluginsTable." + i;

      Long id = requestContext.getLong(colPrefix + ".id");
      Boolean enabled = "1".equals(requestContext.getString(colPrefix + ".enabled"));
      Boolean remove = "1".equals(requestContext.getString(colPrefix + ".remove"));
      String groupId = requestContext.getString(colPrefix + ".groupId");
      String artifactId = requestContext.getString(colPrefix + ".artifactId");
      String version = requestContext.getString(colPrefix + ".version");

      if (id == null) {
        pluginDAO.create(artifactId, groupId, version, enabled);
      } else {
        Plugin plugin = pluginDAO.findById(id);
        if (remove == true) {
          pluginDAO.delete(plugin);
        } else {
          pluginDAO.updateEnabled(plugin, enabled);
          pluginDAO.updateArtifactId(plugin, artifactId);
          pluginDAO.updateGroupId(plugin, groupId);
          pluginDAO.updateVersion(plugin, version);
        }
      }
    }

    Long repositoriesRowCount = requestContext.getLong("repositoriesTable.rowCount");
    for (int i = 0; i < repositoriesRowCount; i++) {
      String colPrefix = "repositoriesTable." + i;

      Long id = requestContext.getLong(colPrefix + ".id");
      String url = requestContext.getString(colPrefix + ".url");
      Boolean remove = "1".equals(requestContext.getString(colPrefix + ".remove"));

      if (id == null) {
        pluginRepositoryDAO.create(url);
      } else {
        PluginRepository repository = pluginRepositoryDAO.findById(id);
        if (remove == true) {
          pluginRepositoryDAO.delete(repository);
        } else {
          pluginRepositoryDAO.updateUrl(repository, url);
        }
      }
    }

    processForm(requestContext);

    //    List<PluginRepository> pluginRepositories = pluginRepositoryDAO.listAll();
    //    List<Plugin> plugins = pluginDAO.listAll();
    //
    //    requestContext.getRequest().setAttribute("repositories", pluginRepositories);
    //    requestContext.getRequest().setAttribute("plugins", plugins);
    //
    //    requestContext.setIncludeJSP("/templates/system/plugins.jsp");
  }