/*
 * 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.hierarchy.type;

import com.intellij.ide.hierarchy.HierarchyProvider;
import com.intellij.ide.hierarchy.HierarchyBrowser;
import com.intellij.ide.hierarchy.TypeHierarchyBrowserBase;
import com.intellij.psi.*;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.editor.Editor;
import com.intellij.codeInsight.TargetElementUtil;

/**
 * @author yole
 */
public class JavaTypeHierarchyProvider implements HierarchyProvider {
  public PsiElement getTarget(final DataContext dataContext) {
    final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
    if (project == null) return null;

    final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
    if (editor != null) {
      final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (file == null) return null;

      final PsiElement targetElement = TargetElementUtil
          .findTargetElement(editor, TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtil.LOOKUP_ITEM_ACCEPTED);
      if (targetElement instanceof PsiClass) {
        return targetElement;
      }

      final int offset = editor.getCaretModel().getOffset();
      PsiElement element = file.findElementAt(offset);
      while (element != null) {
        if (element instanceof PsiFile) {
          if (!(element instanceof PsiClassOwner)) return null;
          final PsiClass[] classes = ((PsiClassOwner)element).getClasses();
          return classes.length == 1 ? classes[0] : null;
        }
        if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) {
          return element;
        }
        element = element.getParent();
      }

      return null;
    }
    else {
      final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
      return element instanceof PsiClass ? (PsiClass)element : null;
    }
  }

  public HierarchyBrowser createHierarchyBrowser(final PsiElement target) {
    return new TypeHierarchyBrowser(target.getProject(), (PsiClass) target);
  }

  public void browserActivated(final HierarchyBrowser hierarchyBrowser) {
    final TypeHierarchyBrowser browser = (TypeHierarchyBrowser)hierarchyBrowser;
    final String typeName =
      browser.isInterface() ? TypeHierarchyBrowserBase.SUBTYPES_HIERARCHY_TYPE : TypeHierarchyBrowserBase.TYPE_HIERARCHY_TYPE;
    browser.changeView(typeName);
  }
}

@@ -20,10 +20,10 @@
 0-20
-09
+12
  Jet
@@ -636,16 +636,71 @@
 .type;%0A%0A
+import com.intellij.codeInsight.TargetElementUtilBase;%0A
 import c
@@ -734,22 +734,21 @@
 ierarchy
-Provid
+Brows
 er;%0Aimpo
@@ -778,37 +778,38 @@
 rarchy.Hierarchy
-Brows
+Provid
 er;%0Aimport com.i
@@ -860,35 +860,8 @@
 se;%0A
-import com.intellij.psi.*;%0A
 impo
@@ -951,24 +951,20 @@
 nSystem.
-Platform
+Lang
 DataKeys
@@ -998,36 +998,40 @@
 pi.actionSystem.
-Lang
+Platform
 DataKeys;%0Aimport
@@ -1056,23 +1056,21 @@
 api.
-project.Project
+editor.Editor
 ;%0Aim
@@ -1091,37 +1091,39 @@
 lij.openapi.
-editor.Editor
+project.Project
 ;%0Aimport com
@@ -1136,37 +1136,13 @@
 lij.
-codeInsight.TargetElementUtil
+psi.*
 ;%0A%0A/
@@ -1704,27 +1704,20 @@
 mentUtil
-%0A          
+Base
 .findTar
@@ -1752,16 +1752,20 @@
 mentUtil
+Base
 .ELEMENT
@@ -1772,32 +1772,119 @@
 _NAME_ACCEPTED %7C
+%0A                                                                                      
  TargetElementUt
@@ -1885,16 +1885,20 @@
 mentUtil
+Base
 .REFEREN
@@ -1919,16 +1919,103 @@
 CEPTED %7C
+%0A                                                                                      
  TargetE
@@ -2024,16 +2024,20 @@
 mentUtil
+Base
 .LOOKUP_
@@ -2618,16 +2618,59 @@
 usClass)
+ && !(element instanceof PsiSyntheticClass)
 ) %7B%0A    

make sure we don't try to show Java type hierarchy for JSPs