/*
 * 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.structureView.impl.java;

import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.SortableTreeElement;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.util.PsiFormatUtil;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collection;

public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> implements SortableTreeElement {
  public PsiMethodTreeElement(PsiMethod method, boolean isInherited) {
    super(isInherited,method);
  }

  @NotNull
  public Collection<StructureViewTreeElement> getChildrenBase() {
    final ArrayList<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>();
    final PsiMethod element = getElement();
    if (element == null || element instanceof JspHolderMethod) return result;

    final TextRange range = element.getTextRange();
    if (range == null) return result;

    final PsiFile psiFile = element.getContainingFile();
    if (psiFile == null || psiFile instanceof PsiCompiledElement) return result;

    final String fileText = psiFile.getText();
    if (fileText == null) return result;
    
    if (!range.substring(fileText).contains(PsiKeyword.CLASS)) return result;

    element.accept(new JavaRecursiveElementWalkingVisitor(){
      @Override public void visitClass(PsiClass aClass) {
        if (!(aClass instanceof PsiAnonymousClass) && !(aClass instanceof PsiTypeParameter)) {
          result.add(new JavaClassTreeElement(aClass, isInherited()));
        }

      }
    });
    return result;
  }

  public String getPresentableText() {
    return PsiFormatUtil.formatMethod(
      getElement(),
      PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS,
      PsiFormatUtil.SHOW_TYPE
    );
  }


  @Override
  public TextAttributesKey getTextAttributesKey() {
    if (isInherited()) return CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES;
    return super.getTextAttributesKey();
  }

  public PsiMethod getMethod() {
    return getElement();
  }

  public String getAlphaSortKey() {
    final PsiMethod method = getElement();
    if (method != null) {
      return method.getName();
    }
    return "";
  }
}

@@ -944,16 +944,66 @@
 tRange;%0A
+import com.intellij.openapi.util.text.StringUtil;%0A
 import c
@@ -1126,24 +1126,107 @@
 FormatUtil;%0A
+import com.intellij.psi.util.PsiFormatUtilBase;%0Aimport com.intellij.util.Function;%0A
 import org.j
@@ -2703,24 +2703,28 @@
 siFormatUtil
+Base
 .SHOW_NAME %7C
@@ -2723,16 +2723,44 @@
 W_NAME %7C
+%0A                           
  PsiForm
@@ -2757,32 +2757,36 @@
    PsiFormatUtil
+Base
 .SHOW_TYPE %7C Psi
@@ -2795,16 +2795,20 @@
 rmatUtil
+Base
 .TYPE_AF
@@ -2822,24 +2822,28 @@
 siFormatUtil
+Base
 .SHOW_PARAME
@@ -2867,16 +2867,20 @@
 rmatUtil
+Base
 .SHOW_TY
@@ -3246,24 +3246,24 @@
  != null) %7B%0A
-
       return
@@ -3279,16 +3279,356 @@
 etName()
+ + %22 %22 + StringUtil.join(method.getParameterList().getParameters(), new Function%3CPsiParameter, String%3E() %7B%0A        @Override%0A        public String fun(PsiParameter psiParameter) %7B%0A          PsiTypeElement typeElement = psiParameter.getTypeElement();%0A          return typeElement != null ? typeElement.getText() : %22%22;%0A        %7D%0A      %7D, %22 %22)
 ;%0A    %7D%0A

include parameter type names in sort key for comparing methods in Java structure view (IDEA-72755)