/*
 * 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.
 */

/*
 * User: anna
 * Date: 16-Jan-2008
 */
package com.intellij.packageDependencies.ui;

import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.scopeChooser.GroupByScopeTypeAction;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.search.scope.packageSet.PackageSet;
import com.intellij.psi.search.scope.packageSet.PatternPackageSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.Set;

public class PackagePatternProvider extends PatternDialectProvider {
  @NonNls public static final String PACKAGES = "package";
  private static final Logger LOG = Logger.getInstance("#" + PackagePatternProvider.class.getName());
   public static final Icon ICON = IconLoader.getIcon("/general/packagesTab.png");

  @Nullable
  private static GeneralGroupNode getGroupParent(PackageDependenciesNode node) {
    if (node instanceof GeneralGroupNode) return (GeneralGroupNode)node;
    if (node == null || node instanceof RootNode) return null;
    return getGroupParent((PackageDependenciesNode)node.getParent());
  }

  public PackageSet createPackageSet(final PackageDependenciesNode node, final boolean recursively) {
    GeneralGroupNode groupParent = getGroupParent(node);
    String scope1 = PatternPackageSet.SCOPE_ANY;
    if (groupParent != null) {
      String name = groupParent.toString();
      if (TreeModelBuilder.PRODUCTION_NAME.equals(name)) {
        scope1 = PatternPackageSet.SCOPE_SOURCE;
      }
      else if (TreeModelBuilder.TEST_NAME.equals(name)) {
        scope1 = PatternPackageSet.SCOPE_TEST;
      }
      else if (TreeModelBuilder.LIBRARY_NAME.equals(name)) {
        scope1 = PatternPackageSet.SCOPE_LIBRARY;
      }
    }
    final String scope = scope1;
    if (node instanceof ModuleGroupNode){
      if (!recursively) return null;
      @NonNls final String modulePattern = "group:" + ((ModuleGroupNode)node).getModuleGroup().toString();
      return new PatternPackageSet("*..*", scope, modulePattern);
    } else if (node instanceof ModuleNode) {
      if (!recursively) return null;
      final String modulePattern = ((ModuleNode)node).getModuleName();
      return new PatternPackageSet("*..*", scope, modulePattern);
    }
    else if (node instanceof PackageNode) {
      String pattern = ((PackageNode)node).getPackageQName();
      if (pattern != null) {
        pattern += recursively ? "..*" : ".*";
      }
      else {
        pattern = recursively ? "*..*" : ".*";
      }

      return new PatternPackageSet(pattern, scope, getModulePattern(node));
    }
    else if (node instanceof FileNode) {
      if (recursively) return null;
      FileNode fNode = (FileNode)node;
      final PsiElement element = fNode.getPsiElement();
      final StringBuilder buf = new StringBuilder(20);
      if (element instanceof PsiJavaFile) {
        final PsiJavaFile javaFile = (PsiJavaFile)element;
        String packageName = javaFile.getPackageName();
        buf.append(packageName);
        if (buf.length() > 0) {
          buf.append('.');
        }
        final VirtualFile virtualFile = javaFile.getVirtualFile();
        LOG.assertTrue(virtualFile != null);
        final String name = virtualFile.getNameWithoutExtension();
        if (!JavaPsiFacade.getInstance(element.getProject()).getNameHelper().isIdentifier(name)) return null;
        buf.append(name);
      }
      if (buf.length() > 0) {
        return new PatternPackageSet(buf.toString(), scope, getModulePattern(node));
      }
    }
    else if (node instanceof GeneralGroupNode) {
      return new PatternPackageSet("*..*", scope, null);
    }

    return null;
  }

  public Icon getIcon() {
    return ICON;
  }

  public TreeModel createTreeModel(final Project project, final Marker marker) {
    return TreeModelBuilder.createTreeModel(project, false, marker);
  }

  public TreeModel createTreeModel(final Project project, final Set<PsiFile> deps, final Marker marker,
                                   final DependenciesPanel.DependencyPanelSettings settings) {
    return TreeModelBuilder.createTreeModel(project, false, deps, marker, settings);
  }

  public String getDisplayName() {
    return IdeBundle.message("title.packages");
  }

  @NotNull
  public String getShortName() {
    return PACKAGES;
  }

  public AnAction[] createActions(Project project, final Runnable update) {
    return new AnAction[]{new GroupByScopeTypeAction(update)};
  }
}
@@ -1083,23 +1083,26 @@
 .psi.Psi
-Element
+ClassOwner
 ;%0Aimport
@@ -1122,20 +1122,23 @@
 .psi.Psi
-File
+Element
 ;%0Aimport
@@ -1158,20 +1158,16 @@
 .psi.Psi
-Java
 File;%0Aim
@@ -3828,24 +3828,26 @@
 ceof Psi
-JavaFile
+ClassOwner
 ) %7B%0A    
@@ -3859,24 +3859,26 @@
 inal Psi
-JavaFile
+ClassOwner
  javaFil
@@ -3889,16 +3889,18 @@
 (Psi
-JavaFile
+ClassOwner
 )ele

package pattern should work for all class owners (e.g. groovy)