/*
   * (non-Javadoc)
   *
   * @see org.akaza.openclinica.control.submit.DataEntryServlet#loadDBValues()
   */
  @Override
  protected boolean shouldLoadDBValues(DisplayItemBean dib) {
    // my understanding-jxu:
    // if the status is pending, should not load the db value
    // if the status is UNAVAILABLE,load DB value
    // interesting bug here: some fields load, some don't
    // remove a session value here:
    // int keyId = ecb.getId();
    // session.removeAttribute(COUNT_VALIDATE+keyId);
    // logger.info("^^^removed count_validate here");
    // wonky place to do it, but no other place at the moment, tbh
    if (dib.getData().getStatus() == null || dib.getData().getStatus().equals(Status.UNAVAILABLE)) {
      return true;
    }
    /*
     * if (!dib.getData().getStatus().equals(Status.UNAVAILABLE)) {
     * logger.info("status don't match.."); return false; //return true; }
     */

    // how about this instead:
    // if it's pending, return false
    // otherwise return true?
    if (dib.getData().getStatus().equals(Status.PENDING)) {
      // logger.info("status was pending...");
      return false;
      // return true;
    }

    return true;
  }
  /**
   * Performs calculation. <br>
   * Notice: both parameter 'itemdata' and parameter 'errs' might be updated in this method.
   *
   * @param displayItems
   * @param items
   * @param itemdata
   * @param errs
   * @return
   * @author ywang (Jan. 2008)
   */
  public String doCalculation(
      DisplayItemBean displayItem,
      HashMap<String, ItemBean> items,
      HashMap<String, String> itemdata,
      HashMap<Integer, TreeSet<Integer>> itemOrdinals,
      StringBuffer errs,
      int ordinal) {
    if (itemdata == null) {
      logger.error("In DataEntryServlet doCalculation(), itemdata map is empty!");
      errs.append("Calculation cannot be started because needed items are empty" + "; ");
      return "";
    }
    String value = "";
    NumberFormat nf = NumberFormat.getInstance();
    Parser parser = new Parser(items, itemdata);

    ItemBean ib = displayItem.getItem();
    ItemFormMetadataBean ifm = displayItem.getMetadata();
    ResponseOptionBean rob = (ResponseOptionBean) ifm.getResponseSet().getOptions().get(0);
    ArrayList<ScoreToken> parsedExp = new ArrayList<ScoreToken>();
    int type = ifm.getResponseSet().getResponseTypeId();
    if (type == 8) {
      parsedExp = parser.assignVariables(parser.parseScoreTokens(rob.getValue()), ordinal);
    } else if (type == 9) {
      // YW, 1-16-2008, for group-calculation type. Current restrictions:
      // 1. only calculate sum(), avg(), min(), max(), median(), stdev()
      // 2. formula arguments only contain item beans
      // 3. only one item bean per argument
      parsedExp = parser.assignVariables(parser.parseScoreTokens(rob.getValue()), itemOrdinals);
    }
    if (parser.getErrors().length() > 0) {
      errs.append(parser.getErrors());
    } else {
      try {
        value = ScoreUtil.eval(parsedExp);
      } catch (ScoreException se) {
        logger.error(se.getMessage());
      }
      ItemDataType idt = ib.getDataType();
      if (value == null || value.length() == 0) {
        value = "";
        String exp = rob.getValue();
        exp = exp.replace("##", ",");
        errs.append("Result is empty in" + " " + exp + "; ");
        // errors.append(resexception.getString("result_is_empty_in") +
        // " " + exp + "; ");
      } else {
        value = this.getMathContextValue(value, ifm, idt, errs);
      }
      // idb.setStatus(Status.UNAVAILABLE);
      itemdata.put(ib.getId() + "_" + ordinal, value);
    }

    return value;
  }
  /**
   * Assumes the children are ordered by getMetadata().getColumnNumber() in ascending order.
   *
   * @param children The children to set.
   */
  public void setChildren(ArrayList children) {
    this.children = children;
    numChildren = children.size();

    if (numChildren > 0) {
      DisplayItemBean dib = (DisplayItemBean) children.get(numChildren - 1);
      numColumns = dib.getMetadata().getColumnNumber();
    } else {
      numColumns = 1;
    }
  }
  public static DiscrepancyNoteBean createDiscrepancyNote(
      ItemBean itemBean,
      String message,
      EventCRFBean eventCrfBean,
      DisplayItemBean displayItemBean,
      Integer parentId,
      UserAccountBean uab,
      DataSource ds,
      StudyBean study) {
    // DisplayItemBean displayItemBean) {
    DiscrepancyNoteBean note = new DiscrepancyNoteBean();
    StudySubjectDAO ssdao = new StudySubjectDAO(ds);
    note.setDescription(message);
    note.setDetailedNotes("Failed Validation Check");
    note.setOwner(uab);
    note.setCreatedDate(new Date());
    note.setResolutionStatusId(ResolutionStatus.OPEN.getId());
    note.setDiscrepancyNoteTypeId(DiscrepancyNoteType.FAILEDVAL.getId());
    if (parentId != null) {
      note.setParentDnId(parentId);
    }

    note.setField(itemBean.getName());
    note.setStudyId(study.getId());
    note.setEntityName(itemBean.getName());
    note.setEntityType("ItemData");
    note.setEntityValue(displayItemBean.getData().getValue());

    note.setEventName(eventCrfBean.getName());
    note.setEventStart(eventCrfBean.getCreatedDate());
    note.setCrfName(displayItemBean.getEventDefinitionCRF().getCrfName());

    StudySubjectBean ss = (StudySubjectBean) ssdao.findByPK(eventCrfBean.getStudySubjectId());
    note.setSubjectName(ss.getName());

    note.setEntityId(displayItemBean.getData().getId());
    note.setColumn("value");

    DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(ds);
    note = (DiscrepancyNoteBean) dndao.create(note);
    // so that the below method works, need to set the entity above
    // System.out.println("trying to create mapping with " + note.getId() + " " + note.getEntityId()
    // + " " + note.getColumn() + " " + note.getEntityType());
    dndao.createMapping(note);
    // System.out.println("just created mapping");
    return note;
  }
  @Override
  protected DisplayItemBean validateDisplayItemBean(
      DiscrepancyValidator v,
      DisplayItemBean dib,
      String inputName,
      RuleValidator rv,
      HashMap<String, ArrayList<String>> groupOrdinalPLusItemOid,
      Boolean fireRuleValidation,
      ArrayList<String> messages,
      HttpServletRequest request) {

    org.akaza.openclinica.bean.core.ResponseType rt =
        dib.getMetadata().getResponseSet().getResponseType();
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);

    boolean isSingleItem = false;
    if (StringUtil.isBlank(inputName)) { // for single items
      inputName = getInputName(dib);
      isSingleItem = true;
    }
    // we only give warning to user if data entered in DDE is different from
    // IDE when the first
    // time user hits 'save'
    int keyId = ecb.getId();
    Integer validationCount = (Integer) request.getSession().getAttribute(COUNT_VALIDATE + keyId);

    ItemDataBean valueToCompare = dib.getData();
    if (!isSingleItem) {
      valueToCompare = dib.getDbData();
    }

    if (isSingleItem) {
      dib = loadFormValue(dib, request);
    }
    if (groupOrdinalPLusItemOid.containsKey(dib.getItem().getOid()) || fireRuleValidation) {
      messages = messages == null ? groupOrdinalPLusItemOid.get(dib.getItem().getOid()) : messages;
      dib = validateDisplayItemBeanSingleCV(rv, dib, inputName, messages);
    }

    return dib;
  }
  @Override
  protected DisplayItemBean validateCalcTypeDisplayItemBean(
      ScoreItemValidator sv, DisplayItemBean dib, String inputName, HttpServletRequest request) {

    org.akaza.openclinica.bean.core.ResponseType rt =
        dib.getMetadata().getResponseSet().getResponseType();
    ItemDataDAO iddao = new ItemDataDAO(getDataSource());
    boolean isSingleItem = false;
    HttpSession session = request.getSession();
    if (StringUtil.isBlank(inputName)) { // for single items
      inputName = getInputName(dib);
      isSingleItem = true;
    }
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);

    // we only give warning to user if data entered in DDE is different from
    // IDE when the first
    // time user hits 'save'
    int keyId = ecb.getId();
    Integer validationCount = (Integer) session.getAttribute(COUNT_VALIDATE + keyId);

    ItemDataBean valueToCompare = new ItemDataBean();
    if (isSingleItem) {
      int idId = dib.getData().getId();
      if (idId > 0) {
        valueToCompare = (ItemDataBean) iddao.findByPK(idId);
      }
    } else {
      valueToCompare = dib.getDbData();
    }
    if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CALCULATION)
        || rt.equals(org.akaza.openclinica.bean.core.ResponseType.GROUP_CALCULATION)) {
      boolean showOriginalItem =
          getItemMetadataService().isShown(dib.getItem().getId(), ecb, valueToCompare);
      boolean showItem = dib.getMetadata().isShowItem();
      boolean showDuplicateItem =
          getItemMetadataService()
              .hasPassedDDE(
                  dib.getMetadata(),
                  ecb,
                  valueToCompare); // .isShown(dib.getItem().getId(), ecb, dib.getDbData());
      if (showOriginalItem && showDuplicateItem || showItem) {
        dib = validateDisplayItemBeanText(sv, dib, inputName, request);
      }
      if (showOriginalItem && showDuplicateItem || showItem) {
        sv.addValidation(
            inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
        sv.setErrorMessage(
            respage.getString("value_you_specified")
                + " "
                + valueToCompare.getValue()
                + " "
                + respage.getString("from_initial_data_entry"));
      }
    }

    return dib;
  }
  @Override
  @SuppressWarnings(value = "unchecked")
  public void processRequest() throws Exception {
    ItemDataDAO itemDataDao = new ItemDataDAO(sm.getDataSource());
    EventCRFDAO eventCrfDao = new EventCRFDAO(sm.getDataSource());
    CrfBusinessLogicHelper crfBusinessLogicHelper = new CrfBusinessLogicHelper(sm.getDataSource());
    String action = request.getParameter("action");

    FormProcessor fp = new FormProcessor(request);

    // checks which module the requests are from
    String module = fp.getString(MODULE);
    request.setAttribute(MODULE, module);

    resetPanel();
    panel.setStudyInfoShown(false);
    panel.setOrderedData(true);

    setToPanel(resword.getString("create_CRF"), respage.getString("br_create_new_CRF_entering"));

    setToPanel(
        resword.getString("create_CRF_version"), respage.getString("br_create_new_CRF_uploading"));
    setToPanel(
        resword.getString("revise_CRF_version"), respage.getString("br_if_you_owner_CRF_version"));
    setToPanel(
        resword.getString("CRF_spreadsheet_template"),
        respage.getString("br_download_blank_CRF_spreadsheet_from"));
    setToPanel(
        resword.getString("example_CRF_br_spreadsheets"),
        respage.getString("br_download_example_CRF_instructions_from"));

    if ("confirm".equalsIgnoreCase(action)) {
      List<DisplayItemBeanWrapper> displayItemBeanWrappers =
          (List<DisplayItemBeanWrapper>) session.getAttribute("importedData");
      logger.info("Size of displayItemBeanWrappers : " + displayItemBeanWrappers.size());
      forwardPage(Page.VERIFY_IMPORT_CRF_DATA);
    }

    if ("save".equalsIgnoreCase(action)) {
      List<DisplayItemBeanWrapper> displayItemBeanWrappers =
          (List<DisplayItemBeanWrapper>) session.getAttribute("importedData");
      // System.out.println("Size of displayItemBeanWrappers : " + displayItemBeanWrappers.size());

      for (DisplayItemBeanWrapper wrapper : displayItemBeanWrappers) {

        int eventCrfBeanId = -1;
        EventCRFBean eventCrfBean = new EventCRFBean();

        // TODO : tom , the wrapper object has all the necessary data -
        // as you see we check the
        // is to see if this data is Savable if it is then we go ahead
        // and save it. if not we discard.
        // So the change needs to happen here , instead of discarding we
        // need to file discrepancy notes
        // and save the data. If you look in the
        // Page.VERIFY_IMPORT_CRF_DATA jsp file you can see how I am
        // pulling the errors. and use that in the same way.

        logger.info("right before we check to make sure it is savable: " + wrapper.isSavable());
        if (wrapper.isSavable()) {
          ArrayList<Integer> eventCrfInts = new ArrayList<Integer>();
          // based on the use case: "If any of the data does not meet
          // validations specified in the CRF
          // Template, a discrepancy note is automatically logged.
          // The DN will have a type of Failed Validation Check, and
          // a message of Failed Validation check."
          // System.out.println("wrapper problems found : " +
          // wrapper.getValidationErrors().toString());
          for (DisplayItemBean displayItemBean : wrapper.getDisplayItemBeans()) {
            eventCrfBeanId = displayItemBean.getData().getEventCRFId();
            eventCrfBean = (EventCRFBean) eventCrfDao.findByPK(eventCrfBeanId);
            logger.info("found value here: " + displayItemBean.getData().getValue());
            logger.info("found status here: " + eventCrfBean.getStatus().getName());
            // System.out.println("found event crf bean name here: "
            // +
            // eventCrfBean.getEventName()+" id "+eventCrfBean.getId
            // ());
            // SO, items can be created in a wrapper which is set to
            // overwrite
            // we get around this by checking the bean first, to
            // make sure it's not null
            ItemDataBean itemDataBean = new ItemDataBean();
            itemDataBean =
                itemDataDao.findByItemIdAndEventCRFIdAndOrdinal(
                    displayItemBean.getItem().getId(),
                    eventCrfBean.getId(),
                    displayItemBean.getData().getOrdinal());
            if (wrapper.isOverwrite() && itemDataBean.getStatus() != null) {
              // ItemDataBean itemDataBean = new ItemDataBean();
              // itemDataBean =
              // itemDataDao.findByItemIdAndEventCRFIdAndOrdinal(
              // displayItemBean.getItem().getId(),
              // eventCrfBean.getId(), displayItemBean
              // .getData().getOrdinal());
              // itemDataBean =
              // itemDataDao.findByEventCRFIdAndItemName(
              // eventCrfBean,
              // displayItemBean.getItem().getName());
              logger.info(
                  "just tried to find item data bean on item name "
                      + displayItemBean.getItem().getName());
              itemDataBean.setUpdatedDate(new Date());
              itemDataBean.setUpdater(ub);
              itemDataBean.setValue(displayItemBean.getData().getValue());
              // set status?
              itemDataDao.update(itemDataBean);
              logger.info("updated: " + itemDataBean.getItemId());
              // need to set pk here in order to create dn
              displayItemBean.getData().setId(itemDataBean.getId());
            } else {
              itemDataDao.create(displayItemBean.getData());
              logger.info(
                  "created: "
                      + displayItemBean.getData().getItemId()
                      + "event CRF ID = "
                      + eventCrfBean.getId()
                      + "CRF VERSION ID ="
                      + eventCrfBean.getCRFVersionId());

              // does this dao function work for repeating
              // events/groups?
              // ItemDataBean itemDataBean =
              // itemDataDao.findByEventCRFIdAndItemName(
              // eventCrfBean,
              // displayItemBean.getItem().getName());
              ItemDataBean itemDataBean2 =
                  itemDataDao.findByItemIdAndEventCRFIdAndOrdinal(
                      displayItemBean.getItem().getId(),
                      eventCrfBean.getId(),
                      displayItemBean.getData().getOrdinal());
              logger.info(
                  "found: id " + itemDataBean2.getId() + " name " + itemDataBean2.getName());
              displayItemBean.getData().setId(itemDataBean2.getId());
            }
            // logger.info("created item data bean:
            // "+displayItemBean.getData().getId());
            // logger.info("created:
            // "+displayItemBean.getData().getName());
            // logger.info("continued:
            // "+displayItemBean.getData().getItemId());
            ItemDAO idao = new ItemDAO(sm.getDataSource());
            ItemBean ibean = (ItemBean) idao.findByPK(displayItemBean.getData().getItemId());
            // logger.info("continued2: getName " +
            // ibean.getName());
            // System.out.println("*** checking for validation errors: " + ibean.getName());
            String itemOid =
                displayItemBean.getItem().getOid()
                    + "_"
                    + wrapper.getStudyEventRepeatKey()
                    + "_"
                    + displayItemBean.getData().getOrdinal()
                    + "_"
                    + wrapper.getStudySubjectOid();
            if (wrapper.getValidationErrors().containsKey(itemOid)) {
              ArrayList messageList = (ArrayList) wrapper.getValidationErrors().get(itemOid);
              // if
              // (wrapper.getValidationErrors().containsKey(ibean
              // .getName())) {
              // ArrayList messageList = (ArrayList)
              // wrapper.getValidationErrors
              // ().get(ibean.getName());
              // could be more then one will have to iterate
              // could it be more than one? tbh 08/2008
              for (int iter = 0; iter < messageList.size(); iter++) {
                String message = (String) messageList.get(iter);
                DiscrepancyNoteBean parentDn =
                    ImportSpringJob.createDiscrepancyNote(
                        ibean,
                        message,
                        eventCrfBean,
                        displayItemBean,
                        null,
                        ub,
                        sm.getDataSource(),
                        currentStudy);
                ImportSpringJob.createDiscrepancyNote(
                    ibean,
                    message,
                    eventCrfBean,
                    displayItemBean,
                    parentDn.getId(),
                    ub,
                    sm.getDataSource(),
                    currentStudy);
                // System.out.println("*** created disc note with message: " + message);
                // displayItemBean);
              }
            }
            // logger.info("created:
            // "+displayItemBean.getDbData().getName());
            if (!eventCrfInts.contains(new Integer(eventCrfBean.getId()))) {
              crfBusinessLogicHelper.markCRFComplete(eventCrfBean, ub);
              // System.out.println("*** just updated event crf bean: " + eventCrfBean.getId());
              eventCrfInts.add(new Integer(eventCrfBean.getId()));
            }
          }
          // end of item datas, tbh
          // crfBusinessLogicHelper.markCRFComplete(eventCrfBean, ub);
          // System .out.println("*** just updated event crf bean: "+
          // eventCrfBean.getId());
          // need to update the study event status as well, tbh
          // crfBusinessLogicHelper.updateStudyEvent(eventCrfBean,
          // ub);
          // above should do it for us, tbh 08/2008
        }
      }

      addPageMessage(respage.getString("data_has_been_successfully_import"));
      // forwardPage(Page.SUBMIT_DATA_SERVLET);
      forwardPage(Page.LIST_STUDY_SUBJECTS_SERVLET);
      // replaced tbh, 06/2009
    }
  }
  @Override
  protected List<DisplayItemGroupBean> validateDisplayItemGroupBean(
      DiscrepancyValidator v,
      DisplayItemGroupBean digb,
      List<DisplayItemGroupBean> digbs,
      List<DisplayItemGroupBean> formGroups,
      RuleValidator rv,
      HashMap<String, ArrayList<String>> groupOrdinalPLusItemOid) {

    // logger.info("===got this far");
    int keyId = ecb.getId();
    Integer validationCount = (Integer) session.getAttribute(COUNT_VALIDATE + keyId);

    formGroups = loadFormValueForItemGroup(digb, digbs, formGroups, edcb.getId());
    logger.info(
        "found formgroups size for "
            + digb.getGroupMetaBean().getName()
            + ": "
            + formGroups.size()
            + " compare to db groups size: "
            + digbs.size());

    String inputName = "";
    for (int i = 0; i < formGroups.size(); i++) {
      DisplayItemGroupBean displayGroup = formGroups.get(i);

      List<DisplayItemBean> items = displayGroup.getItems();
      int order = displayGroup.getOrdinal();
      if (displayGroup.isAuto() && displayGroup.getFormInputOrdinal() > 0) {
        order = displayGroup.getFormInputOrdinal();
      }
      for (DisplayItemBean displayItem : items) {
        if (displayGroup.isAuto()) {
          inputName = getGroupItemInputName(displayGroup, order, displayItem);
        } else {
          inputName = getGroupItemManualInputName(displayGroup, order, displayItem);
        }
        if (displayItem.getMetadata().isShowItem()
            || getItemMetadataService()
                .isShown(displayItem.getItem().getId(), ecb, displayItem.getData())) {
          // add the validation
          if (groupOrdinalPLusItemOid.containsKey(displayItem.getItem().getOid())
              || groupOrdinalPLusItemOid.containsKey(
                  String.valueOf(order + 1) + displayItem.getItem().getOid())) {
            System.out.println(
                "IN : " + String.valueOf(order + 1) + displayItem.getItem().getOid());
            validateDisplayItemBean(
                v,
                displayItem,
                inputName,
                rv,
                groupOrdinalPLusItemOid,
                true,
                groupOrdinalPLusItemOid.get(
                    String.valueOf(order + 1) + displayItem.getItem().getOid()));
          } else {
            validateDisplayItemBean(
                v, displayItem, inputName, rv, groupOrdinalPLusItemOid, false, null);
          }
        } else {
          System.out.println("OUT : " + String.valueOf(order + 1) + displayItem.getItem().getOid());
        }
        // validateDisplayItemBean(v, displayItem, inputName);
      }
    }
    return formGroups;
  }
  @Override
  protected DisplayItemBean validateDisplayItemBean(
      DiscrepancyValidator v, DisplayItemBean dib, String inputName) {

    org.akaza.openclinica.bean.core.ResponseType rt =
        dib.getMetadata().getResponseSet().getResponseType();

    boolean isSingleItem = false;
    if (StringUtil.isBlank(inputName)) { // for single items
      inputName = getInputName(dib);
      isSingleItem = true;
    }
    // we only give warning to user if data entered in DDE is different from
    // IDE when the first
    // time user hits 'save'
    int keyId = ecb.getId();
    Integer validationCount = (Integer) session.getAttribute(COUNT_VALIDATE + keyId);

    ItemDataBean valueToCompare = dib.getData();
    if (!isSingleItem) {
      valueToCompare = dib.getDbData();
    }
    boolean showOriginalItem =
        getItemMetadataService()
            .isShown(dib.getItem().getId(), ecb, valueToCompare); // was dib.getData()
    boolean showItem = dib.getMetadata().isShowItem();
    boolean showDuplicateItem =
        getItemMetadataService()
            .hasPassedDDE(
                dib.getMetadata(),
                ecb,
                valueToCompare); // .isShown(dib.getItem().getId(), ecb, dib.getDbData());// where
    // is the set db data?
    logger.debug(
        "*** show original item has value "
            + dib.getData().getValue()
            + " and show item has value "
            + valueToCompare.getValue());
    logger.debug(
        "--- show original: "
            + showOriginalItem
            + " show duplicate: "
            + showDuplicateItem
            + " and just show item: "
            + showItem);
    logger.debug("VALIDATION COUNT " + validationCount);
    if (showOriginalItem && showDuplicateItem || showItem) {
      // it should either be shown already, OR shown in the database?
      // logger.debug("=== we passed, adding validation here");
      Integer indValidationCount =
          (Integer) session.getAttribute(COUNT_VALIDATE + keyId + dib.getMetadata().getId());
      if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXT)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXTAREA)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.FILE)) {
        dib = validateDisplayItemBeanText(v, dib, inputName);
        // necessary?
        // if (indValidationCount == null || validationCount == null || validationCount.intValue()
        // == 0) {
        logger.debug("=== we passed, adding validation here TEXT " + valueToCompare.getId());
        v.addValidation(
            inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
        v.setErrorMessage(
            respage.getString("value_you_specified")
                + " "
                + valueToCompare.getValue()
                + " "
                + respage.getString("from_initial_data_entry"));
        // session.setAttribute(COUNT_VALIDATE + keyId + dib.getMetadata().getId(), new Integer(1));
        // }

      } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.RADIO)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECT)) {
        dib = validateDisplayItemBeanSingleCV(v, dib, inputName);
        // ItemFormMetadataBean ifmdb = dib.getMetadata();
        // ResponseSetBean rsBean = ifmdb.getResponseSet();
        // logger.info("### found a response set count of "+inputName+"
        // "+rsBean.getOptions().size());
        // TODO sees it at this end tbh 1878
        // if (indValidationCount == null || validationCount == null || validationCount.intValue()
        // == 0) {
        logger.debug("=== we passed, adding validation here RADIO " + valueToCompare.getId());
        v.addValidation(
            inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
        String errorValue = valueToCompare.getValue();

        java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();

        for (int u = 0; u < options.size(); u++) {
          ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
          if (rob.getValue().equals(errorValue)) {
            errorValue = rob.getText();
          }
        }
        v.setErrorMessage(
            respage.getString("value_you_specified")
                + " "
                + errorValue
                + " "
                + respage.getString("from_initial_data_entry"));
        // session.setAttribute(COUNT_VALIDATE + keyId + dib.getMetadata().getId(), new Integer(1));
        // }
      } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CHECKBOX)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECTMULTI)) {
        dib = validateDisplayItemBeanMultipleCV(v, dib, inputName);
        // if (indValidationCount == null || validationCount == null || validationCount.intValue()
        // == 0) {
        logger.debug("=== we passed, adding validation here CHECKBOX " + valueToCompare.getId());
        v.addValidation(
            inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, true);
        // repeated from above, tbh 112007
        String errorValue = valueToCompare.getValue();
        String errorTexts = "";

        java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();

        for (int u = 0; u < options.size(); u++) {
          ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
          if (errorValue.contains(rob.getValue())) {
            errorTexts = errorTexts + rob.getText();
            if (u < options.size() - 1) {
              // the values for multi-select are seperated by
              // comma
              errorTexts = errorTexts + ", ";
            }
          }
        }
        v.setErrorMessage(
            respage.getString("value_you_specified")
                + " "
                + errorTexts
                + " "
                + respage.getString("from_initial_data_entry"));
        // session.setAttribute(COUNT_VALIDATE + keyId + dib.getMetadata().getId(), new Integer(1));
        // }
      }
    }
    // only load form value when an item is not in a group,
    // if in group, the value is already loaded
    // see formGroups = loadFormValueForItemGroup(digb,digbs,formGroups);
    if (isSingleItem) {
      dib = loadFormValue(dib);
    }

    return dib;
  }
  @Override
  protected DisplayItemBean validateDisplayItemBean(
      DiscrepancyValidator v, DisplayItemBean dib, String inputName, HttpServletRequest request) {

    org.akaza.openclinica.bean.core.ResponseType rt =
        dib.getMetadata().getResponseSet().getResponseType();
    HttpSession session = request.getSession();
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);

    boolean isSingleItem = false;
    if (StringUtil.isBlank(inputName)) { // for single items
      inputName = getInputName(dib);
      isSingleItem = true;
    }

    // we only give warning to user if data entered in DDE is different from
    // IDE when the first
    // time user hits 'save'
    int keyId = ecb.getId();
    Integer validationCount = (Integer) session.getAttribute(COUNT_VALIDATE + keyId);

    // @pgawade 12-Aug-2011 issue 10601:
    // 1. Moved the call to loadFormValue method setting values
    // from form here. It was at the end
    // of this method before that is after validations and so an extra
    // validation for checking value entered
    // against the data type was getting implemented for non-repeating group
    // items.
    // 2. Copying the form data into new object for non repeating items to
    // pass to validation
    // for matching IDE and DDE values. Id same reference is used, the way
    // code here was written, it affetcs
    // the value used in validation of data entered in DDE against the
    // related data type
    ItemDataBean valueToCompareTmp = dib.getData();
    ItemDataBean valueToCompare = copyItemDataBean(valueToCompareTmp);

    if (!isSingleItem) {
      valueToCompare = dib.getDbData();
    }

    // only load form value when an item is not in a group,
    // if in group, the value is already loaded
    // see formGroups = loadFormValueForItemGroup(digb,digbs,formGroups);
    if (isSingleItem) {
      dib = loadFormValue(dib, request);
    }

    boolean showOriginalItem =
        getItemMetadataService()
            .isShown(dib.getItem().getId(), ecb, valueToCompare); // was dib.getData()
    boolean showItem = dib.getMetadata().isShowItem();
    if (!showItem && dib.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId() > 0) {
      showItem = true;
    }
    boolean showDuplicateItem =
        getItemMetadataService()
            .hasPassedDDE(
                dib.getMetadata(),
                ecb,
                valueToCompare); // .isShown(dib.getItem().getId(), ecb, dib.getDbData());// where
                                 // is the set db data?
    logger.debug(
        "*** show original item has value "
            + dib.getData().getValue()
            + " and show item has value "
            + valueToCompare.getValue());
    logger.debug(
        "--- show original: "
            + showOriginalItem
            + " show duplicate: "
            + showDuplicateItem
            + " and just show item: "
            + showItem);
    logger.debug("VALIDATION COUNT " + validationCount);
    if (showOriginalItem && showDuplicateItem || showItem) {
      if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXT)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXTAREA)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.FILE)) {
        dib = validateDisplayItemBeanText(v, dib, inputName, request);
        if (validationCount == null || validationCount.intValue() == 0) {
          v.addValidation(
              inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
          v.setErrorMessage(
              respage.getString("value_you_specified")
                  + " "
                  + valueToCompare.getValue()
                  + " "
                  + respage.getString("from_initial_data_entry"));
        }

      } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.RADIO)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECT)) {
        dib = validateDisplayItemBeanSingleCV(v, dib, inputName);
        // ItemFormMetadataBean ifmdb = dib.getMetadata();
        // ResponseSetBean rsBean = ifmdb.getResponseSet();
        // logger.info("### found a response set count of "+inputName+"
        // "+rsBean.getOptions().size());
        // TODO sees it at this end tbh 1878

        if (validationCount == null || validationCount.intValue() == 0) {
          v.addValidation(
              inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
          String errorValue = valueToCompare.getValue();

          java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();

          for (int u = 0; u < options.size(); u++) {
            ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
            if (rob.getValue().equals(errorValue)) {
              errorValue = rob.getText();
            }
          }
          v.setErrorMessage(
              respage.getString("value_you_specified")
                  + " "
                  + errorValue
                  + " "
                  + respage.getString("from_initial_data_entry"));
        }
      } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CHECKBOX)
          || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECTMULTI)) {
        dib = validateDisplayItemBeanMultipleCV(v, dib, inputName);

        if (validationCount == null || validationCount.intValue() == 0) {
          v.addValidation(
              inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, true);
          // repeated from above, tbh 112007
          String errorValue = valueToCompare.getValue();
          String errorTexts = "";

          java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();

          for (int u = 0; u < options.size(); u++) {
            ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
            if (errorValue.contains(rob.getValue())) {
              errorTexts = errorTexts + rob.getText();
              if (u < options.size() - 1) {
                // the values for multi-select are seperated by
                // comma
                errorTexts = errorTexts + ", ";
              }
            }
          }
          v.setErrorMessage(
              respage.getString("value_you_specified")
                  + " "
                  + errorTexts
                  + " "
                  + respage.getString("from_initial_data_entry"));
        }
      }
    }
    // // only load form value when an item is not in a group,
    // // if in group, the value is already loaded
    // // see formGroups = loadFormValueForItemGroup(digb,digbs,formGroups);
    // if (isSingleItem) {
    // dib = loadFormValue(dib, request);
    // }

    return dib;
  }