// Copyright (C) 2008 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.client.changes;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.GitwebLink;
import com.google.gerrit.client.change.DraftActions;
import com.google.gerrit.client.download.DownloadPanel;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.AccountLinkPanel;
import com.google.gerrit.client.ui.ActionDialog;
import com.google.gerrit.client.ui.CherryPickDialog;
import com.google.gerrit.client.ui.ComplexDisclosurePanel;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.common.data.UiCommandDetail;
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Panel;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
    implements OpenHandler<DisclosurePanel> {
  private static final int R_AUTHOR = 0;
  private static final int R_COMMITTER = 1;
  private static final int R_PARENTS = 2;
  private static final int R_DOWNLOAD = 3;
  private static final int R_CNT = 4;

  private final ChangeDetailCache detailCache;
  private final ChangeDetail changeDetail;
  private final PatchSet patchSet;
  private final FlowPanel body;

  private Grid infoTable;
  private Panel actionsPanel;
  private PatchTable patchTable;
  private final Set<ClickHandler> registeredClickHandler =  new HashSet<>();

  private PatchSet.Id diffBaseId;

  /**
   * Creates a closed complex disclosure panel for a patch set.
   * The patch set details are loaded when the complex disclosure panel is opened.
   */
  public PatchSetComplexDisclosurePanel(final PatchSet ps, boolean isOpen,
      boolean hasDraftComments) {
    super(Util.M.patchSetHeader(ps.getPatchSetId()), isOpen);
    detailCache = ChangeCache.get(ps.getId().getParentKey()).getChangeDetailCache();
    changeDetail = detailCache.get();
    patchSet = ps;

    body = new FlowPanel();
    setContent(body);

    if (hasDraftComments) {
      final Image draftComments = new Image(Gerrit.RESOURCES.draftComments());
      draftComments.setTitle(Util.C.patchSetWithDraftCommentsToolTip());
      getHeader().add(draftComments);
    }

    final GitwebLink gw = Gerrit.getGitwebLink();
    final InlineLabel revtxt = new InlineLabel(ps.getRevision().get() + " ");
    revtxt.addStyleName(Gerrit.RESOURCES.css().patchSetRevision());
    getHeader().add(revtxt);
    if (gw != null && gw.canLink(ps)) {
      final Anchor revlink =
          new Anchor(gw.getLinkName(), false, gw.toRevision(changeDetail.getChange()
              .getProject(), ps));
      revlink.addStyleName(Gerrit.RESOURCES.css().patchSetLink());
      getHeader().add(revlink);
    }

    if (ps.isDraft()) {
      final InlineLabel draftLabel = new InlineLabel(Util.C.draftPatchSetLabel());
      draftLabel.addStyleName(Gerrit.RESOURCES.css().patchSetRevision());
      getHeader().add(draftLabel);
    }

    if (isOpen) {
      ensureLoaded(changeDetail.getCurrentPatchSetDetail());
    } else {
      addOpenHandler(this);
    }

  }

  public void setDiffBaseId(PatchSet.Id diffBaseId) {
    this.diffBaseId = diffBaseId;
  }

  /**
   * Display the table showing the Author, Committer and Download links,
   * followed by the action buttons.
   */
  public void ensureLoaded(final PatchSetDetail detail) {
    loadInfoTable(detail);
    loadActionPanel(detail);
    loadPatchTable(detail);
  }

  public void loadInfoTable(final PatchSetDetail detail) {
    infoTable = new Grid(R_CNT, 2);
    infoTable.setStyleName(Gerrit.RESOURCES.css().infoBlock());
    infoTable.addStyleName(Gerrit.RESOURCES.css().patchSetInfoBlock());

    initRow(R_AUTHOR, Util.C.patchSetInfoAuthor());
    initRow(R_COMMITTER, Util.C.patchSetInfoCommitter());
    initRow(R_PARENTS, Util.C.patchSetInfoParents());
    initRow(R_DOWNLOAD, Util.C.patchSetInfoDownload());

    final CellFormatter itfmt = infoTable.getCellFormatter();
    itfmt.addStyleName(0, 0, Gerrit.RESOURCES.css().topmost());
    itfmt.addStyleName(0, 1, Gerrit.RESOURCES.css().topmost());
    itfmt.addStyleName(R_CNT - 1, 0, Gerrit.RESOURCES.css().bottomheader());
    itfmt.addStyleName(R_AUTHOR, 1, Gerrit.RESOURCES.css().useridentity());
    itfmt.addStyleName(R_COMMITTER, 1, Gerrit.RESOURCES.css().useridentity());
    itfmt.addStyleName(R_DOWNLOAD, 1, Gerrit.RESOURCES.css()
        .downloadLinkListCell());

    final PatchSetInfo info = detail.getInfo();
    displayUserIdentity(R_AUTHOR, info.getAuthor());
    displayUserIdentity(R_COMMITTER, info.getCommitter());
    displayParents(info.getParents());
    displayDownload();

    body.add(infoTable);
  }

  public void loadActionPanel(final PatchSetDetail detail) {
    if (!patchSet.getId().equals(diffBaseId)) {
      actionsPanel = new FlowPanel();
      actionsPanel.setStyleName(Gerrit.RESOURCES.css().patchSetActions());
      actionsPanel.setVisible(true);
      if (Gerrit.isSignedIn()) {
        if (changeDetail.canEdit()) {
          populateReviewAction();
          if (changeDetail.isCurrentPatchSet(detail)) {
            populateActions(detail);
          }
          populateCommands(detail);
        }
        if (detail.getPatchSet().isDraft()) {
          if (changeDetail.canPublish()) {
            populatePublishAction();
          }
          if (changeDetail.canDeleteDraft()
              && changeDetail.getPatchSets().size() > 1) {
            populateDeleteDraftPatchSetAction();
          }
        }
      }
      body.add(actionsPanel);
    }
  }

  public void loadPatchTable(final PatchSetDetail detail) {
    if (!patchSet.getId().equals(diffBaseId)) {
      patchTable = new PatchTable();
      patchTable.setSavePointerId("PatchTable " + patchSet.getId());
      patchTable.display(diffBaseId, detail);
      for (ClickHandler clickHandler : registeredClickHandler) {
        patchTable.addClickHandler(clickHandler);
      }
      patchTable.setRegisterKeys(true);
      setActive(true);
      body.add(patchTable);
    }
  }

  public class ChangeDownloadPanel extends DownloadPanel {
    public ChangeDownloadPanel(String project, String ref, boolean allowAnonymous) {
      super(project, ref, allowAnonymous);
    }

    @Override
    public void populateDownloadCommandLinks() {
      // This site prefers usage of the 'repo' tool, so suggest
      // that for easy fetch.
      //
      if (allowedSchemes.contains(DownloadScheme.REPO_DOWNLOAD)) {
        commands.add(cmdLinkfactory.new RepoCommandLink(projectName,
            changeDetail.getChange().getChangeId() + "/"
            + patchSet.getPatchSetId()));
      }

      if (!urls.isEmpty()) {
        if (allowedCommands.contains(DownloadCommand.CHECKOUT)
            || allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
          commands.add(cmdLinkfactory.new CheckoutCommandLink());
        }
        if (allowedCommands.contains(DownloadCommand.PULL)
            || allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
          commands.add(cmdLinkfactory.new PullCommandLink());
        }
        if (allowedCommands.contains(DownloadCommand.CHERRY_PICK)
            || allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
          commands.add(cmdLinkfactory.new CherryPickCommandLink());
        }
        if (allowedCommands.contains(DownloadCommand.FORMAT_PATCH)
            || allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
          commands.add(cmdLinkfactory.new FormatPatchCommandLink());
        }
      }
    }
  }

  private void displayDownload() {
    ChangeDownloadPanel dp = new ChangeDownloadPanel(
      changeDetail.getChange().getProject().get(),
      patchSet.getRefName(),
      changeDetail.isAllowsAnonymous());

    infoTable.setWidget(R_DOWNLOAD, 1, dp);
  }

  private void displayUserIdentity(final int row, final UserIdentity who) {
    if (who == null) {
      infoTable.clearCell(row, 1);
      return;
    }

    final FlowPanel fp = new FlowPanel();
    fp.setStyleName(Gerrit.RESOURCES.css().patchSetUserIdentity());
    if (who.getName() != null) {
      if (who.getAccount() != null) {
        fp.add(new AccountLinkPanel(who));
      } else {
        final InlineLabel lbl = new InlineLabel(who.getName());
        lbl.setStyleName(Gerrit.RESOURCES.css().accountName());
        fp.add(lbl);
      }
    }
    if (who.getEmail() != null) {
      fp.add(new InlineLabel("<" + who.getEmail() + ">"));
    }
    if (who.getDate() != null) {
      fp.add(new InlineLabel(FormatUtil.mediumFormat(who.getDate())));
    }
    infoTable.setWidget(row, 1, fp);
  }

  private void displayParents(final List<PatchSetInfo.ParentInfo> parents) {
    if (parents.size() == 0) {
      infoTable.setWidget(R_PARENTS, 1, new InlineLabel(Util.C.initialCommit()));
      return;
    }
    final Grid parentsTable = new Grid(parents.size(), 2);

    parentsTable.setStyleName(Gerrit.RESOURCES.css().parentsTable());
    parentsTable.addStyleName(Gerrit.RESOURCES.css().noborder());
    final CellFormatter ptfmt = parentsTable.getCellFormatter();
    int row = 0;
    for (PatchSetInfo.ParentInfo parent : parents) {
      parentsTable.setWidget(row, 0, new InlineLabel(parent.id.get()));
      ptfmt.addStyleName(row, 0, Gerrit.RESOURCES.css().noborder());
      ptfmt.addStyleName(row, 0, Gerrit.RESOURCES.css().monospace());
      parentsTable.setWidget(row, 1,
          new InlineLabel(Util.cropSubject(parent.shortMessage)));
      ptfmt.addStyleName(row, 1, Gerrit.RESOURCES.css().noborder());
      row++;
    }
    infoTable.setWidget(R_PARENTS, 1, parentsTable);
  }

  private void populateActions(final PatchSetDetail detail) {
    final boolean isOpen = changeDetail.getChange().getStatus().isOpen();

    if (isOpen && changeDetail.canSubmit()) {
      final Button b =
          new Button(Util.M
              .submitPatchSet(detail.getPatchSet().getPatchSetId()));
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          ChangeApi.submit(
              patchSet.getId().getParentKey().get(),
              patchSet.getRevision().get(),
              new GerritCallback<SubmitInfo>() {
                  public void onSuccess(SubmitInfo result) {
                    redisplay();
                  }

                  public void onFailure(Throwable err) {
                    if (SubmitFailureDialog.isConflict(err)) {
                      new SubmitFailureDialog(err.getMessage()).center();
                      redisplay();
                    } else {
                      b.setEnabled(true);
                      super.onFailure(err);
                    }
                  }

                  private void redisplay() {
                    Gerrit.display(
                        PageLinks.toChange(patchSet.getId().getParentKey()),
                        new ChangeScreen(patchSet.getId().getParentKey()));
                  }
              });
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.canRevert()) {
      final Button b = new Button(Util.C.buttonRevertChangeBegin());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          new ActionDialog(b, true, Util.C.revertChangeTitle(),
              Util.C.headingRevertMessage()) {
            {
              sendButton.setText(Util.C.buttonRevertChangeSend());
              message.setText(Util.M.revertChangeDefaultMessage(
                  detail.getInfo().getSubject(),
                  detail.getPatchSet().getRevision().get())
              );
            }

            @Override
            public void onSend() {
              ChangeApi.revert(changeDetail.getChange().getChangeId(),
                  getMessageText(), new GerritCallback<ChangeInfo>() {
                    @Override
                    public void onSuccess(ChangeInfo result) {
                      sent = true;
                      Gerrit.display(PageLinks.toChange(new Change.Id(result
                          ._number())));
                      hide();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                      enableButtons(true);
                      super.onFailure(caught);
                    }
                  });
            }
          }.center();
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.canCherryPick()) {
      final Button b = new Button(Util.C.buttonCherryPickChangeBegin());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          new CherryPickDialog(b, changeDetail.getChange().getProject()) {
            {
              sendButton.setText(Util.C.buttonCherryPickChangeSend());
              if (changeDetail.getChange().getStatus().isClosed()) {
                message.setText(Util.M.cherryPickedChangeDefaultMessage(
                    detail.getInfo().getMessage().trim(),
                    detail.getPatchSet().getRevision().get()));
              } else {
                message.setText(detail.getInfo().getMessage().trim());
              }
            }

            @Override
            public void onSend() {
              ChangeApi.cherrypick(changeDetail.getChange().getChangeId(),
                  patchSet.getRevision().get(),
                  getDestinationBranch(),
                  getMessageText(),
                  new GerritCallback<ChangeInfo>() {
                    @Override
                    public void onSuccess(ChangeInfo result) {
                      sent = true;
                      Gerrit.display(PageLinks.toChange(new Change.Id(result
                          ._number())));
                      hide();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                      enableButtons(true);
                      super.onFailure(caught);
                    }
                  });
            }
          }.center();
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.canAbandon()) {
      final Button b = new Button(Util.C.buttonAbandonChangeBegin());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          new ActionDialog(b, false, Util.C.abandonChangeTitle(),
              Util.C.headingAbandonMessage()) {
            {
              sendButton.setText(Util.C.buttonAbandonChangeSend());
            }

            @Override
            public void onSend() {
              // TODO: once the other users of ActionDialog have converted to
              // REST APIs, we can use createCallback() rather than providing
              // them directly.
              ChangeApi.abandon(changeDetail.getChange().getChangeId(),
                  getMessageText(), new GerritCallback<ChangeInfo>() {
                    @Override
                    public void onSuccess(ChangeInfo result) {
                      sent = true;
                      Gerrit.display(PageLinks.toChange(new Change.Id(result
                          ._number())));
                      hide();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                      enableButtons(true);
                      super.onFailure(caught);
                    }
                  });
            }
          }.center();
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.getChange().getStatus() == Change.Status.DRAFT
        && changeDetail.canDeleteDraft()) {
      final Button b = new Button(Util.C.buttonDeleteDraftChange());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          ChangeApi.deleteChange(patchSet.getId().getParentKey().get(),
              new GerritCallback<JavaScriptObject>() {
            public void onSuccess(JavaScriptObject result) {
              Gerrit.display(PageLinks.MINE);
            }

            public void onFailure(Throwable err) {
              if (SubmitFailureDialog.isConflict(err)) {
                new SubmitFailureDialog(err.getMessage()).center();
                Gerrit.display(PageLinks.MINE);
              } else {
                b.setEnabled(true);
                super.onFailure(err);
              }
            }
          });
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.canRestore()) {
      final Button b = new Button(Util.C.buttonRestoreChangeBegin());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          new ActionDialog(b, false, Util.C.restoreChangeTitle(),
              Util.C.headingRestoreMessage()) {
            {
              sendButton.setText(Util.C.buttonRestoreChangeSend());
            }

            @Override
            public void onSend() {
              ChangeApi.restore(changeDetail.getChange().getChangeId(),
                  getMessageText(), new GerritCallback<ChangeInfo>() {
                    @Override
                    public void onSuccess(ChangeInfo result) {
                      sent = true;
                      Gerrit.display(PageLinks.toChange(new Change.Id(result
                          ._number())));
                      hide();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                      enableButtons(true);
                      super.onFailure(caught);
                    }
                  });
            }
          }.center();
        }
      });
      actionsPanel.add(b);
    }

    if (changeDetail.canRebase()) {
      final Button b = new Button(Util.C.buttonRebaseChange());
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          final Change.Id id = patchSet.getId().getParentKey();
          ChangeApi.rebase(id.get(), patchSet.getRevision().get(),
              new GerritCallback<ChangeInfo>() {
                public void onSuccess(ChangeInfo result) {
                  Gerrit.display(PageLinks.toChange(id));
                }
              });
        }
      });
      actionsPanel.add(b);
    }
  }

  private void populateCommands(final PatchSetDetail detail) {
    for (final UiCommandDetail cmd : detail.getCommands()) {
      final Button b = new Button();
      b.setText(cmd.label);
      b.setEnabled(cmd.enabled);
      b.setTitle(cmd.title);
      b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          b.setEnabled(false);
          AsyncCallback<NativeString> cb =
              new AsyncCallback<NativeString>() {
                @Override
                public void onFailure(Throwable caught) {
                  b.setEnabled(true);
                  new ErrorDialog(caught).center();
                }

                @Override
                public void onSuccess(NativeString msg) {
                  b.setEnabled(true);
                  if (msg != null && !msg.asString().isEmpty()) {
                    Window.alert(msg.asString());
                  }
                  Gerrit.display(PageLinks.toChange(patchSet.getId()));
                }
              };
          RestApi api = ChangeApi.revision(patchSet.getId()).view(cmd.id);
          if ("PUT".equalsIgnoreCase(cmd.method)) {
            api.put(JavaScriptObject.createObject(), cb);
          } else if ("DELETE".equalsIgnoreCase(cmd.method)) {
            api.delete(cb);
          } else {
            api.post(JavaScriptObject.createObject(), cb);
          }
        }
      });
      actionsPanel.add(b);
    }
  }

  private void populateReviewAction() {
    final Button b = new Button(Util.C.buttonReview());
    b.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        Gerrit.display(Dispatcher.toPublish(patchSet.getId()));
      }
    });
    actionsPanel.add(b);
  }

  private void populatePublishAction() {
    final Button b = new Button(Util.C.buttonPublishPatchSet());
    b.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        b.setEnabled(false);
        final Change.Id id = patchSet.getId().getParentKey();
        ChangeApi.publish(id.get(),
            patchSet.getRevision().get(),
            DraftActions.cs(id));
      }
    });
    actionsPanel.add(b);
  }

  private void populateDeleteDraftPatchSetAction() {
    final Button b = new Button(Util.C.buttonDeleteDraftPatchSet());
    b.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        b.setEnabled(false);
        final Change.Id id = patchSet.getId().getParentKey();
        ChangeApi.deleteRevision(id.get(),
            patchSet.getRevision().get(),
            DraftActions.cs(id));
      }
    });
    actionsPanel.add(b);
  }

  public void refresh() {
    if (patchSet.getId().equals(diffBaseId)) {
      if (patchTable != null) {
        patchTable.setVisible(false);
      }
      if (actionsPanel != null) {
        actionsPanel.setVisible(false);
      }
    } else {
      if (patchTable != null) {
        if (patchTable.getBase() == null && diffBaseId == null
            || patchTable.getBase() != null
            && patchTable.getBase().equals(diffBaseId)) {
          actionsPanel.setVisible(true);
          patchTable.setVisible(true);
          return;
        }
      }

      AccountDiffPreference diffPrefs;
      if (patchTable == null) {
        diffPrefs = new ListenableAccountDiffPreference().get();
      } else {
        diffPrefs = patchTable.getPreferences().get();
        patchTable.setVisible(false);
      }

      Util.DETAIL_SVC.patchSetDetail2(diffBaseId, patchSet.getId(), diffPrefs,
          new GerritCallback<PatchSetDetail>() {
            @Override
            public void onSuccess(PatchSetDetail result) {
              if (actionsPanel != null) {
                actionsPanel.setVisible(true);
              } else {
                loadActionPanel(result);
              }
              loadPatchTable(result);
            }
          });
    }
  }

  @Override
  public void onOpen(final OpenEvent<DisclosurePanel> event) {
    if (infoTable == null) {
      AccountDiffPreference diffPrefs;
      if (diffBaseId == null) {
        diffPrefs = null;
      } else {
        diffPrefs = new ListenableAccountDiffPreference().get();
      }

      Util.DETAIL_SVC.patchSetDetail2(diffBaseId, patchSet.getId(), diffPrefs,
          new GerritCallback<PatchSetDetail>() {
            public void onSuccess(final PatchSetDetail result) {
              loadInfoTable(result);
              loadActionPanel(result);
            }
          });
    }
  }

  private void initRow(final int row, final String name) {
    infoTable.setText(row, 0, name);
    infoTable.getCellFormatter().addStyleName(row, 0,
        Gerrit.RESOURCES.css().header());
  }

  public PatchSet getPatchSet() {
    return patchSet;
  }

  /**
   * Adds a click handler to the patch table.
   * If the patch table is not yet initialized it is guaranteed that the click handler
   * is added to the patch table after initialization.
   */
  public void addClickHandler(final ClickHandler clickHandler) {
    registeredClickHandler.add(clickHandler);
    if (patchTable != null) {
      patchTable.addClickHandler(clickHandler);
    }
  }

  /** Activates / Deactivates the key navigation and the highlighting of the current row for the patch table */
  public void setActive(boolean active) {
    if (patchTable != null) {
      patchTable.setActive(active);
    }
  }
}
