// Copyright (C) 2013 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.change;

import static com.google.gerrit.client.FormatUtil.formatAbsBytes;
import static com.google.gerrit.client.FormatUtil.formatAbsPercentage;
import static com.google.gerrit.client.FormatUtil.formatBytes;
import static com.google.gerrit.client.FormatUtil.formatPercentage;

import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeEditApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.changes.ReviewInfo;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.FileInfo;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.impl.HyperlinkImpl;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.progress.client.ProgressBar;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import java.sql.Timestamp;

public class FileTable extends FlowPanel {
  private static final FileTableResources R = GWT
      .create(FileTableResources.class);

  interface FileTableResources extends ClientBundle {
    @Source("file_table.css")
    FileTableCss css();
  }

  interface FileTableCss extends CssResource {
    String table();
    String nohover();
    String pointer();
    String reviewed();
    String status();
    String pathColumn();
    String commonPrefix();
    String renameCopySource();
    String draftColumn();
    String newColumn();
    String commentColumn();
    String deltaColumn1();
    String deltaColumn2();
    String inserted();
    String deleted();
    String restoreDelete();
  }

  public enum Mode {
    REVIEW,
    EDIT
  }

  private static final String DELETE;
  private static final String RESTORE;
  private static final String REVIEWED;
  private static final String OPEN;
  private static final int C_PATH = 3;
  private static final HyperlinkImpl link = GWT.create(HyperlinkImpl.class);

  static {
    DELETE = DOM.createUniqueId().replace('-', '_');
    RESTORE = DOM.createUniqueId().replace('-', '_');
    REVIEWED = DOM.createUniqueId().replace('-', '_');
    OPEN = DOM.createUniqueId().replace('-', '_');
    init(DELETE, RESTORE, REVIEWED, OPEN);
  }

  private static native void init(String d, String t, String r, String o) /*-{
    $wnd[d] = $entry(function(e,i) {
      @com.google.gerrit.client.change.FileTable::onDelete(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
    });
    $wnd[t] = $entry(function(e,i) {
      @com.google.gerrit.client.change.FileTable::onRestore(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
    });
    $wnd[r] = $entry(function(e,i) {
      @com.google.gerrit.client.change.FileTable::onReviewed(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
    });
    $wnd[o] = $entry(function(e,i) {
      return @com.google.gerrit.client.change.FileTable::onOpen(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i);
    });
  }-*/;

  private static void onDelete(NativeEvent e, int idx) {
    MyTable t = getMyTable(e);
    if (t != null) {
      t.onDelete(idx);
    }
  }

  private static boolean onRestore(NativeEvent e, int idx) {
    MyTable t = getMyTable(e);
    if (t != null) {
      t.onRestore(idx);
      e.preventDefault();
      e.stopPropagation();
      return false;
    }
    return true;
  }

  private static void onReviewed(NativeEvent e, int idx) {
    MyTable t = getMyTable(e);
    if (t != null) {
      t.onReviewed(InputElement.as(Element.as(e.getEventTarget())), idx);
    }
  }

  private static boolean onOpen(NativeEvent e, int idx) {
    if (link.handleAsClick(e.<Event> cast())) {
      MyTable t = getMyTable(e);
      if (t != null) {
        t.onOpenRow(1 + idx);
        e.preventDefault();
        e.stopPropagation();
        return false;
      }
    }
    return true;
  }

  private static MyTable getMyTable(NativeEvent event) {
    Element e = event.getEventTarget().cast();
    for (e = DOM.getParent(e); e != null; e = DOM.getParent(e)) {
      EventListener l = DOM.getEventListener(e);
      if (l instanceof MyTable) {
        return (MyTable) l;
      }
    }
    return null;
  }

  private PatchSet.Id base;
  private PatchSet.Id curr;
  private MyTable table;
  private boolean register;
  private JsArrayString reviewed;
  private String scrollToPath;
  private ChangeScreen.Style style;
  private Widget replyButton;
  private boolean editExists;
  private Mode mode;

  @Override
  protected void onLoad() {
    super.onLoad();
    R.css().ensureInjected();
  }

  public void set(PatchSet.Id base, PatchSet.Id curr, ChangeScreen.Style style,
      Widget replyButton, Mode mode, boolean editExists) {
    this.base = base;
    this.curr = curr;
    this.style = style;
    this.replyButton = replyButton;
    this.mode = mode;
    this.editExists = editExists;
  }

