/*
 * Copyright 2017 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
package io.flutter.actions;

import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.ide.projectWizard.NewProjectWizard;
import com.intellij.ide.projectWizard.ProjectTypeStep;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.components.JBList;
import com.intellij.util.ReflectionUtil;

// TODO(messick): Replace this with a wizard that does not include the first step of this wizard.
public class FlutterNewProjectAction extends AnAction {

  private ProjectTypeStep myProjectTypeStep;

  public FlutterNewProjectAction() {
    super("New Flutter Project...");
  }

  @Override
  public void actionPerformed(AnActionEvent e) {
    NewProjectWizard wizard = new NewProjectWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, null);
    ModuleWizardStep firstStep = wizard.getSequence().getAllSteps().get(0);
    myProjectTypeStep = (ProjectTypeStep)firstStep;
    // Using a private field messes up type analysis for generics. Can't be helped...
    JBList projectTypeList = fetchPrivateField("myProjectTypeList");
    CollectionListModel dataModel = (CollectionListModel)projectTypeList.getModel();
    Object flutterItem = null;
    for (Object item : dataModel.getItems()) {
      if (item.toString().equals("Flutter")) {
        flutterItem = item;
        break;
      }
    }
    // Remove all project types except Flutter. Need to verify that this does not cause a memory leak.
    if (flutterItem != null) {
      projectTypeList.setSelectedValue(flutterItem, false);
      // The list cannot be cleared because an empty list causes an NPE when the selected template is updated.
      for (Object item : dataModel.getItems().toArray()) {
        if (item != flutterItem) {
          //noinspection unchecked
          dataModel.remove(item);
        }
      }
    }
    NewProjectUtil.createNewProject(getEventProject(e), wizard);
  }

  private JBList fetchPrivateField(@SuppressWarnings("SameParameterValue") String fieldName) {
    return ReflectionUtil // Fetching a private field.
      .getField(ProjectTypeStep.class, myProjectTypeStep, JBList.class, fieldName);
  }
}

@@ -239,16 +239,123 @@
 ctUtil;%0A
+import com.intellij.ide.projectView.ProjectView;%0Aimport com.intellij.ide.projectView.impl.ProjectViewPane;%0A
 import c
@@ -453,24 +453,93 @@
 ctTypeStep;%0A
+import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;%0A
 import com.i
@@ -694,16 +694,333 @@
 nEvent;%0A
+import com.intellij.openapi.application.ApplicationManager;%0Aimport com.intellij.openapi.application.ModalityState;%0Aimport com.intellij.openapi.progress.ProgressManager;%0Aimport com.intellij.openapi.project.Project;%0Aimport com.intellij.openapi.project.ProjectBundle;%0Aimport com.intellij.openapi.project.ProjectManager;%0A
 import c
@@ -1075,24 +1075,76 @@
 esProvider;%0A
+import com.intellij.openapi.startup.StartupManager;%0A
 import com.i
@@ -1539,16 +1539,913 @@
 );%0A  %7D%0A%0A
+  private static void createNewProject(Project projectToClose, AbstractProjectWizard wizard) %7B%0A    final boolean proceed = ProgressManager.getInstance().runProcessWithProgressSynchronously(() -%3E %7B%0A      ProjectManager.getInstance().getDefaultProject(); //warm up components%0A    %7D, ProjectBundle.message(%22project.new.wizard.progress.title%22), true, null);%0A    if (!proceed) return;%0A    if (!wizard.showAndGet()) %7B%0A      return;%0A    %7D%0A%0A    final Project newProject = NewProjectUtil.createFromWizard(wizard, projectToClose);%0A    StartupManager.getInstance(newProject).registerPostStartupActivity(() -%3E %7B%0A      ApplicationManager.getApplication().invokeLater(() -%3E %7B%0A        // We want to show the Project view, not the Android view since it doesn't make the Dart code visible.%0A        ProjectView.getInstance(newProject).changeView(ProjectViewPane.ID);%0A      %7D, ModalityState.NON_MODAL);%0A    %7D);%0A  %7D%0A%0A
   @Overr
@@ -3642,24 +3642,27 @@
  %7D%0A    %7D%0A   
+ //
  NewProjectU
@@ -3661,24 +3661,100 @@
 ProjectUtil.
+createNewProject() does not return the project, so it is inlined below.%0A    
 createNewPro

Switch to Project view after creating a Flutter project (#1296)