/**
   * Constructor.
   *
   * @param inScope the scope.
   * @param inPostBoxDefaultText Text to show when box is empty.
   */
  public PostToStreamComposite(final StreamScope inScope, final String inPostBoxDefaultText) {
    postBoxDefaultText = inPostBoxDefaultText;
    setupWidgets(inScope);
    setupEvents();

    SystemSettingsModel.getInstance().fetch(null, true);
    onRemainingCharactersChanged();
  }
  /** Shows the ToS modal. */
  private void displayToS() {

    Session.getInstance()
        .getEventBus()
        .addObserver(
            GotSystemSettingsResponseEvent.class,
            new Observer<GotSystemSettingsResponseEvent>() {
              public void update(final GotSystemSettingsResponseEvent event) {
                if (displayTOS) {
                  Dialog.showCentered(
                      new TermsOfServiceDialogContent(
                          new TermsOfServiceDTO(event.getResponse().getTermsOfService()), false));
                }
              }
            });

    SystemSettingsModel.getInstance().fetch(null, true);
  }
  /**
   * Get the header composite.
   *
   * @param viewer the user.
   * @return the header composite.
   */
  HeaderComposite getHeaderComposite(final PersonModelView viewer) {
    panel.add(footerPanel);
    header.render(viewer);

    Session.getInstance()
        .getEventBus()
        .addObserver(
            GotSystemSettingsResponseEvent.class,
            new Observer<GotSystemSettingsResponseEvent>() {
              public void update(final GotSystemSettingsResponseEvent event) {
                final SystemSettings settings = event.getResponse();
                header.setSiteLabelTemplate(settings.getHeaderTemplate(), settings.getSiteLabel());
                footerPanel.setSiteLabelTemplate(
                    settings.getFooterTemplate(), settings.getSiteLabel());
              }
            });

    SystemSettingsModel.getInstance().fetch(null, true);

    return header;
  }
  /** Activate the control. */
  public void activate() {
    this.clear();
    this.setVisible(true);
    Widget avatar =
        new AvatarWidget(
            Session.getInstance().getCurrentPerson().getId(),
            Session.getInstance().getCurrentPerson().getAvatarId(),
            EntityType.PERSON,
            Size.VerySmall,
            Background.White);
    avatar.addStyleName("avatar");
    this.add(avatar);

    FlowPanel body = new FlowPanel();
    body.addStyleName("body");

    commentBox = new TextArea();
    body.add(commentBox);
    commentBox.setFocus(true);

    countDown = new Label(Integer.toString(MAXLENGTH));
    countDown.addStyleName("characters-remaining");
    body.add(countDown);

    post = new Hyperlink("post", History.getToken());
    post.addStyleName("post-button");
    post.addStyleName("inactive");

    final Label warning = new Label();
    warning.addStyleName("warning hidden");
    body.add(warning);

    Session.getInstance()
        .getEventBus()
        .addObserver(
            GotSystemSettingsResponseEvent.class,
            new Observer<GotSystemSettingsResponseEvent>() {
              public void update(final GotSystemSettingsResponseEvent event) {
                String text = event.getResponse().getContentWarningText();
                if (text != null && !text.isEmpty()) {
                  warning.removeStyleName("hidden");
                  warning.setText(text);
                }
              }
            });

    SystemSettingsModel.getInstance().fetch(null, true);

    post.addClickHandler(
        new ClickHandler() {
          public void onClick(final ClickEvent event) {
            fullCollapse = false;
            if (!inactive) {
              unActivate();
              CommentDTO comment = new CommentDTO();
              comment.setBody(commentBox.getText());
              comment.setActivityId(messageId);
              Session.getInstance()
                  .getActionProcessor()
                  .makeRequest(
                      new ActionRequestImpl<CommentDTO>("postActivityCommentAction", comment),
                      new AsyncCallback<CommentDTO>() {
                        /* implement the async call back methods */
                        public void onFailure(final Throwable caught) {}

                        public void onSuccess(final CommentDTO result) {
                          Session.getInstance()
                              .getEventBus()
                              .notifyObservers(new CommentAddedEvent(result, messageId));
                        }
                      });
            }
          }
        });
    body.add(post);

    this.add(body);
    commentBox.setFocus(true);
    nativeSetFocus(commentBox.getElement());

    commentBox.addBlurHandler(
        new BlurHandler() {
          public void onBlur(final BlurEvent arg0) {
            TimerFactory timerFactory = new TimerFactory();
            timerFactory.runTimer(
                BLUR_DELAY,
                new TimerHandler() {
                  public void run() {
                    if (commentBox.getText().length() == 0) {
                      unActivate();
                    }
                  }
                });
          }
        });

    commentBox.addKeyPressHandler(
        new KeyPressHandler() {
          public void onKeyPress(final KeyPressEvent event) {
            if (event.getCharCode() == KeyCodes.KEY_ESCAPE) {
              unActivate();
            }
          }
        });

    commentBox.addKeyUpHandler(
        new KeyUpHandler() {
          public void onKeyUp(final KeyUpEvent event) {
            onCommentChanges();
          }
        });

    commentBox.addChangeHandler(
        new ChangeHandler() {
          public void onChange(final ChangeEvent event) {
            onCommentChanges();
          }
        });
  }
  /** Build page. */
  private void buildPage() {
    posterAvatar.add(
        avatarRenderer.render(
            Session.getInstance().getCurrentPerson().getEntityId(),
            Session.getInstance().getCurrentPerson().getAvatarId(),
            EntityType.PERSON,
            Size.Small));
    postCharCount.setInnerText(POST_MAX.toString());
    checkPostBox();
    postBox.setLabel("Post to your stream...");
    postBox.reset();

    addEvents();

    postBox.addKeyUpHandler(
        new KeyUpHandler() {
          public void onKeyUp(final KeyUpEvent event) {
            checkPostBox();
          }
        });

    postBox.addFocusHandler(
        new FocusHandler() {
          public void onFocus(final FocusEvent event) {
            postOptions.addClassName(style.visiblePostBox());
          }
        });

    postBox.addBlurHandler(
        new BlurHandler() {
          public void onBlur(final BlurEvent event) {

            timerFactory.runTimer(
                BLUR_DELAY,
                new TimerHandler() {
                  public void run() {
                    if (postBox.getText().trim().length() == 0
                        && !addLinkComposite.inAddMode()
                        && attachment == null) {
                      postOptions.removeClassName(style.visiblePostBox());
                      postBox.getElement().getStyle().clearHeight();
                      postBox.reset();
                    }
                  }
                });
          }
        });

    setupPostButtonClickHandler();

    postBox.addKeyDownHandler(
        new KeyDownHandler() {
          public void onKeyDown(final KeyDownEvent event) {
            if ((event.getNativeKeyCode() == KeyCodes.KEY_TAB
                    || event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
                && !event.isAnyModifierKeyDown()
                && activeItemIndex != null) {
              hashTags
                  .getWidget(activeItemIndex)
                  .getElement()
                  .dispatchEvent(
                      Document.get().createClickEvent(1, 0, 0, 0, 0, false, false, false, false));
              event.preventDefault();
              event.stopPropagation();
              // clearSearch();

            } else if (event.getNativeKeyCode() == KeyCodes.KEY_DOWN && activeItemIndex != null) {
              if (activeItemIndex + 1 < hashTags.getWidgetCount()) {
                selectItem((Label) hashTags.getWidget(activeItemIndex + 1));
              }
              event.preventDefault();
              event.stopPropagation();
            } else if (event.getNativeKeyCode() == KeyCodes.KEY_UP && activeItemIndex != null) {
              if (activeItemIndex - 1 >= 0) {
                selectItem((Label) hashTags.getWidget(activeItemIndex - 1));
              }
              event.preventDefault();
              event.stopPropagation();
            } else if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER && event.isControlKeyDown()) {
              postButton
                  .getElement()
                  .dispatchEvent(
                      Document.get().createClickEvent(1, 0, 0, 0, 0, false, false, false, false));
              event.preventDefault();
              event.stopPropagation();
            }
          }
        });

    postBox.addKeyUpHandler(
        new KeyUpHandler() {
          public void onKeyUp(final KeyUpEvent event) {
            int tagsAdded = 0;

            String postText = postBox.getText();
            if (!postText.endsWith(" ")) {
              String[] words = postText.split("\\s");
              if (words.length >= 1) {
                final String lastWord = words[words.length - 1];
                if (lastWord.startsWith("#")) {
                  boolean activeItemSet = false;
                  Label firstItem = null;

                  for (String hashTag : allHashTags) {
                    if (hashTag.startsWith(lastWord)) {
                      // get list ready on first tag added
                      if (tagsAdded == 0) {
                        hashTags.clear();

                        String boxHeight =
                            postBox.getElement().getStyle().getHeight().replace("px", "");
                        if (boxHeight.isEmpty()) {
                          boxHeight = "44";
                        }
                        hashTags
                            .getElement()
                            .getStyle()
                            .setTop(
                                Integer.parseInt(boxHeight) + HASH_TAG_DROP_DOWN_PADDING, Unit.PX);
                        hashTags.setVisible(true);
                      }

                      final String hashTagFinal = hashTag;
                      final Label tagLbl = new Label(hashTagFinal);
                      tagLbl.addClickHandler(
                          new ClickHandler() {
                            public void onClick(final ClickEvent event) {
                              String postText = postBox.getText();
                              postText =
                                  postText.substring(0, postText.length() - lastWord.length())
                                      + hashTagFinal
                                      + " ";
                              postBox.setText(postText);
                              hashTags.setVisible(false);
                              hashTags.clear();
                              activeItemIndex = null;
                            }
                          });
                      tagLbl.addMouseOverHandler(
                          new MouseOverHandler() {
                            public void onMouseOver(final MouseOverEvent arg0) {
                              selectItem(tagLbl);
                            }
                          });
                      hashTags.add(tagLbl);

                      if (firstItem == null) {
                        firstItem = tagLbl;
                      }

                      if (activeItemIndex != null
                          && activeItemIndex.equals(hashTags.getWidgetCount() - 1)) {
                        activeItemIndex = null;
                        activeItemSet = true;
                        selectItem(tagLbl);
                      }

                      tagsAdded++;
                      if (tagsAdded >= MAX_HASH_TAG_AUTOCOMPLETE_ENTRIES) {
                        break;
                      }
                    }
                  }

                  if (!activeItemSet && firstItem != null) {
                    activeItemIndex = null;
                    selectItem(firstItem);
                  }
                }
              }
            }

            if (tagsAdded == 0) {
              hashTags.setVisible(false);
              activeItemIndex = null;
            }
          }
        });

    AllPopularHashTagsModel.getInstance().fetch(null, true);
    SystemSettingsModel.getInstance().fetch(null, true);

    hashTags.setVisible(false);
  }
  /** Activate the control. */
  public void activate() {
    clear();
    this.setVisible(true);
    Widget avatar =
        new AvatarWidget(
            Session.getInstance().getCurrentPerson().getAvatarId(),
            EntityType.PERSON,
            Size.VerySmall);
    avatar.addStyleName(StaticResourceBundle.INSTANCE.coreCss().avatar());
    this.add(avatar);

    FlowPanel body = new FlowPanel();
    body.addStyleName(StaticResourceBundle.INSTANCE.coreCss().body());

    SimplePanel boxWrapper = new SimplePanel();
    boxWrapper.addStyleName(StaticResourceBundle.INSTANCE.coreCss().boxWrapper());
    commentBox = new ExtendedTextArea(true);
    boxWrapper.add(commentBox);
    body.add(boxWrapper);
    commentBox.setFocus(true);

    countDown = new Label(Integer.toString(MAXLENGTH));
    countDown.addStyleName(StaticResourceBundle.INSTANCE.coreCss().charactersRemaining());
    body.add(countDown);

    post = new PushButton("post");
    post.addStyleName(StaticResourceBundle.INSTANCE.coreCss().postButton());
    post.addStyleName(StaticResourceBundle.INSTANCE.coreCss().inactive());
    body.add(post);

    final Label warning = new Label();
    warning.addStyleName(StaticResourceBundle.INSTANCE.coreCss().warning());
    warning.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hidden());
    body.add(warning);

    Session.getInstance()
        .getEventBus()
        .addObserver(
            GotSystemSettingsResponseEvent.class,
            new Observer<GotSystemSettingsResponseEvent>() {
              public void update(final GotSystemSettingsResponseEvent event) {
                String text = event.getResponse().getContentWarningText();
                if (text != null && !text.isEmpty()) {
                  warning.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().hidden());
                  warning.setText(text);
                }
              }
            });

    SystemSettingsModel.getInstance().fetch(null, true);

    post.addClickHandler(
        new ClickHandler() {
          public void onClick(final ClickEvent event) {
            fullCollapse = false;
            if (!inactive) {
              unActivate();
              CommentDTO comment = new CommentDTO();
              comment.setBody(commentBox.getText());
              comment.setActivityId(messageId);
              Session.getInstance()
                  .getActionProcessor()
                  .makeRequest(
                      "postActivityCommentAction",
                      comment,
                      new AsyncCallback<CommentDTO>() {
                        /* implement the async call back methods */
                        public void onFailure(final Throwable caught) {}

                        public void onSuccess(final CommentDTO result) {
                          ActivityModel.getInstance().clearCache();
                          Session.getInstance()
                              .getEventBus()
                              .notifyObservers(new CommentAddedEvent(result, messageId));
                        }
                      });
            }
          }
        });

    this.add(body);
    commentBox.setFocus(true);
    nativeSetFocus(commentBox.getElement());

    commentBox.addBlurHandler(
        new BlurHandler() {
          public void onBlur(final BlurEvent arg0) {
            TimerFactory timerFactory = new TimerFactory();
            timerFactory.runTimer(
                BLUR_DELAY,
                new TimerHandler() {
                  public void run() {
                    if (commentBox.getText().length() == 0) {
                      unActivate();
                    }
                  }
                });
          }
        });

    commentBox.addKeyDownHandler(
        new KeyDownHandler() {
          public void onKeyDown(final KeyDownEvent event) {
            if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
              unActivate();
            } else if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER && event.isControlKeyDown()) {
              post.getElement()
                  .dispatchEvent(
                      Document.get().createClickEvent(1, 0, 0, 0, 0, false, false, false, false));
              event.preventDefault();
              event.stopPropagation();
            }
          }
        });

    commentBox.addKeyUpHandler(
        new KeyUpHandler() {
          public void onKeyUp(final KeyUpEvent event) {
            onCommentChanges();
          }
        });

    commentBox.addValueChangeHandler(
        new ValueChangeHandler<String>() {
          public void onValueChange(final ValueChangeEvent<String> inArg0) {
            onCommentChanges();
          }
        });

    commentBox.addChangeHandler(
        new ChangeHandler() {
          public void onChange(final ChangeEvent event) {
            onCommentChanges();
          }
        });
  }