  void setValue(NativeMap<FileInfo> fileMap,
      Timestamp myLastReply,
      @Nullable NativeMap<JsArray<CommentInfo>> comments,
      @Nullable NativeMap<JsArray<CommentInfo>> drafts) {
    JsArray<FileInfo> list = fileMap.values();
    FileInfo.sortFileInfoByPath(list);

    DisplayCommand cmd = new DisplayCommand(fileMap, list,
        myLastReply, comments, drafts);
    if (cmd.execute()) {
      cmd.showProgressBar();
      Scheduler.get().scheduleIncremental(cmd);
    }
  }

  void markReviewed(JsArrayString reviewed) {
    if (table != null) {
      table.markReviewed(reviewed);
    } else {
      this.reviewed = reviewed;
    }
  }

  void unregisterKeys() {
    register = false;

    if (table != null) {
      table.setRegisterKeys(false);
    }
  }

  void registerKeys() {
    register = true;

    if (table != null) {
      table.setRegisterKeys(true);
    }
  }

  void scrollToPath(String path) {
    if (table != null) {
      table.scrollToPath(path);
    } else {
      scrollToPath = path;
    }
  }

  void openAll() {
    if (table != null) {
      String self = Gerrit.selfRedirect(null);
      for (FileInfo info : Natives.asList(table.list)) {
        Window.open(self + "#" + url(info), "_blank", null);
      }
    }
  }

  private void setTable(MyTable table) {
    clear();
    add(table);
    this.table = table;

    if (register) {
      table.setRegisterKeys(true);
    }
    if (reviewed != null) {
      table.markReviewed(reviewed);
      reviewed = null;
    }
    if (scrollToPath != null) {
      table.scrollToPath(scrollToPath);
      scrollToPath = null;
    }
  }

  private String url(FileInfo info) {
    return info.binary()
      ? Dispatcher.toUnified(base, curr, info.path())
      : mode == Mode.REVIEW
            ? Dispatcher.toPatch(base, curr, info.path())
            : Dispatcher.toEditScreen(curr, info.path());
  }

  private final class MyTable extends NavigationTable<FileInfo> {
    private final NativeMap<FileInfo> map;
    private final JsArray<FileInfo> list;

    MyTable(NativeMap<FileInfo> map, JsArray<FileInfo> list) {
      this.map = map;
      this.list = list;
      table.setWidth("");

      keysNavigation.add(
          new PrevKeyCommand(0, 'k', Util.C.patchTablePrev()),
          new NextKeyCommand(0, 'j', Util.C.patchTableNext()));
      keysNavigation.add(new OpenKeyCommand(0, 'o', Util.C.patchTableOpenDiff()));
      keysNavigation.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER,
          Util.C.patchTableOpenDiff()));

      keysNavigation.add(
          new OpenFileCommand(list.length() - 1, 0, '[', Resources.C.openLastFile()),
          new OpenFileCommand(0, 0, ']', Resources.C.openCommitMessage()));

      keysAction.add(new KeyCommand(0, 'r', PatchUtil.C.toggleReviewed()) {
        @Override
        public void onKeyPress(KeyPressEvent event) {
          int row = getCurrentRow();
          if (1 <= row && row <= MyTable.this.list.length()) {
            FileInfo info = MyTable.this.list.get(row - 1);
            InputElement b = getReviewed(info);
            boolean c = !b.isChecked();
            setReviewed(info, c);
            b.setChecked(c);
          }
        }
      });

