// 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.patches;

import com.google.gerrit.client.data.SideBySideLine;
import com.google.gerrit.client.data.SideBySidePatchDetail;
import com.google.gerrit.client.reviewdb.PatchLineComment;
import com.google.gerrit.client.ui.ComplexDisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import java.util.Iterator;
import java.util.List;

public class SideBySideTable extends AbstractPatchContentTable {
  private int fileCnt;
  private int maxLineNumber;

  protected int getFileCount() {
    return fileCnt;
  }

  protected String getFileTitle(int file) {
    return table.getText(0, 1 + file * 2 + 1);
  }

  @Override
  protected void onCellDoubleClick(final int row, int column) {
    if (column > 0 && getRowItem(row) instanceof SideBySideLineList) {
      final SideBySideLineList pl = (SideBySideLineList) getRowItem(row);
      final short file = (short) ((column - 1) / 2);
      if (column < (1 + file * 2 + 1)) {
        column++;
      }

      final SideBySideLine line = pl.lines.get(file);
      switch (line.getType()) {
        case DELETE:
        case EQUAL:
        case INSERT: {
          createCommentEditor(row + 1, column, line.getLineNumber(), file);
          break;
        }
      }
    }
  }

  @Override
  protected void onOpenItem(final Object item) {
    if (item instanceof SideBySideLineList) {
      final SideBySideLineList pl = (SideBySideLineList) item;
      final short file = (short) (pl.lines.size() - 1);
      final int row = getCurrentRow();
      final int column = 1 + file * 2 + 1;
      final SideBySideLine line = pl.lines.get(file);
      createCommentEditor(row + 1, column, line.getLineNumber(), file);
      return;
    }

    super.onOpenItem(item);
  }

  @Override
  protected void bindDrafts(final List<PatchLineComment> drafts) {
    int[] rows = new int[fileCnt];
    for (final PatchLineComment c : drafts) {
      final int side = fileFor(c);
      if (side < 0 || fileCnt <= side) {
        // We shouldn't have been given this draft; it doesn't display
        // in our current UI layout.
        //
        continue;
      }
      int row = rows[side];
      while (row < table.getRowCount()) {
        if (getRowItem(row) instanceof SideBySideLineList) {
          final SideBySideLineList pl = (SideBySideLineList) getRowItem(row);
          final SideBySideLine line = pl.lines.get(side);
          if (line != null && line.getLineNumber() >= c.getLine()) {
            break;
          }
        }
        row++;
      }
      row++;
      boolean needInsert = true;
      for (int cell = 0; cell < table.getCellCount(row); cell++) {
        final Widget w = table.getWidget(row, cell);
        if (w instanceof CommentEditorPanel
            || w instanceof ComplexDisclosurePanel) {
          needInsert = false;
          break;
        }
      }
      if (needInsert) {
        table.insertRow(row);
        table.getCellFormatter().setStyleName(row, 0, S_ICON_CELL);
      }
      bindComment(row, 1 + side * 2 + 1, c, true);
      rows[side] = row + 1;
    }
  }

  public void display(final SideBySidePatchDetail detail) {
    setPatchKey(detail.getPatch().getKey());
    initVersions(detail.getFileCount());
    setAccountInfoCache(detail.getAccounts());
    fileCnt = detail.getFileCount();
    maxLineNumber = detail.getLineCount();

    List<SideBySideLine> prior = null;

    // Generate the table in HTML, because its quicker than by DOM.
    // This pass does not include the line comments; they need full
    // GWT widgets and are relatively infrequent. We do them later.
    //
    final SafeHtmlBuilder nc = new SafeHtmlBuilder();
    appendHeader(nc);
    for (final List<SideBySideLine> pLine : detail.getLines()) {
      if (skipped(prior, pLine) > 0) {
        appendSkipLine(nc);
      }
      prior = pLine;
      appendFileLine(nc, pLine);
    }
    if (skipped(prior, null) > 0) {
      appendSkipLine(nc);
    }
    resetHtml(nc);

    // Insert the comment widgets now that the table DOM has been
    // parsed out of the HTML by the browser. We also bind each
    // of the row item objects.
    //
    int row = 1;
    prior = null;
    for (final List<SideBySideLine> pLine : detail.getLines()) {
      final int skipCnt = skipped(prior, pLine);
      if (skipCnt > 0) {
        bindSkipLine(row, skipCnt);
        row++;
      }
      prior = pLine;

      setRowItem(row, new SideBySideLineList(pLine));

      final int lineRow = row;
      for (int fileId = 0; fileId < fileCnt; fileId++) {
        final SideBySideLine s = pLine.get(fileId);
        if (s == null) {
          continue;
        }

        final List<PatchLineComment> comments = s.getComments();
        if (comments == null) {
          continue;
        }

        int commentRow = lineRow + 1;
        for (Iterator<PatchLineComment> ci = comments.iterator(); ci.hasNext();) {
          final PatchLineComment c = ci.next();
          boolean needInsert = true;
          for (int cell = 0; cell < table.getCellCount(commentRow); cell++) {
            final Widget w = table.getWidget(commentRow, cell);
            if (w instanceof CommentEditorPanel
                || w instanceof ComplexDisclosurePanel) {
              needInsert = false;
              break;
            }
          }
          if (needInsert) {
            table.insertRow(commentRow);
            table.getCellFormatter().setStyleName(commentRow, 0, S_ICON_CELL);
          }
          table.setWidget(commentRow, 1 + 2 * fileId, null);
          bindComment(commentRow, 1 + 2 * fileId + 1, c, !ci.hasNext());
          commentRow++;
        }
        row = Math.max(row, commentRow - 1);
      }
      row++;
    }
    final int skipCnt = skipped(prior, null);
    if (skipCnt > 0) {
      bindSkipLine(row, skipCnt);
      row++;
    }
  }

