/**
   * Read event schedule from file.
   *
   * @return
   */
  private List<String[]> parseEvents() {
    List<String[]> events = new ArrayList<String[]>();
    try {
      // Attempt to open file for reading.
      //            File file = new File(EVENT_FILE_NAME);
      InputStream file = getServletContext().getResourceAsStream(EVENT_FILE_NAME);
      Scanner scanner = new Scanner(file);

      // Read each line.
      for (int count = 0; scanner.hasNext(); count++) {
        String event = scanner.nextLine();

        // Parse event fields.
        String[] fields = event.split("\t");

        // If number of fields is not correct, throw error.
        if (fields.length != EVENT_FIELD.values().length) {
          throw new Exception(
              "Invalid event file! Number of fields not correct at line " + count + ".");
        }

        // Add event to list.
        events.add(fields);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    return events;
  }
  /**
   * Show event table.
   *
   * @param writer
   * @param city
   * @param category
   */
  private void showEventTable(
      PrintWriter writer, List<String[]> events, String city, String category) {
    writer.append("<h2>Monthly ");
    if (!category.equalsIgnoreCase(OPTION_ALL)) {
      writer.append(category + " ");
    }
    writer.append("events");
    if (!city.equalsIgnoreCase(OPTION_ALL)) {
      writer.append(" in " + city);
    }
    writer.append(":\n");
    writer.append("<table border='1' cellpadding='5'>\n");
    writer.append("<tr>\n");
    writer.append("<th>ID</th>\n");
    for (EVENT_FIELD field : EVENT_FIELD.values()) {
      writer.append("<th>" + field.name() + "</th>\n");
    }
    writer.append("</tr>\n");

    // Filter event list to match conditions.
    List<String[]> filteredEvents = new ArrayList<String[]>(),
        outputEvents = new ArrayList<String[]>();
    if (city.equalsIgnoreCase(OPTION_ALL)) {
      filteredEvents.addAll(events);
    } else {
      for (String[] event : events) {
        if (event[EVENT_FIELD.City.ordinal()].equalsIgnoreCase(city)) {
          filteredEvents.add(event);
        }
      }
    }
    if (category.equalsIgnoreCase(OPTION_ALL)) {
      outputEvents.addAll(filteredEvents);
    } else {
      for (String[] event : filteredEvents) {
        if (event[EVENT_FIELD.Category.ordinal()].equalsIgnoreCase(category)) {
          outputEvents.add(event);
        }
      }
    }

    // Display filtered event list.
    for (int i = 0; i < outputEvents.size(); i++) {
      String[] event = outputEvents.get(i);
      writer.append("<tr>\n");
      writer.append("<td>" + (i + 1) + "</td>\n");
      for (EVENT_FIELD field : EVENT_FIELD.values()) {
        writer.append("<td>" + event[field.ordinal()] + "</td>\n");
      }
      writer.append("</tr>\n");
    }

    writer.append("</table>\n");
  }