      setSavePointerId(
          (base != null ? base.toString() + ".." : "")
          + curr.toString());
    }

    void onDelete(int idx) {
      String path = list.get(idx).path();
      ChangeEditApi.delete(curr.getParentKey().get(), path,
          new AsyncCallback<VoidResult>() {
            @Override
            public void onSuccess(VoidResult result) {
              Gerrit.display(PageLinks.toChangeInEditMode(
                  curr.getParentKey()));
            }

            @Override
            public void onFailure(Throwable caught) {
            }
          });
    }

    void onRestore(int idx) {
      String path = list.get(idx).path();
      ChangeEditApi.restore(curr.getParentKey().get(), path,
          new AsyncCallback<VoidResult>() {
            @Override
            public void onSuccess(VoidResult result) {
              Gerrit.display(PageLinks.toChangeInEditMode(
                  curr.getParentKey()));
            }

            @Override
            public void onFailure(Throwable caught) {
            }
          });
    }

    void onReviewed(InputElement checkbox, int idx) {
      setReviewed(list.get(idx), checkbox.isChecked());
    }

    private void setReviewed(FileInfo info, boolean r) {
      RestApi api = ChangeApi.revision(curr)
          .view("files")
          .id(info.path())
          .view("reviewed");
      if (r) {
        api.put(CallbackGroup.<ReviewInfo>emptyCallback());
      } else {
        api.delete(CallbackGroup.<ReviewInfo>emptyCallback());
      }
    }

    void markReviewed(JsArrayString reviewed) {
      for (int i = 0; i < reviewed.length(); i++) {
        FileInfo info = map.get(reviewed.get(i));
        if (info != null) {
          getReviewed(info).setChecked(true);
        }
      }
    }

    private InputElement getReviewed(FileInfo info) {
      CellFormatter fmt = table.getCellFormatter();
      Element e = fmt.getElement(1 + info._row(), 1);
      return InputElement.as(e.getFirstChildElement());
    }

    void scrollToPath(String path) {
      FileInfo info = map.get(path);
      if (info != null) {
        movePointerTo(1 + info._row(), true);
      }
    }

    @Override
    protected Object getRowItemKey(FileInfo item) {
      return item.path();
    }

    @Override
    protected int findRow(Object id) {
      FileInfo info = map.get((String) id);
      return info != null ? 1 + info._row() : -1;
    }

    @Override
    protected FileInfo getRowItem(int row) {
      if (1 <= row && row <= list.length()) {
        return list.get(row - 1);
      }
      return null;
    }

    @Override
    protected void onOpenRow(int row) {
      if (1 <= row && row <= list.length()) {
        Gerrit.display(url(list.get(row - 1)));
      }
    }

    @Override
    protected void onCellSingleClick(Event event, int row, int column) {
      if (column == C_PATH && link.handleAsClick(event)) {
        onOpenRow(row);
      } else {
        super.onCellSingleClick(event, row, column);
      }
    }

    private class OpenFileCommand extends KeyCommand {
      private final int index;

      OpenFileCommand(int index, int modifiers, char c, String helpText) {
        super(modifiers, c, helpText);
        this.index = index;
      }

      @Override
      public void onKeyPress(KeyPressEvent event) {
        Gerrit.display(url(list.get(index)));
      }
    }
  }

  private final class DisplayCommand implements RepeatingCommand {
    private final SafeHtmlBuilder sb = new SafeHtmlBuilder();
    private final MyTable myTable;
    private final JsArray<FileInfo> list;
    private final Timestamp myLastReply;
    private final NativeMap<JsArray<CommentInfo>> comments;
    private final NativeMap<JsArray<CommentInfo>> drafts;
    private final boolean hasUser;
    private final boolean showChangeSizeBars;
    private boolean attached;
    private int row;
    private double start;
    private ProgressBar meter;
    private String lastPath = "";

    private boolean hasBinaryFile;
    private boolean hasNonBinaryFile;
    private int inserted;
    private int deleted;
    private long binOldSize;
    private long bytesInserted;
    private long bytesDeleted;

    private DisplayCommand(NativeMap<FileInfo> map,
        JsArray<FileInfo> list,
        Timestamp myLastReply,
        @Nullable NativeMap<JsArray<CommentInfo>> comments,
        @Nullable NativeMap<JsArray<CommentInfo>> drafts) {
      this.myTable = new MyTable(map, list);
      this.list = list;
      this.myLastReply = myLastReply;
      this.comments = comments;
      this.drafts = drafts;
      this.hasUser = Gerrit.isSignedIn();
      this.showChangeSizeBars =
          Gerrit.getUserPreferences().sizeBarInChangeTable();
      myTable.addStyleName(R.css().table());
    }

    @Override
    public boolean execute() {
      boolean attachedNow = isAttached();
      if (!attached && attachedNow) {
        // Remember that we have been attached at least once. If
        // later we find we aren't attached we should stop running.
        attached = true;
      } else if (attached && !attachedNow) {
        // If the user navigated away, we aren't in the DOM anymore.
        // Don't continue to render.
        return false;
      }

      start = System.currentTimeMillis();
      if (row == 0) {
        header(sb);
        computeInsertedDeleted();
      }
      while (row < list.length()) {
        FileInfo info = list.get(row);
        info._row(row);
        render(sb, info);
        if ((++row % 10) == 0 && longRunning()) {
          updateMeter();
          return true;
        }
      }
      footer(sb);
      myTable.resetHtml(sb);
      myTable.finishDisplay();
      setTable(myTable);
      return false;
    }

    private void computeInsertedDeleted() {
      inserted = 0;
      deleted = 0;
      binOldSize = 0;
      bytesInserted = 0;
      bytesDeleted = 0;
      for (int i = 0; i < list.length(); i++) {
        FileInfo info = list.get(i);
        if (!Patch.COMMIT_MSG.equals(info.path())) {
          if (!info.binary()) {
            hasNonBinaryFile = true;
            inserted += info.linesInserted();
            deleted += info.linesDeleted();
          } else {
            hasBinaryFile = true;
            binOldSize += info.size() - info.sizeDelta();
            if (info.sizeDelta() >= 0) {
              bytesInserted += info.sizeDelta();
            } else {
              bytesDeleted += info.sizeDelta();
            }
          }
        }
      }
    }

    void showProgressBar() {
      if (meter == null) {
        meter = new ProgressBar(Util.M.loadingPatchSet(curr.get()));
        FileTable.this.clear();
        FileTable.this.add(meter);
      }
      updateMeter();
    }

    void updateMeter() {
      if (meter != null) {
        int n = list.length();
        meter.setValue((100 * row) / n);
      }
    }

    private boolean longRunning() {
      return System.currentTimeMillis() - start > 200;
    }

    private void header(SafeHtmlBuilder sb) {
      sb.openTr().setStyleName(R.css().nohover());
      sb.openTh().setStyleName(R.css().pointer()).closeTh();
      if (mode == Mode.REVIEW) {
        sb.openTh().setStyleName(R.css().reviewed()).closeTh();
      } else {
        sb.openTh().setStyleName(R.css().restoreDelete()).closeTh();
      }
      sb.openTh().setStyleName(R.css().status()).closeTh();
      sb.openTh().append(Util.C.patchTableColumnName()).closeTh();
      sb.openTh()
        .setAttribute("colspan", 3)
        .append(Util.C.patchTableColumnComments())
        .closeTh();
      sb.openTh()
        .setAttribute("colspan", 2)
        .append(Util.C.patchTableColumnSize())
        .closeTh();
      sb.closeTr();
    }

    private void render(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTr();
      sb.openTd().setStyleName(R.css().pointer()).closeTd();
      if (mode == Mode.REVIEW) {
        columnReviewed(sb, info);
      } else {
        columnDeleteRestore(sb, info);
      }
      columnStatus(sb, info);
      columnPath(sb, info);
      columnComments(sb, info);
      columnDelta1(sb, info);
      columnDelta2(sb, info);
      sb.closeTr();
    }

    private void columnReviewed(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd().setStyleName(R.css().reviewed());
      if (hasUser) {
        sb.openElement("input")
          .setAttribute("title", Resources.C.reviewedFileTitle())
          .setAttribute("type", "checkbox")
          .setAttribute("onclick", REVIEWED + "(event," + info._row() + ")")
          .closeSelf();
      }
      sb.closeTd();
    }

    private void columnDeleteRestore(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd().setStyleName(R.css().restoreDelete());
      if (hasUser) {
        if (!Patch.COMMIT_MSG.equals(info.path())) {
          boolean editable = isEditable(info);
          sb.openDiv()
            .openElement("button")
            .setAttribute("title", Resources.C.restoreFileInline())
            .setAttribute("onclick", RESTORE + "(event," + info._row() + ")")
            .append(new ImageResourceRenderer().render(
                Gerrit.RESOURCES.editUndo()))
            .closeElement("button");
          if (editable) {
            sb.openElement("button")
              .setAttribute("title", Resources.C.removeFileInline())
              .setAttribute("onclick", DELETE + "(event," + info._row() + ")")
              .append(new ImageResourceRenderer().render(
                  Gerrit.RESOURCES.redNot()))
              .closeElement("button");
          }
          sb.closeDiv();
        }
      }
      sb.closeTd();
    }

    private boolean isEditable(FileInfo info) {
      String status = info.status();
      return status == null
          || !ChangeType.DELETED.matches(status);
    }

    private void columnStatus(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd().setStyleName(R.css().status());
      if (!Patch.COMMIT_MSG.equals(info.path())
          && info.status() != null
          && !ChangeType.MODIFIED.matches(info.status())) {
        sb.append(info.status());
      }
      sb.closeTd();
    }

    private void columnPath(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd()
        .setStyleName(R.css().pathColumn())
        .openAnchor();

      String path = info.path();
      if (mode == Mode.EDIT && !isEditable(info)) {
        sb.setAttribute("onclick", RESTORE + "(event," + info._row() + ")");
      } else {
        sb.setAttribute("href", "#" + url(info))
          .setAttribute("onclick", OPEN + "(event," + info._row() + ")");
      }

      if (Patch.COMMIT_MSG.equals(path)) {
        sb.append(Util.C.commitMessage());
      } else if (Gerrit.getUserPreferences().muteCommonPathPrefixes()) {
        int commonPrefixLen = commonPrefix(path);
        if (commonPrefixLen > 0) {
          sb.openSpan().setStyleName(R.css().commonPrefix())
            .append(path.substring(0, commonPrefixLen))
            .closeSpan();
        }
        sb.append(path.substring(commonPrefixLen));
        lastPath = path;
      } else {
        sb.append(path);
      }

      sb.closeAnchor();
      if (info.oldPath() != null) {
        sb.br();
        sb.openSpan().setStyleName(R.css().renameCopySource())
          .append(info.oldPath())
          .closeSpan();
      }
      sb.closeTd();
    }

    private int commonPrefix(String path) {
      for (int n = path.length(); n > 0;) {
        int s = path.lastIndexOf('/', n);
        if (s < 0) {
          return 0;
        }

        String p = path.substring(0, s + 1);
        if (lastPath.startsWith(p)) {
          return s + 1;
        }
        n = s - 1;
      }
      return 0;
    }

    private void columnComments(SafeHtmlBuilder sb, FileInfo info) {
      JsArray<CommentInfo> cList = filterForParent(get(info.path(), comments));
      JsArray<CommentInfo> dList = filterForParent(get(info.path(), drafts));

      sb.openTd().setStyleName(R.css().draftColumn());
      if (dList.length() > 0) {
        sb.append("drafts: ").append(dList.length());
      }
      sb.closeTd();

      int cntAll = cList.length();
      int cntNew = 0;
      if (myLastReply != null) {
        for (int i = cntAll - 1; i >= 0; i--) {
          CommentInfo m = cList.get(i);
          if (m.updated().compareTo(myLastReply) > 0) {
            cntNew++;
          } else {
            break;
          }
        }
      }

      sb.openTd().setStyleName(R.css().newColumn());
      if (cntNew > 0) {
        sb.append("new: ").append(cntNew);
      }
      sb.closeTd();

      sb.openTd().setStyleName(R.css().commentColumn());
      if (cntAll - cntNew > 0) {
        sb.append("comments: ").append(cntAll - cntNew);
      }
      sb.closeTd();
    }

    private JsArray<CommentInfo> filterForParent(JsArray<CommentInfo> list) {
      JsArray<CommentInfo> result = JsArray.createArray().cast();
      for (CommentInfo c : Natives.asList(list)) {
        if (c.side() == Side.REVISION) {
          result.push(c);
        } else if (base == null && !c.hasParent()) {
          result.push(c);
        } else if (base != null && c.parent() == -base.get()) {
          result.push(c);
        }
      }
      return result;
    }

    private JsArray<CommentInfo> get(String p, NativeMap<JsArray<CommentInfo>> m) {
      JsArray<CommentInfo> r = null;
      if (m != null) {
        r = m.get(p);
      }
      if (r == null) {
        r = JsArray.createArray().cast();
      }
      return r;
    }

    private void columnDelta1(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd().setStyleName(R.css().deltaColumn1());
      if (!Patch.COMMIT_MSG.equals(info.path()) && !info.binary()) {
        if (showChangeSizeBars) {
          sb.append(info.linesInserted() + info.linesDeleted());
        } else if (!ChangeType.DELETED.matches(info.status())) {
          if (ChangeType.ADDED.matches(info.status())) {
            sb.append(info.linesInserted())
              .append(" lines");
          } else {
            sb.append("+")
              .append(info.linesInserted())
              .append(", -")
              .append(info.linesDeleted());
          }
        }
      } else if (info.binary()) {
        sb.append(formatBytes(info.sizeDelta()));
        long oldSize = info.size() - info.sizeDelta();
        if (oldSize != 0) {
          sb.append(" (")
            .append(formatPercentage(oldSize, info.sizeDelta()))
            .append(")");
        }
      }
      sb.closeTd();
    }

    private void columnDelta2(SafeHtmlBuilder sb, FileInfo info) {
      sb.openTd().setStyleName(R.css().deltaColumn2());
      if (showChangeSizeBars
          && !Patch.COMMIT_MSG.equals(info.path()) && !info.binary()
          && (info.linesInserted() != 0 || info.linesDeleted() != 0)) {
        int w = 80;
        int t = inserted + deleted;
        int i = Math.max(5, (int) (((double) w) * info.linesInserted() / t));
        int d = Math.max(5, (int) (((double) w) * info.linesDeleted() / t));

        sb.setAttribute(
            "title",
            Util.M.patchTableSize_LongModify(info.linesInserted(),
                info.linesDeleted()));

        if (0 < info.linesInserted()) {
          sb.openDiv()
            .setStyleName(R.css().inserted())
            .setAttribute("style", "width:" + i + "px")
            .closeDiv();
        }
        if (0 < info.linesDeleted()) {
          sb.openDiv()
            .setStyleName(R.css().deleted())
            .setAttribute("style", "width:" + d + "px")
            .closeDiv();
        }
      }
      sb.closeTd();
    }

    private void footer(SafeHtmlBuilder sb) {
      sb.openTr().setStyleName(R.css().nohover());
      sb.openTh().setStyleName(R.css().pointer()).closeTh();
      if (mode == Mode.REVIEW) {
        sb.openTh().setStyleName(R.css().reviewed()).closeTh();
      } else {
        sb.openTh().setStyleName(R.css().restoreDelete()).closeTh();
      }
      sb.openTh().setStyleName(R.css().status()).closeTh();
      sb.openTd().closeTd(); // path
      sb.openTd().setAttribute("colspan", 3).closeTd(); // comments

      // delta1
      sb.openTh().setStyleName(R.css().deltaColumn1());
      if (hasNonBinaryFile) {
        sb.append(Util.M.patchTableSize_Modify(inserted, deleted));
      }
      if (hasBinaryFile) {
        if (hasNonBinaryFile) {
          sb.br();
        }
        if (binOldSize != 0) {
          sb.append(Util.M.patchTableSize_ModifyBinaryFilesWithPercentages(
              formatAbsBytes(bytesInserted),
              formatAbsPercentage(binOldSize, bytesInserted),
              formatAbsBytes(bytesDeleted),
              formatAbsPercentage(binOldSize, bytesDeleted)));
        } else {
          sb.append(Util.M.patchTableSize_ModifyBinaryFiles(
              formatAbsBytes(bytesInserted),
              formatAbsBytes(bytesDeleted)));
        }
      }
      sb.closeTh();

      // delta2
      sb.openTh().setStyleName(R.css().deltaColumn2());
      if (showChangeSizeBars) {
        int w = 80;
        int t = inserted + deleted;
        int i = Math.max(1, (int) (((double) w) * inserted / t));
        int d = Math.max(1, (int) (((double) w) * deleted / t));
        if (i + d > w && i > d) {
          i = w - d;
        } else if (i + d > w && d > i) {
          d = w - i;
        }
        if (0 < inserted) {
          sb.openDiv()
          .setStyleName(R.css().inserted())
          .setAttribute("style", "width:" + i + "px")
          .closeDiv();
        }
        if (0 < deleted) {
          sb.openDiv()
            .setStyleName(R.css().deleted())
            .setAttribute("style", "width:" + d + "px")
            .closeDiv();
        }
      }
      sb.closeTh();

      sb.closeTr();
    }
  }
}
