public PatientDataResult evaluate(RowPerPatientData patientsData, EvaluationContext context) {

    PatientAttributeResult result = new PatientAttributeResult(patientsData, context);
    PatientDateOfBirth pd = (PatientDateOfBirth) patientsData;

    Date birthDate = (Date) (pd.getPatient()).getBirthdate();
    String date = "";
    SimpleDateFormat sdf = new SimpleDateFormat(pd.getDateFormat());
    if (birthDate != null) {
      date = sdf.format(birthDate);
    }
    result.setValue(date);

    return result;
  }
  public PatientDataResult calculateResult(
      List<PatientDataResult> results, EvaluationContext context) {

    PatientAttributeResult alert = new PatientAttributeResult(null, null);

    ProgramWorkflowState state = (ProgramWorkflowState) context.getParameterValue("state");

    StringBuffer alerts = new StringBuffer();

    double height = 0;
    double weight = 0;

    for (PatientDataResult result : results) {

      if (result.getName().equals("CD4Test")) {
        AllObservationValuesResult cd4 = (AllObservationValuesResult) result;

        if (cd4.getValue() != null) {
          int decline = calculateDecline(cd4.getValue());

          if (decline > 50
              && (state.toString().contains("GROUP") || state.toString().contains("FOLLOWING"))) {
            alerts.append("CD4 decline(");
            alerts.append(decline);
            alerts.append(").\n");
          }

          Obs lastCd4 = null;

          if (cd4.getValue().size() > 0) {
            lastCd4 = cd4.getValue().get(cd4.getValue().size() - 1);
          }

          if (lastCd4 == null) {
            alerts.append("No CD4 recorded.\n");
          } else {
            Date dateCd4 = lastCd4.getObsDatetime();
            Date date = Calendar.getInstance().getTime();

            int diff = calculateMonthsDifference(date, dateCd4);

            if (diff > 12) {
              alerts.append("Very late CD4(" + diff + " months ago).\n");
            } else if ((diff > 6) && state.toString().contains("FOLLOWING")) {
              alerts.append("Late CD4(" + diff + " months ago).\n");
            }

            if (state.toString().contains("FOLLOWING")
                && lastCd4.getValueNumeric() != null
                && lastCd4.getValueNumeric() < 500) {
              alerts.append("Eligible for Treatment.\n");
            }
          }
        }
      }
      if (result.getName().equals("viralLoadTest")) {
        AllObservationValuesResult viraload = (AllObservationValuesResult) result;

        if (viraload.getValue() != null) {
          Obs lastviraload = null;

          if (viraload.getValue().size() > 0) {
            lastviraload = viraload.getValue().get(viraload.getValue().size() - 1);
          }

          if (state.toString().contains("GROUP") && (lastviraload == null)) {
            alerts.append("No VL recorded.\n");
          } else {
            try {
              Date dateVl = lastviraload.getObsDatetime();
              Date date = Calendar.getInstance().getTime();

              int diff = calculateMonthsDifference(date, dateVl);

              if (state.toString().contains("GROUP")) {
                if (diff > 12) {
                  alerts.append("Late VL(" + diff + " months ago).\n");
                }

                if (lastviraload.getValueNumeric() != null
                    && lastviraload.getValueNumeric() > 1000) {
                  alerts.append("VL Failure " + lastviraload.getValueNumeric() + ".\n");
                }
              }
            } catch (Exception e) {
            }
          }
        }
      }
      if (result.getName().equals("weightObs")) {
        AllObservationValuesResult wt = (AllObservationValuesResult) result;

        if (wt.getValue() != null) {
          int decline = calculatePercentageDecline(wt.getValue());

          if (decline > 5) {
            alerts.append("WT decline(");
            alerts.append(decline);
            alerts.append("%, ");
            int kilosLost = calculateDecline(wt.getValue());
            alerts.append(kilosLost);
            alerts.append("kg)\n");
          }

          if (wt.getValue().size() > 0) {
            weight = wt.getValue().get(wt.getValue().size() - 1).getValueNumeric();
          }
        }

        if (wt.getValue() == null || wt.getValue().size() == 0) {
          alerts.append("No weight recorded.\n");
        }
      }

      if (result.getName().equals("RecentHeight")) {
        ObservationResult heightOb = (ObservationResult) result;

        if (heightOb.getValue() == null || heightOb.getValue().trim().length() == 0) {
          alerts.append("No height recorded.\n");
        } else {
          height = Double.parseDouble(heightOb.getValue());
        }
      }

      if (result.getName().equals("lastEncInMonth")) {
        DateValueResult encinmonths = (DateValueResult) result;
        if (encinmonths.getValue() != null) {
          Date dateVl = encinmonths.getDateOfObservation();
          Date date = Calendar.getInstance().getTime();
          int diff = calculateMonthsDifference(date, dateVl);
          if (diff > 12) {
            alerts.append("LTFU determine status.\n");
          }
        }
      }

      if (result.getName().equals("IO") && result.getValue() != null) {
        alerts.append("OI reported last visit: " + result.getValue() + "\n");
      }

      if (result.getName().equals("SideEffects") && result.getValue() != null) {
        alerts.append("Side effects reported last visit: " + result.getValue() + "\n");
      }
    }

    if (height > 0 && weight > 0) {
      double bmi = weight / (height / 100 * height / 100);
      int decimalPlace = 1;
      BigDecimal bd = new BigDecimal(Double.toString(bmi));
      bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);

      if (bmi < 16) {
        alerts.append("Very low BMI (" + bd.doubleValue() + ").\n");
      } else if (bmi < 18.5) {
        alerts.append("Low BMI (" + bd.doubleValue() + ").\n");
      }
    }

    alert.setValue(alerts.toString().trim());
    return alert;
  }
  public PatientDataResult calculateResult(
      List<PatientDataResult> results, EvaluationContext context) {

    PatientAttributeResult alert = new PatientAttributeResult(null, null);

    StringBuffer alerts = new StringBuffer();

    for (PatientDataResult result : results) {

      if (result.getName().equals("CD4Test")) {
        ObservationResult cd4 = (ObservationResult) result;

        if (cd4.getValue() != null && cd4.getValue().trim().length() > 0) {
          int cd4Val = Integer.parseInt(cd4.getValue());
          if (cd4Val < 350) {
            if (alerts.length() > 0) {
              alerts.append(", ");
            }
            alerts.append("Low CD4");
          }
        }

        if (cd4.getDateOfObservation() != null) {
          Date dateCd4 = cd4.getDateOfObservation();
          Date date = new Date();

          int diff = calculateMonthsDifference(date, dateCd4);

          if (diff > 7) {
            if (alerts.length() > 0) {
              alerts.append(", ");
            }
            alerts.append("Late CD4");
          }
        }
      }

      if (result.getName().equals("gestationalAge")) {
        if (result.getValue() != null) {
          int gestationalAge = Integer.parseInt(result.getValue().toString());

          if (gestationalAge > 37 && gestationalAge < 41) {
            if (alerts.length() > 0) {
              alerts.append(", ");
            }
            alerts.append("Due to deliver");
          }
          if (gestationalAge > 40) {
            if (alerts.length() > 0) {
              alerts.append(", ");
            }
            alerts.append("Post term");
          }
        }
      }

      if (result.getName().equals("weightObs")) {
        AllObservationValuesResult wt = (AllObservationValuesResult) result;

        if (wt.getValue() != null) {
          int decline = calculateDecline(wt.getValue());

          if (decline == 0) {
            alerts.append("No weight gain\n");
          } else if (decline > 0) {
            alerts.append("Weight decline (");
            alerts.append(decline);
            alerts.append(" kg)\n");
          }
        }

        if (wt.getValue() == null || wt.getValue().size() == 0) {
          alerts.append("No weight recorded.\n");
        }
      }

      if (result.getName().equals("IO") && result.getValue() != null) {
        alerts.append("IO reported last visit: " + result.getValue() + "\n");
      }

      if (result.getName().equals("SideEffects") && result.getValue() != null) {
        alerts.append("Side effects reported last visit: " + result.getValue() + "\n");
      }
    }

    alert.setValue(alerts.toString());
    return alert;
  }