  private void appendHeader(final SafeHtmlBuilder m) {
    final String width = (100 / fileCnt) + "%";
    m.openTr();

    m.openTd();
    m.addStyleName(S_ICON_CELL);
    m.addStyleName("FileColumnHeader");
    m.nbsp();
    m.closeTd();

    if (fileCnt == 2) {
      m.openTd();
      m.addStyleName("FileColumnHeader");
      m.addStyleName("LineNumber");
      m.nbsp();
      m.closeTd();

      m.openTd();
      m.setStyleName("FileColumnHeader");
      m.setAttribute("width", width);
      m.append(PatchUtil.C.patchHeaderOld());
      m.closeTd();
    } else {
      for (int fileId = 0; fileId < fileCnt - 1; fileId++) {
        m.openTd();
        m.addStyleName("FileColumnHeader");
        m.addStyleName("LineNumber");
        m.nbsp();
        m.closeTd();

        m.openTd();
        m.setStyleName("FileColumnHeader");
        m.setAttribute("width", width);
        m.append(PatchUtil.M.patchHeaderAncestor(fileId + 1));
        m.closeTd();
      }
    }

    m.openTd();
    m.addStyleName("FileColumnHeader");
    m.addStyleName("LineNumber");
    m.nbsp();
    m.closeTd();

    m.openTd();
    m.setStyleName("FileColumnHeader");
    m.setAttribute("width", width);
    m.append(PatchUtil.C.patchHeaderNew());
    m.closeTd();

    m.closeTr();
  }

  private int skipped(List<SideBySideLine> prior,
      final List<SideBySideLine> pLine) {
    int existCnt = 0;
    int gapCnt = 0;
    int lines = 0;

    if (prior != null && pLine != null) {
      for (int i = 0; i < fileCnt; i++) {
        final SideBySideLine ps = prior.get(i);
        final SideBySideLine cs = pLine.get(i);
        if (ps != null && cs != null) {
          existCnt++;
          if (ps.getLineNumber() + 1 != cs.getLineNumber()) {
            lines =
                Math.max(lines, cs.getLineNumber() - ps.getLineNumber() - 1);
            gapCnt++;
          }
        }
      }
    } else if (prior != null) {
      for (int i = 0; i < fileCnt; i++) {
        final SideBySideLine ps = prior.get(i);
        if (ps != null) {
          existCnt++;
          if (ps.getLineNumber() < maxLineNumber) {
            lines = Math.max(lines, maxLineNumber - ps.getLineNumber() - 1);
            gapCnt++;
          }
        }
      }
    } else {
      for (int i = 0; i < fileCnt; i++) {
        final SideBySideLine cs = pLine.get(i);
        if (cs != null) {
          existCnt++;
          if (1 != cs.getLineNumber()) {
            lines = Math.max(lines, cs.getLineNumber() - 1);
            gapCnt++;
          }
        }
      }
    }
    return existCnt == gapCnt ? lines : 0;
  }

  private void appendSkipLine(final SafeHtmlBuilder m) {
    m.openTr();

    m.openTd();
    m.setStyleName(S_ICON_CELL);
    m.nbsp();
    m.closeTd();

    m.openTd();
    m.setStyleName("SkipLine");
    m.setAttribute("colspan", fileCnt * 2);
    m.closeTd();
    m.closeTr();
  }

  private void bindSkipLine(int row, final int skipCnt) {
    final FlowPanel skipPanel = new FlowPanel();
    skipPanel.add(new InlineLabel(PatchUtil.M.patchSkipRegion(skipCnt)));
    table.setWidget(row, 1, skipPanel);
  }

  private void appendFileLine(final SafeHtmlBuilder m,
      final List<SideBySideLine> line) {
    m.openTr();
    m.setAttribute("valign", "top");

    m.openTd();
    m.setStyleName(S_ICON_CELL);
    m.nbsp();
    m.closeTd();

    for (int fileId = 0; fileId < fileCnt; fileId++) {
      final SideBySideLine s = line.get(fileId);
      if (s != null) {
        m.openTd();
        m.setStyleName("LineNumber");
        m.append(s.getLineNumber());
        m.closeTd();

        m.openTd();
        m.addStyleName("FileLine");
        m.addStyleName("FileLine-" + s.getType().name());
        if (!"".equals(s.getText())) {
          boolean showWhitespaceErrors = false;
          if (fileId == fileCnt - 1
              && s.getType() == SideBySideLine.Type.INSERT) {
            // Only show whitespace errors in the last column, and
            // only if the line is introduced here.
            //
            showWhitespaceErrors = true;
          }
          m.append(PatchUtil.lineToSafeHtml(s.getText(),
              PatchUtil.DEFAULT_LINE_LENGTH, showWhitespaceErrors));
        } else {
          m.nbsp();
        }
        m.closeTd();
      } else {
        m.openTd();
        m.setStyleName("LineNumber");
        m.nbsp();
        m.closeTd();

        m.openTd();
        m.addStyleName("FileLine");
        m.addStyleName("FileLineNone");
        m.nbsp();
        m.closeTd();
      }
    }

    m.closeTr();
  }

  private static class SideBySideLineList {
    final List<SideBySideLine> lines;

    SideBySideLineList(final List<SideBySideLine> a) {
      lines = a;
    }
  }
}
