/**
   * Validates the given Patient. Currently just checks for errors in identifiers. TODO: Check for
   * errors in all Patient fields.
   *
   * @param obj The patient to validate.
   * @param errors Errors
   * @see org.springframework.validation.Validator#validate(java.lang.Object,
   *     org.springframework.validation.Errors)
   * @should fail validation if gender is blank
   * @should fail validation if birthdate makes patient older that 120 years old
   * @should fail validation if birthdate is a future date
   * @should fail validation if voidReason is blank when patient is voided
   * @should fail validation if causeOfDeath is blank when patient is dead
   */
  public void validate(Object obj, Errors errors) {
    if (log.isDebugEnabled()) log.debug(this.getClass().getName() + ".validate...");

    Patient patient = (Patient) obj;

    if (patient != null) {
      for (PersonName personName : patient.getNames()) {
        personNameValidator.validate(personName, errors);
      }
    }

    // Make sure they choose a gender
    if (StringUtils.isBlank(patient.getGender()))
      errors.rejectValue("gender", "Person.gender.required");

    // check patients birthdate against future dates and really old dates
    if (patient.getBirthdate() != null) {
      if (patient.getBirthdate().after(new Date()))
        errors.rejectValue("birthdate", "error.date.future");
      else {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, -120); // patient cannot be older than 120 years old
        if (patient.getBirthdate().before(c.getTime())) {
          errors.rejectValue("birthdate", "error.date.nonsensical");
        }
      }
    }

    //	 Patient Info
    if (patient.isPersonVoided())
      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "voidReason", "error.null");
    if (patient.isDead() && (patient.getCauseOfDeath() == null))
      errors.rejectValue("causeOfDeath", "Patient.dead.causeOfDeathNull");

    if (!errors.hasErrors()) {
      // Validate PatientIdentifers
      if (patient != null && patient.getIdentifiers() != null) {
        for (PatientIdentifier identifier : patient.getIdentifiers()) {
          patientIdentifierValidator.validate(identifier, errors);
        }
      }
    }
  }
  /**
   * Validates the given Patient. Currently just checks for errors in identifiers. TODO: Check for
   * errors in all Patient fields.
   *
   * @param obj The patient to validate.
   * @param errors Errors
   * @see org.springframework.validation.Validator#validate(java.lang.Object,
   *     org.springframework.validation.Errors)
   * @should fail validation if gender is blank
   * @should fail validation if birthdate makes patient older that 120 years old
   * @should fail validation if birthdate is a future date
   * @should fail validation if a preferred patient identifier is not chosen
   * @should fail validation if voidReason is blank when patient is voided
   * @should fail validation if causeOfDeath is blank when patient is dead
   * @should fail validation if a preferred patient identifier is not chosen for voided patients
   * @should not fail when patient has only one identifier and its not preferred
   * @should pass validation if field lengths are correct
   * @should fail validation if field lengths are not correct
   */
  public void validate(Object obj, Errors errors) {
    if (log.isDebugEnabled()) {
      log.debug(this.getClass().getName() + ".validate...");
    }

    if (obj == null) {
      return;
    }

    super.validate(obj, errors);

    Patient patient = (Patient) obj;

    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "gender", "Person.gender.required");

    // Make sure they chose a preferred ID
    Boolean preferredIdentifierChosen = false;
    // Voided patients have only voided identifiers since they were voided with the patient,
    // so get all otherwise get the active ones
    Collection<PatientIdentifier> identifiers =
        patient.isVoided() ? patient.getIdentifiers() : patient.getActiveIdentifiers();
    for (PatientIdentifier pi : identifiers) {
      if (pi.isPreferred()) {
        preferredIdentifierChosen = true;
      }
    }
    if (!preferredIdentifierChosen && identifiers.size() != 1) {
      errors.reject("error.preferredIdentifier");
    }
    int index = 0;
    if (!errors.hasErrors()) {
      // Validate PatientIdentifers
      if (patient.getIdentifiers() != null) {
        for (PatientIdentifier identifier : patient.getIdentifiers()) {
          errors.pushNestedPath("identifiers[" + index + "]");
          patientIdentifierValidator.validate(identifier, errors);
          errors.popNestedPath();
          index++;
        }
      }
    }
    ValidateUtil.validateFieldLengths(errors, obj.getClass(), "voidReason");
  }