package org.jetbrains.debugger.memory.view;

import com.intellij.icons.AllIcons;
import com.intellij.ui.JBProgressBar;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.components.BorderLayoutPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.view.InstancesWindow.FilteringCompletionReason;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

class FilteringProgressView extends BorderLayoutPanel {
  private final static String LIMIT_REACHED_LABEL = "Limit has been reached";
  private final static String INTERRUPTED_LABEL = "Filtering has been interrupted";

  private final JBProgressBar myProgressBar = new JBProgressBar();
  private final BorderLayoutPanel myProgressPanel = new BorderLayoutPanel();
  private final JBLabel myStopButton = new JBLabel(UIUtil.isUnderDarcula()
      ? AllIcons.Actions.Clean : AllIcons.Actions.CleanLight);
  private final JBLabel myProgressText = new JBLabel();

  private int myProceedCount = 0;
  private int myErrorCount = 0;
  private int myMatchedCount = 0;

  private boolean myIsInProcess = false;

  @Nullable
  private FilteringCompletionReason myCompletionReason = null;

  FilteringProgressView() {
    myStopButton.setOpaque(true);
    myProgressPanel.addToCenter(myProgressBar);
    myProgressPanel.addToRight(myStopButton);
    addToTop(myProgressText);
    addToCenter(myProgressPanel);
  }

  void addStopActionListener(@NotNull Runnable listener) {
    myStopButton.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        listener.run();
      }
    });
  }

  void updateProgress(int proceedCount, int matchedCount, int errorCount) {
    if (myIsInProcess) {
      myProceedCount += proceedCount;
      myMatchedCount += matchedCount;
      myErrorCount += errorCount;
      myProgressBar.setValue(myProceedCount);
      myProgressText.setText(getDescription());
    }
  }

  void start(int totalCount) {
    reset();
    myIsInProcess = true;
    myProgressBar.setMinimum(0);
    myProgressBar.setMaximum(totalCount);
    setProgressBarVisible(true);
  }

  void complete(@NotNull FilteringCompletionReason reason) {
    if (!myIsInProcess) {
      throw new IllegalStateException("First you need to start progress");
    }

    myIsInProcess = false;
    myCompletionReason = reason;
    myProgressText.setText(getDescription());
    setProgressBarVisible(false);
  }

  private void reset() {
    myIsInProcess = false;
    myErrorCount = 0;
    myProceedCount = 0;
    myMatchedCount = 0;
    myCompletionReason = null;
  }

  private void setProgressBarVisible(boolean value) {
    myProgressPanel.setVisible(value);
  }

  private String getDescription() {
    int total = myProgressBar.getMaximum();
    String itemsInfo = String.format("Shown: %d / %d", myMatchedCount, total);
    if (myIsInProcess || myCompletionReason == null) {
      return itemsInfo;
    }

    switch (myCompletionReason) {
      case ALL_CHECKED:
        break;
      case INTERRUPTED:
        itemsInfo = String.format("%s (%s)", itemsInfo, INTERRUPTED_LABEL);
        break;
      case LIMIT_REACHED:
        itemsInfo = String.format("%s (%s)", itemsInfo, LIMIT_REACHED_LABEL);
        break;
    }

    if (!myIsInProcess && myErrorCount != 0) {
      String errors = String.format("Errors: %d", myErrorCount);
      return String.format("<html>%s<br>%s</html>", itemsInfo, errors);
    }

    return itemsInfo;
  }
}

@@ -2172,24 +2172,101 @@
 otalCount);%0A
+    myProgressBar.setValue(0);%0A    myProgressText.setText(getDescription());%0A
     setProgr

Fix bug when progress information not updated if a new filtering task has been started