package com.intellij.lang.html;

import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.xml.XmlTagTreeElement;
import com.intellij.ide.structureView.xml.XmlStructureViewElementProvider;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.List;

public class HtmlStructureViewElementProvider implements XmlStructureViewElementProvider {

  private static int MAX_TEXT_LENGTH = 50;

  @Nullable
  public StructureViewTreeElement createCustomXmlTagTreeElement(@NotNull final XmlTag tag) {
    if (tag.getContainingFile().getViewProvider().getVirtualFile().getFileType() != HtmlFileType.INSTANCE) return null;

    return new HtmlTagTreeElement(tag);
  }

  static class HtmlTagTreeElement extends XmlTagTreeElement {
    public HtmlTagTreeElement(final XmlTag tag) {
      super(tag);
    }

    public String getPresentableText() {
      final XmlTag tag = getElement();
      if (tag == null) return IdeBundle.message("node.structureview.invalid");

      final String id = toCanonicalForm(tag.getAttributeValue("id"));

      final String classValue = tag.getAttributeValue("class");
      final List<String> classValues = classValue != null ? StringUtil.split(classValue, " ") : Collections.<String>emptyList();

      final StringBuilder text = new StringBuilder(tag.getLocalName());

      if (id != null) {
        text.append("#").append(id);
      }

      if (!classValues.isEmpty()) {
        text.append('.').append(StringUtil.join(classValues, "."));
      }

      return text.toString();
    }

    public String getLocationString() {
      final XmlTag tag = getElement();
      if (tag == null) return null;

      final String text = tag.getValue().getTrimmedText();
      return text.isEmpty() ? null : shortenTextIfLong(text);
    }

    private static String shortenTextIfLong(final String text) {
      if (text.length() < MAX_TEXT_LENGTH) return text;

      int index;
      for (index = MAX_TEXT_LENGTH; index > MAX_TEXT_LENGTH - 20; index--) {
        if (!Character.isLetter(text.charAt(index))) {
          break;
        }
      }

      final int endIndex = Character.isLetter(index) ? MAX_TEXT_LENGTH : index;
      return text.substring(0, endIndex) + "...";
    }
  }
}

@@ -316,16 +316,69 @@
 ovider;%0A
+import com.intellij.navigation.LocationPresentation;%0A
 import c
@@ -1062,16 +1062,48 @@
 Element 
+implements LocationPresentation 
 %7B%0A    pu
@@ -2031,16 +2031,32 @@
  text = 
+normalizeSpaces(
 tag.getV
@@ -2078,16 +2078,17 @@
 edText()
+)
 ;%0A      
@@ -2146,24 +2146,459 @@
 xt);%0A    %7D%0A%0A
+    private static String normalizeSpaces(final String text) %7B%0A      final StringBuilder buf = new StringBuilder();%0A%0A      for (char ch : text.toCharArray()) %7B%0A        if (ch %3C= ' ' %7C%7C Character.isSpaceChar(ch)) %7B%0A          if (buf.length() == 0 %7C%7C buf.charAt(buf.length() - 1) != ' ') %7B%0A            buf.append(' ');%0A          %7D%0A        %7D%0A        else %7B%0A          buf.append(ch);%0A        %7D%0A      %7D%0A%0A      return buf.toString();%0A    %7D%0A%0A
     private 
@@ -3027,15 +3027,145 @@
 %22;%0A    %7D
+%0A%0A    public String getLocationPrefix() %7B%0A      return %22  %22;%0A    %7D%0A%0A    public String getLocationSuffix() %7B%0A      return %22%22;%0A    %7D
 %0A  %7D%0A%7D%0A

normalize spaces and do not surround with ()