package com.redhat.ceylon.eclipse.code.hover;

import com.github.rjeschke.txtmark.SpanEmitter;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Module;
import com.redhat.ceylon.compiler.typechecker.model.Scope;
import com.redhat.ceylon.compiler.typechecker.model.Unit;
import com.redhat.ceylon.eclipse.code.html.HTML;

final class CeylonSpanEmitter implements SpanEmitter {
    private final Scope linkScope;
    private final Unit unit;

    CeylonSpanEmitter(Scope linkScope, Unit unit) {
        this.linkScope = linkScope;
        this.unit = unit;
    }

    @Override
    public void emitSpan(StringBuilder out, String content) {
        String linkName;
        String linkTarget; 
        
        int indexOf = content.indexOf("|");
        boolean hasNoPlainText = indexOf == -1;
        if (hasNoPlainText) {
            linkName = content;
            linkTarget = content;
        }
        else {
            linkName = content.substring(0, indexOf);
            linkTarget = content.substring(indexOf+1, content.length()); 
        }
        
        String href = resolveLink(linkTarget, linkScope, unit);
        if (href != null) {
            out.append("<a ").append(href).append(">");
        }
        if (hasNoPlainText) {
        	out.append("<code>");
        }
        int sep = linkName.indexOf("::");
        out.append(sep<0?linkName:linkName.substring(sep+2));
        if (hasNoPlainText) {
        	out.append("</code>");
        }
        if (href != null) {
            out.append("</a>");
        }
    }

    static String resolveLink(String linkTarget, Scope linkScope, Unit unit) {
        String declName;
        Scope scope = null;
        int pkgSeparatorIndex = linkTarget.indexOf("::");
        if (pkgSeparatorIndex == -1) {
            declName = linkTarget;
            scope = linkScope;
        } 
        else {
            String pkgName = linkTarget.substring(0, pkgSeparatorIndex);
            declName = linkTarget.substring(pkgSeparatorIndex+2, linkTarget.length());
            Module module = DocumentationHover.resolveModule(linkScope);
            if (module != null) {
                scope = module.getPackage(pkgName);
            }
        }
        
        if (scope==null || declName == null || "".equals(declName)) {
            return null; // no point in continuing. Required for non-token auto-complete.
        }
        
        String[] declNames = declName.split("\\.");
        Declaration decl = scope.getMemberOrParameter(unit, declNames[0], null, false);
        for (int i=1; i<declNames.length; i++) {
            if (decl instanceof Scope) {
                scope = (Scope) decl;
                decl = scope.getMember(declNames[i], null, false);
            }
            else {
                decl = null;
                break;
            }
        }
    
        if (decl != null) {
            String href = HTML.link(decl);
            return href;
        }
        else {
            return null;
        }
    }
}
@@ -153,16 +153,76 @@
 ration;%0A
+import com.redhat.ceylon.compiler.typechecker.model.Method;%0A
 import c
@@ -776,20 +776,27 @@
 ing link
-Name
+Description
 ;%0A      
@@ -960,34 +960,121 @@
         
-linkName = content
+int sep = content.indexOf(%22::%22);%0A            linkDescription = sep%3C0 ? content : content.substring(sep+2)
 ;%0A      
@@ -1142,20 +1142,27 @@
     link
-Name
+Description
  = conte
@@ -1288,27 +1288,32 @@
         
-String href
+Declaration decl
  = resol
@@ -1349,16 +1349,77 @@
  unit);%0A
+        String href = decl != null ? HTML.link(decl) : null;%0A
         
@@ -1534,33 +1534,36 @@
 Text) %7B%0A        
-%09
+    
 out.append(%22%3Ccod
@@ -1590,143 +1590,169 @@
     
-int sep = linkName.indexOf(%22::%22);%0A        out.append(sep%3C0?linkName:linkName.substring(sep+2));%0A        if (hasNoPlainText) %7B%0A        %09
+out.append(linkDescription);%0A        if (hasNoPlainText) %7B%0A            if (decl instanceof Method) %7B%0A                out.append(%22()%22);%0A            %7D%0A            
 out.
@@ -1868,22 +1868,27 @@
  static 
-String
+Declaration
  resolve
@@ -3175,155 +3175,20 @@
     
-if (decl != null) %7B%0A            String href = HTML.link(decl);%0A            return href;%0A        %7D%0A        else %7B%0A            return null;%0A        %7D
+return decl;
 %0A   

make functions look like functions