/**
   * 處理學生退選線上選課紀錄之方法
   *
   * @param mapping org.apache.struts.action.ActionMapping object
   * @param form org.apache.struts.action.ActionForm object
   * @param request javax.servlet.http.HttpServletRequest object
   * @param response javax.servlet.http.HttpServletResponse object
   * @return org.apache.struts.action.ActionForward object
   * @exception java.lang.Exception
   */
  public ActionForward deleteCourse(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    DynaActionForm aForm = (DynaActionForm) form;
    ActionMessages messages = validateInputForUpdate(aForm, Toolket.getBundle(request));
    if (!messages.isEmpty()) {
      saveErrors(request, messages);
      return mapping.findForward(IConstants.ACTION_MAIN_NAME);
    } else {

      List<SeldDataInfo> aList = getSeldDataListByIndex(request);
      if (!aList.isEmpty()) {

        CourseManager cm = (CourseManager) getBean(COURSE_MANAGER_BEAN_NAME);
        // 取得選課欲退選之Oid列表
        StringBuffer seldBuf = new StringBuffer();
        for (SeldDataInfo info : aList) {
          seldBuf.append(info.getSeldOid()).append(",");
        }
        String inSyntax = StringUtils.substringBeforeLast(seldBuf.toString(), ",");
        log.info("Seld Oid SQL IN Syntax : " + inSyntax);
        String studentNo = aForm.getString("stdNo").toUpperCase();
        MemberManager mm = (MemberManager) getBean(MEMBER_MANAGER_BEAN_NAME);
        String classNo = mm.findStudentByNo(studentNo).getDepartClass();
        // 只有第一階段不會檢查選課人數下限
        cm.txRemoveSelectedSeld(studentNo, classNo, 1, inSyntax, false);
        String idno = getUserCredential(request.getSession(false)).getMember().getIdno();
        for (SeldDataInfo info : aList) {
          cm.txSaveAdcdHistory(info.getDtimeOid(), studentNo.toUpperCase(), idno, "D");
        }
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("Message.DeleteSuccessful"));
        saveMessages(request, messages);
        // aForm.initialize(mapping);
        Toolket.resetCheckboxCookie(response, SELD_LIST_NAME);
        setContentPage(request.getSession(false), "course/OnlineAddRemoveCourse.jsp");
      } else {
        messages = new ActionMessages();
        messages.add(
            ActionMessages.GLOBAL_MESSAGE,
            new ActionMessage("Course.onlineAddRemoveCourse.unselected"));
        saveErrors(request, messages);
        return mapping.findForward(IConstants.ACTION_MAIN_NAME);
      }
    }

    return list(mapping, form, request, response);
  }
  /**
   * 處理確定加選學生低修高選課內容之方法
   *
   * @param mapping org.apache.struts.action.ActionMapping object
   * @param form org.apache.struts.action.ActionForm object
   * @param request javax.servlet.http.HttpServletRequest object
   * @param response javax.servlet.http.HttpServletResponse object
   * @return org.apache.struts.action.ActionForward object
   * @exception java.lang.Exception
   */
  public ActionForward addHigherCourse(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    MemberManager mm = (MemberManager) getBean(MEMBER_MANAGER_BEAN_NAME);
    CourseManager cm = (CourseManager) getBean(COURSE_MANAGER_BEAN_NAME);
    ActionMessages messages = new ActionMessages();
    Seld seld = (Seld) request.getSession(false).getAttribute("seldInfoForOnline");

    try {
      Student student = mm.findStudentByNo(seld.getStudentNo());
      cm.txAddSelectedSeld(seld, student, "1", true);
      String idno = getUserCredential(request.getSession(false)).getMember().getIdno();
      cm.txSaveAdcdHistory(seld.getDtimeOid(), student.getStudentNo().toUpperCase(), idno, "A");
      messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("Message.CreateSuccessful"));
      saveMessages(request, messages);
      Toolket.resetCheckboxCookie(response, SELD_LIST_NAME);
      return list(mapping, form, request, response);

    } catch (SeldException se) {
      ActionMessages errors = new ActionMessages();
      errors.add(
          ActionMessages.GLOBAL_MESSAGE, new ActionMessage("Course.errorN1", se.getMessage()));
      saveErrors(request, errors);
      if (se.getMessage().indexOf("衝堂") != StringUtils.INDEX_NOT_FOUND) {
        // 目前會拒絕衝堂課程進行加選
        Dtime dtime = cm.findDtimeBy(seld.getDtimeOid());
        Csno csno = cm.findCourseInfoByCscode(dtime.getCscode());
        request.setAttribute("csnoInfo", csno);
        request.setAttribute("classInfo", Toolket.getClassFullName(dtime.getDepartClass()));
        setContentPage(request.getSession(false), "course/ConflictList.jsp");
        return list(mapping, form, request, response);
      } else return list(mapping, form, request, response);
    }
  }
  /**
   * 處理確定加選學生選課內容之方法
   *
   * @param mapping org.apache.struts.action.ActionMapping object
   * @param form org.apache.struts.action.ActionForm object
   * @param request javax.servlet.http.HttpServletRequest object
   * @param response javax.servlet.http.HttpServletResponse object
   * @return org.apache.struts.action.ActionForward object
   * @exception java.lang.Exception
   */
  public ActionForward add(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    CourseManager cm = (CourseManager) getBean(COURSE_MANAGER_BEAN_NAME);
    HttpSession session = request.getSession(false);
    DynaActionForm aForm = (DynaActionForm) form;
    Seld seld = processSeldByForm(aForm);
    session.setAttribute("seldInfoForOnline", seld);
    Dtime dtime = cm.findDtimeBy(seld.getDtimeOid());

    ActionMessages messages = validateInputForUpdate(aForm, Toolket.getBundle(request));
    if (!messages.isEmpty()) {
      saveErrors(request, messages);
      return mapping.findForward(IConstants.ACTION_MAIN_NAME);
    } else {
      try {
        // 會以紙本作業完成加選,無需考慮衝堂問題
        // 選課人數上線於前端JavaScript判斷
        // 跨選設定不允許須阻擋並顯示訊息
        // 會顯示衝堂訊息
        MemberManager mm = (MemberManager) getBean(MEMBER_MANAGER_BEAN_NAME);
        ScoreManager sm = (ScoreManager) getBean(IConstants.SCORE_MANAGER_BEAN_NAME);
        Student student = mm.findStudentByNo(seld.getStudentNo());
        ScoreHist scoreHist = new ScoreHist(student.getStudentNo());
        List<ScoreHist> scoreHistList = sm.findScoreHistBy(scoreHist);
        String[] cscodeHist = new String[0];
        Float[] scoreList = new Float[0];
        float passScore = Toolket.getPassScoreByDepartClass(student.getDepartClass());
        for (ScoreHist hist : scoreHistList) {
          cscodeHist = (String[]) ArrayUtils.add(cscodeHist, hist.getCscode().toUpperCase());
          // 抵免要給分數,不然就會被當做無修課記錄而被加選成功
          if ("6".equals(hist.getEvgrType()))
            scoreList =
                (Float[])
                    ArrayUtils.add(
                        scoreList, hist.getScore() != null ? hist.getScore() : passScore);
          else scoreList = (Float[]) ArrayUtils.add(scoreList, hist.getScore());
        }

        int ind = 0, startIndex = 0;
        boolean isHist = false;
        do {
          ind = ArrayUtils.indexOf(cscodeHist, seld.getCscode().toUpperCase(), startIndex);
          startIndex = ind + 1;
          // 判斷是否選過且及格
          isHist =
              ind != StringUtils.INDEX_NOT_FOUND
                  && scoreList[ind] != null
                  && scoreList[ind] >= passScore;
        } while (!isHist && ind != StringUtils.INDEX_NOT_FOUND);

        // 特殊班級(跨校生等)無條件加選
        String[] specialDepartClass = {"1152A", "1220", "122A", "122B", "2220"};
        String[] addGrade = {"42", "52"}; // 2技學生年級要+2
        int stuGrade =
            ArrayUtils.contains(specialDepartClass, student.getDepartClass())
                ? 9
                : Integer.parseInt(StringUtils.substring(student.getDepartClass(), 4, 5));
        stuGrade =
            ArrayUtils.contains(addGrade, StringUtils.substring(student.getDepartClass(), 1, 3))
                ? stuGrade + 2
                : stuGrade;
        int dtimeGrade = Integer.parseInt(StringUtils.substring(dtime.getDepartClass(), 4, 5));

        if (isHist) {
          messages.add(
              ActionMessages.GLOBAL_MESSAGE,
              new ActionMessage("Course.errorN1", "歷年資料查詢到已修過該科目,請確認,謝謝!!"));
          saveErrors(request, messages);
        } else if (stuGrade >= dtimeGrade) {
          // 判斷學生年級與課程所開班級年級
          cm.txAddSelectedSeld(seld, student, "1", true);
          String idno = getUserCredential(request.getSession(false)).getMember().getIdno();
          cm.txSaveAdcdHistory(seld.getDtimeOid(), student.getStudentNo().toUpperCase(), idno, "A");
          if (ind != StringUtils.INDEX_NOT_FOUND)
            messages.add(
                ActionMessages.GLOBAL_MESSAGE,
                new ActionMessage("Course.errorN1", "該科目於歷年資料有查詢到,但該科目未及格,所以加選成功。"));
          else
            messages.add(
                ActionMessages.GLOBAL_MESSAGE, new ActionMessage("Message.CreateSuccessful"));
          saveMessages(request, messages);
        } else {
          messages.add(
              ActionMessages.GLOBAL_MESSAGE,
              new ActionMessage(
                  "Course.messageN1",
                  "注意:學生低修高年級課程,加選作業尚未完成!<br/>"
                      + "&nbsp;&nbsp;&nbsp;&nbsp;按下[再次確定]鍵後課程才會加入學生選課資料中。"));
          saveErrors(request, messages);
          setContentPage(request.getSession(false), "course/OnlineAddHigherCourse.jsp");
          return mapping.findForward(IConstants.ACTION_MAIN_NAME);
        }

        Toolket.resetCheckboxCookie(response, SELD_LIST_NAME);
        return list(mapping, form, request, response);
      } catch (SeldException se) {
        ActionMessages errors = new ActionMessages();
        errors.add(
            ActionMessages.GLOBAL_MESSAGE, new ActionMessage("Course.errorN1", se.getMessage()));
        saveErrors(request, errors);
        if (se.getMessage().indexOf("衝堂") != StringUtils.INDEX_NOT_FOUND) {
          // 目前會拒絕衝堂課程進行加選
          dtime = cm.findDtimeBy(seld.getDtimeOid());
          Csno csno = cm.findCourseInfoByCscode(dtime.getCscode());
          request.setAttribute("csnoInfo", csno);
          request.setAttribute("classInfo", Toolket.getClassFullName(dtime.getDepartClass()));
          setContentPage(request.getSession(false), "course/ConflictList.jsp");
          return list(mapping, form, request, response);
        } else return list(mapping, form, request, response);
      }
    }
  }