/*
 * Copyright 2000-2016 JetBrains s.r.o.
 *
 * 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.intellij.vcs.log.ui.frame;

import com.google.common.primitives.Ints;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.ui.components.JBLoadingPanel;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.data.VcsLogData;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.util.List;

public abstract class CommitSelectionListener implements ListSelectionListener {
  private final static Logger LOG = Logger.getInstance(CommitSelectionListener.class);
  @NotNull private final VcsLogData myLogData;
  @NotNull private final VcsLogGraphTable myGraphTable;
  @NotNull private final JBLoadingPanel myLoadingPanel;

  @Nullable private ProgressIndicator myLastRequest;

  protected CommitSelectionListener(@NotNull VcsLogData data, @NotNull VcsLogGraphTable table, @NotNull JBLoadingPanel panel) {
    myLogData = data;
    myGraphTable = table;
    myLoadingPanel = panel;
  }

  @Override
  public void valueChanged(@Nullable ListSelectionEvent event) {
    if (event != null && event.getValueIsAdjusting()) return;

    if (myLastRequest != null) myLastRequest.cancel();
    myLastRequest = null;

    int rows = myGraphTable.getSelectedRowCount();
    if (rows < 1) {
      myLoadingPanel.stopLoading();
      onEmptySelection();
    }
    else {
      onSelection(myGraphTable.getSelectedRows());
      myLoadingPanel.startLoading();

      final EmptyProgressIndicator indicator = new EmptyProgressIndicator();
      myLastRequest = indicator;

      List<Integer> selectionToLoad = getSelectionToLoad();
      myLogData.getCommitDetailsGetter()
        .loadCommitsData(myGraphTable.getModel().convertToCommitIds(selectionToLoad), detailsList -> {
        if (myLastRequest == indicator && !(indicator.isCanceled())) {
          LOG.assertTrue(selectionToLoad.size() == detailsList.size(),
                         "Loaded incorrect number of details " + detailsList + " for selection " + selectionToLoad);
          myLastRequest = null;
          onDetailsLoaded(detailsList);
          myLoadingPanel.stopLoading();
        }
      }, indicator);
    }
  }

  @NotNull
  protected List<Integer> getSelectionToLoad() {
    return Ints.asList(myGraphTable.getSelectedRows());
  }

  @CalledInAwt
  protected abstract void onDetailsLoaded(@NotNull List<VcsFullCommitDetails> detailsList);

  @CalledInAwt
  protected abstract void onSelection(@NotNull int[] selection);

  @CalledInAwt
  protected abstract void onEmptySelection();
}
@@ -676,16 +676,76 @@
 s.Ints;%0A
+import com.intellij.openapi.application.ApplicationManager;%0A
 import c
@@ -779,24 +779,24 @@
 tic.Logger;%0A
-
 import com.i
@@ -1622,16 +1622,68 @@
 Panel;%0A%0A
+  @Nullable private ListSelectionEvent myLastEvent;%0A
   @Nulla
@@ -2077,16 +2077,41 @@
 eturn;%0A%0A
+    myLastEvent = event;%0A
     if (
@@ -2184,16 +2184,152 @@
  null;%0A%0A
+    ApplicationManager.getApplication().invokeLater(this::processEvent, o -%3E myLastEvent != event);%0A  %7D%0A%0A  public void processEvent() %7B%0A
     int 
@@ -2878,24 +2878,26 @@
 %3E %7B%0A        
+  
 if (myLastRe
@@ -2943,24 +2943,26 @@
 celed())) %7B%0A
+  
           LO
@@ -3045,16 +3045,18 @@
         
+  
 %22Loaded 
@@ -3139,16 +3139,18 @@
 oLoad);%0A
+  
         
@@ -3183,16 +3183,18 @@
         
+  
 onDetail
@@ -3215,16 +3215,18 @@
 sList);%0A
+  
         
@@ -3261,26 +3261,30 @@
 ();%0A        
-%7D%0A
+  %7D%0A  
       %7D, ind

update details & changes later for faster keyboard scrolling