/*
   * this fetches the tour from the database or network
   * if the tour db cache has timed out it will try to cache from network
   * but if that fails revert to using the version cached in the DB
   */
  private static void fetchTourHelper(final Context context, final Handler uiHandler) {
    final TourDB tourDB = TourDB.getInstance(context);

    if (tourDB.tourDetailsCached(TOUR_GUID, true)) {
      List<TourHeader> tourHeaders = tourDB.retrieveTourHeaders();
      sTour = new Tour(tourHeaders.get(0));
      tourDB.populateTourDetails(sTour);
      MobileWebApi.sendSuccessMessage(uiHandler);
      return;
    }

    // check if stale version of tour exists in db
    if (tourDB.tourDetailsCached(TOUR_GUID, false)) {
      // stale version exists, so check if stale version is recent enough
      MobileWebApi webApi = new MobileWebApi(false, false, null, context, null);
      HashMap<String, String> query = new HashMap<String, String>();
      query.put("module", "tours");
      query.put("command", "toursList");

      webApi.requestJSONArray(
          query,
          new JSONArrayResponseListener(new TourRefreshErrorListener(tourDB, uiHandler), null) {

            @Override
            public void onResponse(JSONArray array) throws ServerResponseException, JSONException {
              Long lastModified = null;
              for (int i = 0; i < array.length(); i++) {
                JSONObject tourSummary = array.getJSONObject(i);
                if (tourSummary.getString("id").equals(TOUR_GUID)) {
                  lastModified = tourSummary.getLong("last-modified") * 1000;
                }
              }

              if (lastModified != null) {
                if (lastModified < tourDB.tourDetailsLastUpdated(TOUR_GUID)) {
                  // cache is still fresh (use it, and mark it as fresh)
                  tourDB.markTourFresh(TOUR_GUID);

                  // retrieve tour from DB
                  List<TourHeader> tourHeaders = tourDB.retrieveTourHeaders();
                  sTour = new Tour(tourHeaders.get(0));
                  tourDB.populateTourDetails(sTour);
                  MobileWebApi.sendSuccessMessage(uiHandler);
                  return;
                }
              }

              // tour is not up-to-date we need to update it.
              fetchTourFromNetwork(context, uiHandler);
            }
          });

      return;
    }

    // no fresh or stale version of tour exists must retrieve it from network
    fetchTourFromNetwork(context, uiHandler);
  }