package com.intellij.lang.ant.psi.impl.reference.providers;

import com.intellij.lang.ant.misc.PsiReferenceListSpinAllocator;
import com.intellij.lang.ant.psi.AntStructuredElement;
import com.intellij.lang.ant.psi.impl.reference.AntAttributeReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.source.resolve.reference.ReferenceType;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.GenericReferenceProvider;
import com.intellij.psi.xml.XmlToken;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class AntAttributeReferenceProvider extends GenericReferenceProvider {

  @SuppressWarnings({"HardCodedStringLiteral"})
  @NotNull
  public PsiReference[] getReferencesByElement(PsiElement element) {
    if (!(element instanceof AntStructuredElement)) {
      return PsiReference.EMPTY_ARRAY;
    }
    final AntStructuredElement se = (AntStructuredElement)element;
    final int elementStartOffset = se.getTextRange().getStartOffset();
    final List<PsiReference> list = PsiReferenceListSpinAllocator.alloc();
    try {
      for (PsiElement child : se.getSourceElement().getChildren()) {
        if (child instanceof PsiWhiteSpace) {
          int offsetInElement = child.getTextRange().getStartOffset() - elementStartOffset;
          list.add(new AntAttributeReference(this, se, child.getText(), new TextRange(offsetInElement, offsetInElement + 1), null));
          continue;
        }
        if (child instanceof XmlToken) {
          XmlToken token = (XmlToken)child;
          // TODO: move XmlTokenType to openAPI
          if (token.getTokenType().toString().equals("XML_TAG_END")) {
            break;
          }
        }
      }
      final int count = list.size();
      return (count == 0) ? PsiReference.EMPTY_ARRAY : list.toArray(new PsiReference[count]);
    }
    finally {
      PsiReferenceListSpinAllocator.dispose(list);
    }
  }

  @NotNull
  public PsiReference[] getReferencesByElement(PsiElement element, ReferenceType type) {
    return getReferencesByElement(element);
  }

  @NotNull
  public PsiReference[] getReferencesByString(String str, PsiElement position, ReferenceType type, int offsetInPosition) {
    return getReferencesByElement(position);
  }
}

@@ -367,47 +367,8 @@
 ce;%0A
-import com.intellij.psi.PsiWhiteSpace;%0A
 impo
@@ -1263,27 +1263,224 @@
 eof 
-PsiWhiteSpace) %7B%0A  
+XmlToken) %7B%0A          XmlToken token = (XmlToken)child;%0A          // TODO: move XmlTokenType to openAPI%0A          if (token.getTokenType().toString().equals(%22XML_TAG_END%22)) %7B%0A            break;%0A          %7D%0A        %7D%0A
     
@@ -1563,24 +1563,67 @@
 rtOffset;%0A  
+      final String text = child.getText();%0A
         list
@@ -1663,31 +1663,20 @@
 is, se, 
-child.getT
+t
 ext
-()
 , new Te
@@ -1722,294 +1722,31 @@
 t + 
-1), null));%0A          continue;%0A        %7D%0A        if (child instanceof XmlToken) %7B%0A          XmlToken token = (XmlToken)child;%0A          // TODO: move XmlTokenType to openAPI%0A          if (token.getTokenType().toString().equals(%22XML_TAG_END%22)) %7B%0A            break;%0A          %7D%0A        %7D
+text.length()), null));
 %0A   

define antAttributeReferences not only over PsiWhiteSpace, but over any alement in start tag (that allows completion of attributes with prefix)