/*
 * Copyright 2000-2009 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.ide.actions;

import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.*;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class SelectInAction extends AnAction implements DumbAware {
  @Override
  public void actionPerformed(AnActionEvent e) {
    FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.select.in");
    SelectInContext context = SelectInContextImpl.createContext(e);
    if (context == null) return;
    invoke(e.getDataContext(), context);
  }

  @Override
  public void update(AnActionEvent event) {
    Presentation presentation = event.getPresentation();

    if (SelectInContextImpl.createContext(event) == null) {
      presentation.setEnabled(false);
      presentation.setVisible(false);
    }
    else {
      presentation.setEnabled(true);
      presentation.setVisible(true);
    }
  }

  private static void invoke(DataContext dataContext, SelectInContext context) {
    final List<SelectInTarget> targetVector = Arrays.asList(getSelectInManager(context.getProject()).getTargets());
    ListPopup popup;
    if (targetVector.isEmpty()) {
      DefaultActionGroup group = new DefaultActionGroup();
      group.add(new NoTargetsAction());
      popup = JBPopupFactory.getInstance().createActionGroupPopup(IdeBundle.message("title.popup.select.target"), group, dataContext,
                                                                  JBPopupFactory.ActionSelectionAid.MNEMONICS, true);
    }
    else {
      popup = JBPopupFactory.getInstance().createListPopup(new SelectInActionsStep(targetVector, context));
    }

    popup.showInBestPositionFor(dataContext);
  }

  private static class SelectInActionsStep extends BaseListPopupStep<SelectInTarget> {
    private final SelectInContext mySelectInContext;
    private final List<SelectInTarget> myVisibleTargets;

    public SelectInActionsStep(@NotNull final Collection<SelectInTarget> targetVector, SelectInContext selectInContext) {
      mySelectInContext = selectInContext;
      myVisibleTargets = new ArrayList<SelectInTarget>();
      for (SelectInTarget target : targetVector) {
        myVisibleTargets.add(target);
      }
      init(IdeBundle.message("title.popup.select.target"), myVisibleTargets, null);
    }

    @Override
    @NotNull
    public String getTextFor(final SelectInTarget value) {
      String text = value.toString();
      int n = myVisibleTargets.indexOf(value);
      return numberingText(n, text);
    }

    @Override
    public PopupStep onChosen(final SelectInTarget target, final boolean finalChoice) {
      if (finalChoice) {
        target.selectIn(mySelectInContext, true);
        return FINAL_CHOICE;
      }
      if (target instanceof CompositeSelectInTarget) {
        final ArrayList<SelectInTarget> subTargets = new ArrayList<SelectInTarget>(((CompositeSelectInTarget)target).getSubTargets(mySelectInContext));
        if (subTargets.size() > 0) {
          Collections.sort(subTargets, new SelectInManager.SelectInTargetComparator());
          return new SelectInActionsStep(subTargets, mySelectInContext);
        }
      }
      return FINAL_CHOICE;
    }

    @Override
    public boolean hasSubstep(final SelectInTarget selectedValue) {
      return selectedValue instanceof CompositeSelectInTarget &&
             ((CompositeSelectInTarget)selectedValue).getSubTargets(mySelectInContext).size() != 0;
    }

    @Override
    public boolean isSelectable(final SelectInTarget target) {
      return target.canSelect(mySelectInContext);
    }

    @Override
    public boolean isMnemonicsNavigationEnabled() {
      return true;
    }
  }

  private static String numberingText(final int n, String text) {
    if (n < 9) {
      text = "&" + (n + 1) + ". " + text;
    }
    else if (n == 9) {
      text = "&" + 0 + ". " + text;
    }
    else {
      text = "&" + (char)('A' + n - 10) + ". " + text;
    }
    return text;
  }

  private static SelectInManager getSelectInManager(Project project) {
    return SelectInManager.getInstance(project);
  }

  private static class NoTargetsAction extends AnAction {
    public NoTargetsAction() {
      super(IdeBundle.message("message.no.targets.available"));
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
    }
  }
}
@@ -1058,24 +1058,117 @@
 tPopupStep;%0A
+import com.intellij.openapi.wm.ToolWindow;%0Aimport com.intellij.openapi.wm.ToolWindowManager;%0A
 import org.j
@@ -3444,24 +3444,361 @@
 toString();%0A
+      String id = value.getMinorViewId() == null ? value.getToolWindowId() : null;%0A      ToolWindow toolWindow = id == null ? null : ToolWindowManager.getInstance(mySelectInContext.getProject()).getToolWindow(id);%0A      if (toolWindow != null) %7B%0A        text = text.replace(value.getToolWindowId(), toolWindow.getStripeTitle());%0A      %7D%0A
       int n 
@@ -4792,12 +4792,11 @@
 e() 
-!= 0
+%3E 1
 ;%0A  

use TW stripeTitle if needed. skip extra popup-step in case of one item.