/** Put the widget in single activity mode. */
 private void setSingleActivityMode() {
   sortPanel.setVisible(false);
   titlePanel.setVisible(false);
   postContent.setVisible(false);
   stream.setVisible(false);
   searchStatusWidget.setVisible(false);
   searchBoxWidget.setVisible(false);
   feedLinkWidget.setVisible(false);
   sortSearchRow.setVisible(false);
   EventBus.getInstance().notifyObservers(new ChangeActivityModeEvent(true));
 }
  /**
   * Initialize page.
   *
   * @param inShowRecipients if recipients should be shown.
   * @param itemRenderer Renderer for activities.
   */
  public StreamPanel(
      final ShowRecipient inShowRecipients, final ItemRenderer<ActivityDTO> itemRenderer) {
    addStyleName(StaticResourceBundle.INSTANCE.coreCss().layoutContainer());

    stream = new StreamListPanel(itemRenderer);
    stream.addStyleName(StaticResourceBundle.INSTANCE.coreCss().stream());
    stream.setVisible(false);

    // @author cm325 need to expose id
    stream.getElement().setId("ym-expose-stream-panel-stream");

    shadowPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().postToStreamContainer());
    shadowPanel.setVisible(false);

    searchBoxWidget = new StreamSearchBoxWidget();
    searchStatusWidget = new StreamSearchStatusWidget();

    lockedMessage.setVisible(false);
    error.setVisible(false);

    postContent.add(shadowPanel);

    titlePanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().streamTitlebar());
    streamTitleWidget = new StreamTitleWidget();
    titlePanel.add(streamTitleWidget);
    addGadgetWidget = new StreamAddAppWidget();
    titlePanel.add(addGadgetWidget);

    sortSearchRow.addStyleName(StaticResourceBundle.INSTANCE.coreCss().navpanel());
    sortSearchRow.add(sortPanel);
    sortSearchRow.add(feedLinkWidget);
    sortSearchRow.add(searchBoxWidget);

    // @author cm325 need to expose id
    sortSearchRow.getElement().setId("ym-expose-stream-panel-sort-search-row");

    this.add(postContent);
    this.add(titlePanel);
    this.add(searchStatusWidget);
    this.add(new UnseenActivityNotificationPanel());
    this.add(sortSearchRow);
    this.add(error);
    this.add(lockedMessage);
    this.add(stream);
    this.add(activityDetailPanel);

    stream.reinitialize();

    // ---- Wire up events ----
    final EventBus eventBus = Session.getInstance().getEventBus();

    eventBus.addObserver(
        UpdatedHistoryParametersEvent.class,
        new Observer<UpdatedHistoryParametersEvent>() {
          public void update(final UpdatedHistoryParametersEvent event) {
            checkHistory(event.getParameters());

            // Only process this once.
            eventBus.removeObserver(UpdatedHistoryParametersEvent.class, this);
          }
        },
        true);

    eventBus.addObserver(
        UpdatedHistoryParametersEvent.class,
        new Observer<UpdatedHistoryParametersEvent>() {
          public void update(final UpdatedHistoryParametersEvent event) {
            if (checkHistory(event.getParameters())) {
              eventBus.notifyObservers(StreamReinitializeRequestEvent.getEvent());
            }
          }
        });

    eventBus.addObserver(
        GotActivityResponseEvent.class,
        new Observer<GotActivityResponseEvent>() {
          public void update(final GotActivityResponseEvent event) {
            setSingleActivityMode();
            activityDetailPanel.clear();
            activityDetailPanel.add(new ActivityDetailPanel(event.getResponse(), inShowRecipients));
          }
        });

    eventBus.addObserver(
        StreamRequestMoreEvent.class,
        new Observer<StreamRequestMoreEvent>() {
          public void update(final StreamRequestMoreEvent arg1) {
            JSONObject jsonObj = StreamJsonRequestFactory.getJSONRequest(jsonQuery);
            jsonObj = StreamJsonRequestFactory.setMaxId(lastSeenId, jsonObj);

            // Must be sorted by date to request more.
            jsonObj = StreamJsonRequestFactory.setSort("date", jsonObj);

            if (!search.isEmpty()) {
              searchBoxWidget.setSearchTerm(search);
              searchStatusWidget.setSearchTerm(search);

              jsonObj = StreamJsonRequestFactory.setSearchTerm(search, jsonObj);
            }

            StreamModel.getInstance().fetch(jsonObj.toString(), false);
          }
        });

    eventBus.addObserver(
        GotStreamResponseEvent.class,
        new Observer<GotStreamResponseEvent>() {
          public void update(final GotStreamResponseEvent event) {
            PagedSet<ActivityDTO> activity = event.getStream();

            int numberOfActivities = activity.getPagedSet().size();
            if (numberOfActivities > 0) {
              lastSeenId = activity.getPagedSet().get(numberOfActivities - 1).getId();
            }

            MessageStreamUpdateEvent updateEvent = new MessageStreamUpdateEvent(activity);
            updateEvent.setMoreResults(activity.getTotal() > activity.getPagedSet().size());

            error.setText("");
            error.setVisible(false);
            eventBus.notifyObservers(updateEvent);
            stream.setVisible(true);
          }
        });

    eventBus.addObserver(
        StreamReinitializeRequestEvent.class,
        new Observer<StreamReinitializeRequestEvent>() {
          public void update(final StreamReinitializeRequestEvent event) {
            eventBus.notifyObservers(new StreamRequestEvent(streamName, jsonQuery, true));
          }
        });

    eventBus.addObserver(
        MessageStreamAppendEvent.class,
        new Observer<MessageStreamAppendEvent>() {
          public void update(final MessageStreamAppendEvent evt) {
            if ("date".equals(sortPanel.getSort())) {
              eventBus.notifyObservers(StreamReinitializeRequestEvent.getEvent());
            } else {
              sortPanel.updateSelected("date", true);
            }
          }
        });

    eventBus.addObserver(
        StreamRequestEvent.class,
        new Observer<StreamRequestEvent>() {
          public void update(final StreamRequestEvent event) {
            if (event.getForceReload() || !event.getJson().equals(jsonQuery)) {
              streamName = event.getStreamName();
              jsonQuery = event.getJson();
              if (activityId != 0L) {
                ActivityModel.getInstance().fetch(activityId, false);
              } else {
                setListMode();
                stream.reinitialize();

                String titleLinkUrl = null;
                String updatedJson = jsonQuery;
                JSONObject queryObject =
                    JSONParser.parse(updatedJson).isObject().get("query").isObject();

                // Only show cancel option if search is not part of the view.
                Boolean canChange = !queryObject.containsKey("keywords");

                if (queryObject.containsKey("keywords")) {
                  final String streamSearchText =
                      queryObject.get("keywords").isString().stringValue();

                  searchBoxWidget.setSearchTerm(streamSearchText);
                  searchStatusWidget.setSearchTerm(streamSearchText);

                  updatedJson =
                      StreamJsonRequestFactory.setSearchTerm(
                              streamSearchText,
                              StreamJsonRequestFactory.getJSONRequest(updatedJson))
                          .toString();
                } else if (!search.isEmpty()) {
                  searchBoxWidget.setSearchTerm(search);
                  searchStatusWidget.setSearchTerm(search);

                  updatedJson =
                      StreamJsonRequestFactory.setSearchTerm(
                              search, StreamJsonRequestFactory.getJSONRequest(updatedJson))
                          .toString();

                }
                // see if the stream belongs to a group and set up the stream title as a link
                else if (queryObject.containsKey("recipient")
                    && queryObject.get("recipient").isArray().size() == 1) {
                  JSONArray recipientArr = queryObject.get("recipient").isArray();
                  JSONObject recipientObj = recipientArr.get(0).isObject();

                  // only show the link if viewing a group stream on the activity page
                  if ("GROUP".equals(recipientObj.get("type").isString().stringValue())
                      && Session.getInstance().getUrlPage() == Page.ACTIVITY) {
                    String shortName = recipientObj.get("name").isString().stringValue();
                    titleLinkUrl =
                        Session.getInstance()
                            .generateUrl(new CreateUrlRequest(Page.GROUPS, shortName));
                  }
                  searchBoxWidget.onSearchCanceled();
                  searchStatusWidget.onSearchCanceled();
                } else {
                  searchBoxWidget.onSearchCanceled();
                  searchStatusWidget.onSearchCanceled();
                }

                sort = sortPanel.getSort();

                updatedJson =
                    StreamJsonRequestFactory.setSort(
                            sort, StreamJsonRequestFactory.getJSONRequest(updatedJson))
                        .toString();

                streamTitleWidget.setStreamTitle(streamName, titleLinkUrl);
                addGadgetWidget.setStreamTitle(streamName);
                searchBoxWidget.setCanChange(canChange);
                searchStatusWidget.setCanChange(canChange);

                StreamModel.getInstance().fetch(updatedJson, false);
              }
            }
          }
        });

    eventBus.addObserver(
        StreamSearchBeginEvent.class,
        new Observer<StreamSearchBeginEvent>() {
          public void update(final StreamSearchBeginEvent event) {
            eventBus.notifyObservers(
                new UpdateHistoryEvent(
                    new CreateUrlRequest("search", event.getSearchText(), false)));
          }
        });

    eventBus.addObserver(
        DeletedActivityResponseEvent.class,
        new Observer<DeletedActivityResponseEvent>() {
          public void update(final DeletedActivityResponseEvent ev) {
            eventBus.notifyObservers(
                new ShowNotificationEvent(new Notification("Activity has been deleted")));
          }
        });
  }