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

import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_END;
import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_MID;
import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_START;

import java.util.Collection;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;

import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.model.typechecker.model.Type;

class ConvertToConcatenationProposal extends CorrectionProposal {

    private ConvertToConcatenationProposal(String name, Change change) {
        super(name, change, null);
    }

    static void addConvertToConcatenationProposal(Collection<ICompletionProposal> proposals,
            IFile file, Tree.CompilationUnit cu, final Node node, IDocument doc) {
        class TemplateVisitor extends Visitor {
            Tree.StringTemplate result;
            @Override
            public void visit(Tree.StringTemplate that) {
                if (that.getStartIndex()<=node.getStartIndex() &&
                    that.getEndIndex()>=node.getEndIndex()) {
                    result = that;
                }
                super.visit(that);
            }
        }
        TemplateVisitor tv = new TemplateVisitor();
        tv.visit(cu);
        Tree.StringTemplate template = tv.result;
        if (template!=null) {
            TextFileChange change = new TextFileChange("Convert to Concatenation", file);
            change.setEdit(new MultiTextEdit());
            Type st = node.getUnit().getStringType();
            List<Tree.StringLiteral> literals = template.getStringLiterals();
            List<Tree.Expression> expressions = template.getExpressions();
            for (int i=0; i<literals.size(); i++) {
                Tree.StringLiteral s = literals.get(i);
                int stt = s.getToken().getType();
                if (stt==STRING_END||stt==STRING_MID) {
                    change.addEdit(new ReplaceEdit(s.getStartIndex(), 2, " + \""));
                }
                if (stt==STRING_START||stt==STRING_MID) {
                    change.addEdit(new ReplaceEdit(s.getEndIndex()-2, 2, "\" + "));
                }
                if (i<expressions.size()) {
                    Tree.Expression e = expressions.get(i);
                    if (e.getTerm() 
                            instanceof Tree.OperatorExpression) {
                        change.addEdit(new InsertEdit(e.getStartIndex(), "("));
                        change.addEdit(new InsertEdit(e.getEndIndex(), ")"));
                    }
                    if (!e.getTypeModel().isSubtypeOf(st)) {
                        change.addEdit(new InsertEdit(e.getEndIndex(), ".string"));
                    }
                }
            }
            proposals.add(new ConvertToConcatenationProposal("Convert to string concatenation", change));
        }
    }
    
    
}
@@ -593,32 +593,74 @@
 TextFileChange;%0A
+import org.eclipse.text.edits.DeleteEdit;%0A
 import org.eclip
@@ -2370,32 +2370,439 @@
 iterals.get(i);%0A
+                if (s.getText().isEmpty()) %7B%0A                    if (i%3E0 && i%3Cliterals.size()-1) %7B%0A                        change.addEdit(new ReplaceEdit(s.getStartIndex(), s.getDistance(), %22 + %22));%0A                    %7D%0A                    else %7B%0A                        change.addEdit(new DeleteEdit(s.getStartIndex(), s.getDistance()));%0A                    %7D%0A                %7D%0A                else %7B%0A    
                 
@@ -2843,32 +2843,36 @@
                 
+    
 if (stt==STRING_
@@ -2887,32 +2887,36 @@
 ==STRING_MID) %7B%0A
+    
                 
@@ -2991,34 +2991,40 @@
                 
-%7D%0A
+    %7D%0A  
                 
@@ -3015,32 +3015,34 @@
                 
+  
 if (stt==STRING_
@@ -3059,32 +3059,36 @@
 ==STRING_MID) %7B%0A
+    
                 
@@ -3147,32 +3147,54 @@
 , 2, %22%5C%22 + %22));%0A
+                    %7D%0A
                 

eliminate empty strings when converting to concatenation