// 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.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.Patch.PatchType;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.progress.client.ProgressBar;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class PatchTable extends Composite {
  interface PatchValidator {
    /**
     * @param patch
     * @return true if patch is valid.
     */
    boolean isValid(Patch patch);
  }

  final PatchValidator PREFERENCE_VALIDATOR =
      new PatchValidator() {
        @Override
        public boolean isValid(Patch patch) {
          return !((listenablePrefs.get().isSkipDeleted()
              && patch.getChangeType().equals(ChangeType.DELETED))
              || (listenablePrefs.get().isSkipUncommented()
              && patch.getCommentCount() == 0));
        }

      };

  private final FlowPanel myBody;
  private PatchSetDetail detail;
  private Command onLoadCommand;
  private MyTable myTable;
  private String savePointerId;
  private PatchSet.Id base;
  private List<Patch> patchList;
  private Map<Patch.Key, Integer> patchMap;
  private ListenableAccountDiffPreference listenablePrefs;

  private List<ClickHandler> clickHandlers;
  private boolean active;
  private boolean registerKeys;

  PatchTable(ListenableAccountDiffPreference prefs) {
    listenablePrefs = prefs;
    myBody = new FlowPanel();
    initWidget(myBody);
  }

  PatchTable() {
    this(new ListenableAccountDiffPreference());
  }

  int indexOf(Patch.Key patch) {
    Integer i = patchMap().get(patch);
    return i != null ? i : -1;
  }

  private Map<Patch.Key, Integer> patchMap() {
    if (patchMap == null) {
      patchMap = new HashMap<>();
      for (int i = 0; i < patchList.size(); i++) {
        patchMap.put(patchList.get(i).getKey(), i);
      }
    }
    return patchMap;
  }

  void display(PatchSet.Id base, PatchSetDetail detail) {
    this.base = base;
    this.detail = detail;
    this.patchList = detail.getPatches();
    this.patchMap = null;
    myTable = null;

    final DisplayCommand cmd = new DisplayCommand(patchList, base);
    if (cmd.execute()) {
      cmd.initMeter();
      Scheduler.get().scheduleIncremental(cmd);
    } else {
      cmd.showTable();
    }
  }

  PatchSet.Id getBase() {
    return base;
  }

  void setSavePointerId(final String id) {
    savePointerId = id;
  }

  boolean isLoaded() {
    return myTable != null;
  }

  void onTableLoaded(final Command cmd) {
    if (myTable != null) {
      cmd.execute();
    } else {
      onLoadCommand = cmd;
    }
  }

  void addClickHandler(final ClickHandler clickHandler) {
    if (myTable != null) {
      myTable.addClickHandler(clickHandler);
    } else {
      if (clickHandlers == null) {
        clickHandlers = new ArrayList<>(2);
      }
      clickHandlers.add(clickHandler);
    }
  }

  void setRegisterKeys(final boolean on) {
    registerKeys = on;
    if (myTable != null) {
      myTable.setRegisterKeys(on);
    }
  }

  void movePointerTo(final Patch.Key k) {
    if (myTable != null) {
      myTable.movePointerTo(k);
    }
  }

  void setActive(boolean active) {
    this.active = active;
    if (myTable != null) {
      myTable.setActive(active);
    }
  }

  void notifyDraftDelta(final Patch.Key k, final int delta) {
    if (myTable != null) {
      myTable.notifyDraftDelta(k, delta);
    }
  }

  private void setMyTable(MyTable table) {
    myBody.clear();
    myBody.add(table);
    myTable = table;

    if (clickHandlers != null) {
      for (ClickHandler ch : clickHandlers) {
        myTable.addClickHandler(ch);
      }
      clickHandlers = null;
    }

    if (active) {
      myTable.setActive(true);
      active = false;
    }

    if (registerKeys) {
      myTable.setRegisterKeys(registerKeys);
      registerKeys = false;
    }

    myTable.finishDisplay();
  }

  /**
   * @return a link to the previous file in this patch set, or null.
   */
  InlineHyperlink getPreviousPatchLink(int index) {
    int previousPatchIndex = getPreviousPatch(index, PREFERENCE_VALIDATOR);
    if (previousPatchIndex < 0) {
      return null;
    }
    return createLink(previousPatchIndex,
        SafeHtml.asis(Util.C.prevPatchLinkIcon()), null);
  }

  /**
   * @return a link to the next file in this patch set, or null.
   */
  InlineHyperlink getNextPatchLink(int index) {
    int nextPatchIndex = getNextPatch(index, false, PREFERENCE_VALIDATOR);
    if (nextPatchIndex < 0) {
      return null;
    }
    return createLink(nextPatchIndex, null,
        SafeHtml.asis(Util.C.nextPatchLinkIcon()));
  }

  /**
   * @return a link to the the given patch.
   * @param index The patch to link to
   * @param before A string to display at the beginning of the href text
   * @param after A string to display at the end of the href text
   */
  PatchLink createLink(int index, SafeHtml before, SafeHtml after) {
    Patch patch = patchList.get(index);
    Patch.Key thisKey = patch.getKey();
    PatchLink link;

    if (isUnifiedPatchLink(patch)) {
      link = new PatchLink.Unified("", base, thisKey);
    } else {
      link = new PatchLink.SideBySide("", base, thisKey);
    }

    SafeHtmlBuilder text = new SafeHtmlBuilder();
    text.append(before);
    text.append(getFileNameOnly(patch));
    text.append(after);
    SafeHtml.set(link, text);
    return link;
  }

  private static boolean isUnifiedPatchLink(final Patch patch) {
    return (patch.getPatchType().equals(PatchType.BINARY)
        || (Gerrit.isSignedIn()
            && Gerrit.getUserAccount().getGeneralPreferences().getDiffView()
            .equals(DiffView.UNIFIED_DIFF)));
  }

  private static String getFileNameOnly(Patch patch) {
    // Note: use '/' here and not File.pathSeparator since git paths
    // are always separated by /
    //
    String fileName = getDisplayFileName(patch);
    int s = fileName.lastIndexOf('/');
    if (s >= 0) {
      fileName = fileName.substring(s + 1);
    }
    return fileName;
  }

  static String getDisplayFileName(Patch patch) {
    return getDisplayFileName(patch.getKey());
  }

  static String getDisplayFileName(Patch.Key patchKey) {
    if (Patch.COMMIT_MSG.equals(patchKey.get())) {
      return Util.C.commitMessage();
    }
    return patchKey.get();
  }

  /**
   * Update the reviewed status for the given patch.
   */
  void updateReviewedStatus(Patch.Key patchKey, boolean reviewed) {
    if (myTable != null) {
      myTable.updateReviewedStatus(patchKey, reviewed);
    }
  }

  ListenableAccountDiffPreference getPreferences() {
    return listenablePrefs;
  }

  private class MyTable extends NavigationTable<Patch> {
    private static final int C_PATH = 2;
    private static final int C_DRAFT = 3;
    private static final int C_SIZE = 4;
    private static final int C_SIDEBYSIDE = 5;
    private int activeRow = -1;

    MyTable() {
      keysNavigation.add(new PrevKeyCommand(0, 'k', Util.C.patchTablePrev()));
      keysNavigation.add(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 OpenUnifiedDiffKeyCommand(0, 'O', Util.C
          .patchTableOpenUnifiedDiff()));

      table.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          final Cell cell = table.getCellForEvent(event);
          if (cell != null && cell.getRowIndex() > 0) {
            movePointerTo(cell.getRowIndex());
          }
        }
      });
      setSavePointerId(PatchTable.this.savePointerId);
    }

    public void addClickHandler(final ClickHandler clickHandler) {
      table.addClickHandler(clickHandler);
    }

    void updateReviewedStatus(final Patch.Key patchKey, boolean reviewed) {
      int idx = patchMap().get(patchKey);
      if (0 <= idx) {
        Patch patch = patchList.get(idx);
        if (patch.isReviewedByCurrentUser() != reviewed) {
          int row = idx + 1;
          int col = C_SIDEBYSIDE + 2;
          if (patch.getPatchType() == Patch.PatchType.BINARY) {
            col = C_SIDEBYSIDE + 3;
          }
          if (reviewed) {
            table.setWidget(row, col, new Image(Gerrit.RESOURCES.greenCheck()));
          } else {
            table.clearCell(row, col);
          }
          patch.setReviewedByCurrentUser(reviewed);
        }
      }
    }

    void notifyDraftDelta(final Patch.Key key, final int delta) {
      int idx = patchMap().get(key);
      if (0 <= idx) {
        Patch p = patchList.get(idx);
        p.setDraftCount(p.getDraftCount() + delta);
        SafeHtmlBuilder m = new SafeHtmlBuilder();
        appendCommentCount(m, p);
        SafeHtml.set(table, idx + 1, C_DRAFT, m);
      }
    }

    @Override
    public void resetHtml(final SafeHtml html) {
      super.resetHtml(html);
    }

    @Override
    public void movePointerTo(Object oldId) {
      super.movePointerTo(oldId);
    }

    /** Activates / Deactivates the key navigation and the highlighting of the current row for this table */
    void setActive(boolean active) {
      if (active) {
        if(activeRow > 0 && getCurrentRow() != activeRow) {
          super.movePointerTo(activeRow);
          activeRow = -1;
        }
      } else {
        if(getCurrentRow() > 0) {
          activeRow = getCurrentRow();
          super.movePointerTo(-1);
        }
      }
      setRegisterKeys(active);
    }

    void initializeRow(int row) {
      Patch patch = PatchTable.this.patchList.get(row - 1);
      setRowItem(row, patch);

      Widget nameCol = new PatchLink.SideBySide(getDisplayFileName(patch), base,
          patch.getKey());

      if (patch.getSourceFileName() != null) {
        final String text;
        if (patch.getChangeType() == Patch.ChangeType.RENAMED) {
          text = Util.M.renamedFrom(patch.getSourceFileName());
        } else if (patch.getChangeType() == Patch.ChangeType.COPIED) {
          text = Util.M.copiedFrom(patch.getSourceFileName());
        } else {
          text = Util.M.otherFrom(patch.getSourceFileName());
        }
        final Label line = new Label(text);
        line.setStyleName(Gerrit.RESOURCES.css().sourceFilePath());
        final FlowPanel cell = new FlowPanel();
        cell.add(nameCol);
        cell.add(line);
        nameCol = cell;
      }
      table.setWidget(row, C_PATH, nameCol);

      int C_UNIFIED = C_SIDEBYSIDE + 1;

      PatchLink sideBySide = new PatchLink.SideBySide(
          Util.C.patchTableDiffSideBySide(), base, patch.getKey());
      sideBySide.setStyleName("gwt-Anchor");

      PatchLink unified = new PatchLink.Unified(Util.C.patchTableDiffUnified(),
          base, patch.getKey());
      unified.setStyleName("gwt-Anchor");

      table.setWidget(row, C_SIDEBYSIDE, sideBySide);
      table.setWidget(row, C_UNIFIED, unified);
    }

    void initializeLastRow(int row) {
      Anchor sideBySide = new Anchor(Util.C.diffAllSideBySide());
      sideBySide.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          for (Patch p : detail.getPatches()) {
            openWindow(Dispatcher.toSideBySide(base, p.getKey()));
          }
        }
      });
      table.setWidget(row, C_SIDEBYSIDE - 2, sideBySide);

      int C_UNIFIED = C_SIDEBYSIDE - 2 + 1;
      Anchor unified = new Anchor(Util.C.diffAllUnified());
      unified.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          for (Patch p : detail.getPatches()) {
            openWindow(Dispatcher.toUnified(base, p.getKey()));
          }
        }
      });
      table.setWidget(row, C_UNIFIED, unified);
    }

    private void openWindow(String token) {
      String url = Window.Location.getPath() + "#" + token;
      Window.open(url, "_blank", null);
    }

    void appendHeader(final SafeHtmlBuilder m) {
      m.openTr();

      // Cursor
      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().iconHeader());
      m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());
      m.nbsp();
      m.closeTd();

      // Mode
      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().iconHeader());
      m.nbsp();
      m.closeTd();

      // "File path"
      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
      m.append(Util.C.patchTableColumnName());
      m.closeTd();

      // "Comments"
      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
      m.append(Util.C.patchTableColumnComments());
      m.closeTd();

      // "Size"
      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
      m.append(Util.C.patchTableColumnSize());
      m.closeTd();

      // "Diff"
      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
      m.setAttribute("colspan", 3);
      m.append(Util.C.patchTableColumnDiff());
      m.closeTd();

      // "Reviewed"
      if (Gerrit.isSignedIn()) {
        m.openTd();
        m.setStyleName(Gerrit.RESOURCES.css().iconHeader());
        m.addStyleName(Gerrit.RESOURCES.css().dataHeader());
        m.append(Util.C.reviewed());
        m.closeTd();
      }

      m.closeTr();
    }

    void appendRow(final SafeHtmlBuilder m, final Patch p,
        final boolean isReverseDiff) {
      m.openTr();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().iconCell());
      m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());
      m.nbsp();
      m.closeTd();

      m.openTd();
      m.setStyleName(Gerrit.RESOURCES.css().changeTypeCell());
      if (isReverseDiff) {
        m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
      }

      if (Patch.COMMIT_MSG.equals(p.getFileName())) {
        m.nbsp();
      } else {
        m.append(p.getChangeType().getCode());
      }
      m.closeTd();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().dataCell());
      m.addStyleName(Gerrit.RESOURCES.css().filePathCell());
      m.closeTd();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().dataCell());
      m.addStyleName(Gerrit.RESOURCES.css().commentCell());
      appendCommentCount(m, p);
      m.closeTd();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().dataCell());

      m.addStyleName(Gerrit.RESOURCES.css().patchSizeCell());
      if (isReverseDiff) {
        m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
      }

      appendSize(m, p);
      m.closeTd();

      // Diff
      openlink(m, 2);
      m.closeTd();
      openlink(m, 1);
      m.closeTd();

      // Green check mark if the user is logged in and they reviewed that file
      if (Gerrit.isSignedIn()) {
        m.openTd();
        m.setStyleName(Gerrit.RESOURCES.css().dataCell());
        if (p.isReviewedByCurrentUser()) {
          m.openDiv();
          m.setStyleName(Gerrit.RESOURCES.css().greenCheckClass());
          m.closeSelf();
        }
        m.closeTd();
      }

      m.closeTr();
    }

    void appendLastRow(final SafeHtmlBuilder m, int ins, int dels,
        final boolean isReverseDiff) {
      m.openTr();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().iconCell());
      m.addStyleName(Gerrit.RESOURCES.css().noborder());
      m.nbsp();
      m.closeTd();

      m.openTd();
      m.setAttribute("colspan", C_SIZE - 1);
      m.closeTd();

      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().dataCell());
      m.addStyleName(Gerrit.RESOURCES.css().patchSizeCell());
      m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());

      if (isReverseDiff) {
        m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
      }

      m.append(Util.M.patchTableSize_Modify(ins, dels));
      m.closeTd();

      openlink(m, 2);
      m.closeTd();

      openlink(m, 1);
      m.closeTd();

      m.closeTr();
    }

    void appendCommentCount(final SafeHtmlBuilder m, final Patch p) {
      if (p.getCommentCount() > 0) {
        m.append(Util.M.patchTableComments(p.getCommentCount()));
      }
      if (p.getDraftCount() > 0) {
        if (p.getCommentCount() > 0) {
          m.append(", ");
        }
        m.openSpan();
        m.setStyleName(Gerrit.RESOURCES.css().drafts());
        m.append(Util.M.patchTableDrafts(p.getDraftCount()));
        m.closeSpan();
      }
    }

    void appendSize(final SafeHtmlBuilder m, final Patch p) {
      if (Patch.COMMIT_MSG.equals(p.getFileName())) {
        m.nbsp();
        return;
      }

      if (p.getPatchType() == PatchType.UNIFIED) {
        int ins = p.getInsertions();
        int dels = p.getDeletions();

        switch (p.getChangeType()) {
          case ADDED:
            m.append(Util.M.patchTableSize_Lines(ins));
            break;

          case DELETED:
            m.nbsp();
            break;

          case MODIFIED:
          case COPIED:
          case RENAMED:
            m.append(Util.M.patchTableSize_Modify(ins, dels));
            break;

          case REWRITE:
            break;
        }
      } else {
        m.nbsp();
      }
    }

    private void openlink(final SafeHtmlBuilder m, final int colspan) {
      m.openTd();
      m.addStyleName(Gerrit.RESOURCES.css().dataCell());
      m.addStyleName(Gerrit.RESOURCES.css().diffLinkCell());
      m.setAttribute("colspan", colspan);
    }

    @Override
    protected Object getRowItemKey(final Patch item) {
      return item.getKey();
    }

    @Override
    protected void onOpenRow(final int row) {
      Widget link = table.getWidget(row, C_PATH);
      if (link instanceof FlowPanel) {
        link = ((FlowPanel) link).getWidget(0);
      }
      if (link instanceof InlineHyperlink) {
        ((InlineHyperlink) link).go();
      }
    }

    private final class OpenUnifiedDiffKeyCommand extends KeyCommand {

      public OpenUnifiedDiffKeyCommand(int mask, char key, String help) {
        super(mask, key, help);
      }

      @Override
      public void onKeyPress(KeyPressEvent event) {
        Widget link = table.getWidget(getCurrentRow(), C_PATH);
        if (link instanceof FlowPanel) {
          link = ((FlowPanel) link).getWidget(0);
        }
        if (link instanceof PatchLink.Unified) {
          ((InlineHyperlink) link).go();
        } else {
          link = table.getWidget(getCurrentRow(), C_SIDEBYSIDE + 1);
          if (link instanceof PatchLink.Unified) {
            ((InlineHyperlink) link).go();
          }
        }
      }
    }
  }

  private final class DisplayCommand implements RepeatingCommand {
    private final MyTable table;
    private final List<Patch> list;
    private boolean attached;
    private SafeHtmlBuilder nc = new SafeHtmlBuilder();
    private int stage = 0;
    private int row;
    private double start;
    private ProgressBar meter;

    private int insertions;
    private int deletions;

    private final PatchSet.Id psIdToCompareWith;

    private DisplayCommand(final List<Patch> list, final PatchSet.Id psIdToCompareWith) {
      this.table = new MyTable();
      this.list = list;
      this.psIdToCompareWith = psIdToCompareWith;
    }

    /**
     * Add the files contained in the list of patches to the table, one per row.
     */
    @Override
    @SuppressWarnings("fallthrough")
    public boolean execute() {
      final 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;
      }

      boolean isReverseDiff = false;

      if (psIdToCompareWith != null
          && list.get(0).getKey().getParentKey().get() < psIdToCompareWith.get()) {
        isReverseDiff = true;
      }

      start = System.currentTimeMillis();
      switch (stage) {
        case 0:
          if (row == 0) {
            table.appendHeader(nc);
            table.appendRow(nc, list.get(row++), isReverseDiff);
          }
          while (row < list.size()) {
            Patch p = list.get(row);
            insertions += p.getInsertions();
            deletions += p.getDeletions();
            table.appendRow(nc, p, isReverseDiff);
            if ((++row % 10) == 0 && longRunning()) {
              updateMeter();
              return true;
            }
          }
          table.appendLastRow(nc, insertions, deletions, isReverseDiff);
          table.resetHtml(nc);
          table.initializeLastRow(row + 1);
          nc = null;
          stage = 1;
          row = 0;

        case 1:
          while (row < list.size()) {
            table.initializeRow(row + 1);
            if ((++row % 50) == 0 && longRunning()) {
              updateMeter();
              return true;
            }
          }
          updateMeter();
          showTable();
      }
      return false;
    }

    void showTable() {
      setMyTable(table);

      if (PatchTable.this.onLoadCommand != null) {
        PatchTable.this.onLoadCommand.execute();
        PatchTable.this.onLoadCommand = null;
      }
    }

    void initMeter() {
      if (meter == null) {
        meter = new ProgressBar(Util.M.loadingPatchSet(detail.getPatchSet().getId().get()));
        PatchTable.this.myBody.clear();
        PatchTable.this.myBody.add(meter);
      }
      updateMeter();
    }

    void updateMeter() {
      if (meter != null) {
        final int n = list.size();
        meter.setValue(((100 * (stage * n + row)) / (2 * n)));
      }
    }

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


  /**
   * Gets the next patch
   *
   * @param currentIndex
   * @param validators
   * @param loopAround loops back around to the front and traverses if this is
   *        true
   * @return index of next valid patch, or -1 if no valid patches
   */
  int getNextPatch(int currentIndex, boolean loopAround,
      PatchValidator... validators) {
    return getNextPatchHelper(currentIndex, loopAround, detail.getPatches()
        .size(), validators);
  }

  /**
   * Helper function for getNextPatch
   *
   * @param currentIndex
   * @param validators
   * @param loopAround
   * @param maxIndex will only traverse up to this index
   * @return index of next valid patch, or -1 if no valid patches
   */
  private int getNextPatchHelper(int currentIndex, boolean loopAround,
      int maxIndex, PatchValidator... validators) {
    for (int i = currentIndex + 1; i < maxIndex; i++) {
      Patch patch = detail.getPatches().get(i);
      if (patch != null && patchIsValid(patch, validators)) {
        return i;
      }
    }

    if (loopAround) {
      return getNextPatchHelper(-1, false, currentIndex, validators);
    }

    return -1;
  }

  /**
   * @return the index to the previous patch
   */
  int getPreviousPatch(int currentIndex, PatchValidator... validators) {
    for (int i = currentIndex - 1; i >= 0; i--) {
      Patch patch = detail.getPatches().get(i);
      if (patch != null && patchIsValid(patch, validators)) {
        return i;
      }
    }

    return -1;
  }

  /**
   * Helper function that returns whether a patch is valid or not
   *
   * @param patch
   * @param validators
   * @return whether the patch is valid based on the validators
   */
  private boolean patchIsValid(Patch patch, PatchValidator... validators) {
    for (PatchValidator v : validators) {
      if (!v.isValid(patch)) {
        return false;
      }
    }
    return true;
  }
}
