/*
 * 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.codeInsight.generation.actions;

import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class GenerateAction extends DumbAwareAction {
  @Override
  public void actionPerformed(@NotNull final AnActionEvent e) {
    DataContext dataContext = e.getDataContext();

    Project project = ObjectUtils.assertNotNull(getEventProject(e));
    final ListPopup popup =
      JBPopupFactory.getInstance().createActionGroupPopup(
          CodeInsightBundle.message("generate.list.popup.title"),
                                                          wrapGroup(getGroup(), dataContext, project),
                                                          dataContext,
                                                          JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
                                                          false);

    popup.showInBestPositionFor(dataContext);
  }

  @Override
  public void update(@NotNull AnActionEvent event){
    Presentation presentation = event.getPresentation();
    DataContext dataContext = event.getDataContext();
    Project project = CommonDataKeys.PROJECT.getData(dataContext);
    if (project == null) {
      presentation.setEnabled(false);
      return;
    }

    Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
    if (editor == null) {
      presentation.setEnabled(false);
      return;
    }

    boolean groupEmpty = ActionGroupUtil.isGroupEmpty(getGroup(), event, LaterInvocator.isInModalContext());
    presentation.setEnabled(!groupEmpty);
  }

  private static DefaultActionGroup getGroup() {
    return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_GENERATE);
  }

  private static DefaultActionGroup wrapGroup(DefaultActionGroup actionGroup, DataContext dataContext, @NotNull Project project) {
    final DefaultActionGroup copy = new DefaultActionGroup();
    for (final AnAction action : actionGroup.getChildren(null)) {
      if (DumbService.isDumb(project) && !action.isDumbAware()) {
        continue;
      }
      
      if (action instanceof GenerateActionPopupTemplateInjector) {
        final AnAction editTemplateAction = ((GenerateActionPopupTemplateInjector)action).createEditTemplateAction(dataContext);
        if (editTemplateAction != null) {
          copy.add(new GenerateWrappingGroup(action, editTemplateAction));
          continue;
        }
      }
      if (action instanceof DefaultActionGroup) {
        copy.add(wrapGroup((DefaultActionGroup)action, dataContext, project));
      }
      else {
        copy.add(action);
      }
    }
    return copy;
  }

  private static class GenerateWrappingGroup extends ActionGroup {

    private final AnAction myAction;
    private final AnAction myEditTemplateAction;

    GenerateWrappingGroup(AnAction action, AnAction editTemplateAction) {
      myAction = action;
      myEditTemplateAction = editTemplateAction;
      copyFrom(action);
      setPopup(true);
    }

    @Override
    public boolean canBePerformed(@NotNull DataContext context) {
      return true;
    }

    @NotNull
    @Override
    public AnAction[] getChildren(@Nullable AnActionEvent e) {
      return new AnAction[] {myEditTemplateAction};
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
      final Project project = getEventProject(e);
      assert project != null;
      final DumbService dumbService = DumbService.getInstance(project);
      try {
        dumbService.setAlternativeResolveEnabled(true);
        myAction.actionPerformed(e);
      }
      finally {
        dumbService.setAlternativeResolveEnabled(false);
      }
    }
  }
}
@@ -1,13 +1,10 @@
 /
-*%0A *
+/
  Copyrig
@@ -13,17 +13,17 @@
  2000-20
-0
+1
 9 JetBra
@@ -36,566 +36,109 @@
 r.o.
-%0A *%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A *%0A * http://www.apache.org/licenses/LICENSE-2.0%0A *%0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A */
+ Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 %0A%0Apa
@@ -1689,122 +1689,301 @@
     
-DataContext dataContext = event.getDataContext();%0A    Project project = CommonDataKeys.PROJECT.getData(dataContext
+if (ActionPlaces.isPopupPlace(event.getPlace())) %7B%0A      presentation.setEnabledAndVisible(isEnabled(event));%0A    %7D%0A    else %7B%0A      presentation.setEnabled(isEnabled(event));%0A    %7D%0A  %7D%0A%0A  private static boolean isEnabled(@NotNull AnActionEvent event) %7B%0A    Project project = event.getProject(
 );%0A 
@@ -2018,52 +2018,20 @@
     
-p
 re
-sentation.setEnabled(false);%0A      return
+turn false
 ;%0A  
@@ -2055,16 +2055,30 @@
 ditor = 
+event.getData(
 CommonDa
@@ -2094,28 +2094,8 @@
 ITOR
-.getData(dataContext
 );%0A 
@@ -2129,52 +2129,20 @@
     
-p
 re
-sentation.setEnabled(false);%0A      return
+turn false
 ;%0A  
@@ -2263,32 +2263,15 @@
     
-p
 re
-sentation.setEnabled(
+turn 
 !gro
@@ -2277,17 +2277,16 @@
 oupEmpty
-)
 ;%0A  %7D%0A%0A 

Hide disabled Generate action in context menu