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

import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.CORRECTION;
import static com.redhat.ceylon.eclipse.code.parse.CeylonSourcePositionLocator.getIdentifyingNode;

import java.util.Collection;

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.TextChange;
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.eclipse.code.editor.Util;
import com.redhat.ceylon.eclipse.util.FindReferenceVisitor;
import com.redhat.ceylon.eclipse.util.FindStatementVisitor;

class ShadowReferenceProposal extends ChangeCorrectionProposal {
    
    final IFile file;
    final int offset;
    final int length;
    
    ShadowReferenceProposal(int offset, int length, IFile file, 
            TextChange change) {
        super("Shadow reference inside control structure", change);
        this.file=file;
        this.offset=offset;
        this.length=length;
    }
    
    @Override
    public void apply(IDocument document) {
        super.apply(document);
        Util.gotoLocation(file, offset, length);
    }
    
    static void addShadowReferenceProposal(IFile file, Tree.CompilationUnit cu, 
            Collection<ICompletionProposal> proposals, Node node) {
        if (node instanceof Tree.Variable) { //TODO: handle expressions!
            Tree.Variable var = (Tree.Variable) node;
            int offset = var.getIdentifier().getStartIndex();
            TextChange change = new TextFileChange("Shadow Reference", file);
//            TextChange change = new DocumentChange("Shadow Reference", doc);
            change.setEdit(new MultiTextEdit());
            String name = Character.toString(var.getIdentifier().getText().charAt(0));
            change.addEdit(new InsertEdit(offset, name + " = "));
            FindStatementVisitor fsv = new FindStatementVisitor(var/*.getSpecifierExpression().getExpression().getTerm()*/, false);
            fsv.visit(cu);
            FindReferenceVisitor frv = new FindReferenceVisitor(var.getDeclarationModel());
            frv.visit(fsv.getStatement());
            for (Node n: frv.getNodes()) {
                Node identifyingNode = getIdentifyingNode(n);
                Integer start = identifyingNode.getStartIndex();
                if (start!=offset) {
                    change.addEdit(new ReplaceEdit(start, 
                            identifyingNode.getText().length(), name));
                }
            }
            proposals.add(new ShadowReferenceProposal(offset, 1, file, change));
        }
    }
}
@@ -47,93 +47,8 @@
 x;%0A%0A
-import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.CORRECTION;%0A
 impo
@@ -724,16 +724,84 @@
 r.Util;%0A
+import com.redhat.ceylon.eclipse.code.refactor.AbstractRefactoring;%0A
 import c
@@ -1657,36 +1657,8 @@
 e) %7B
- //TODO: handle expressions!
 %0A   
@@ -1786,76 +1786,151 @@
     
-TextChange change = new TextFileChange(%22Shadow Reference%22, file);%0A//
+String varName = var.getIdentifier().getText();%0A            String name = varName.length()%3E1 ? Character.toString(varName.charAt(0)) : %22temp%22;%0A
     
@@ -1961,24 +1961,24 @@
 e = new 
-Document
+TextFile
 Change(%22
@@ -1996,19 +1996,20 @@
 rence%22, 
-doc
+file
 );%0A     
@@ -2056,95 +2056,8 @@
 ));%0A
-            String name = Character.toString(var.getIdentifier().getText().charAt(0));%0A
     
@@ -2869,19 +2869,463 @@
 ;%0A        %7D%0A
+        else if (node instanceof Tree.Term) %7B%0A            String name = AbstractRefactoring.guessName(node);%0A            TextChange change = new TextFileChange(%22Shadow Reference%22, file);%0A            change.setEdit(new MultiTextEdit());%0A            Integer offset = node.getStartIndex();%0A            change.addEdit(new InsertEdit(offset, name + %22 = %22));%0A            proposals.add(new ShadowReferenceProposal(offset, 1, file, change));%0A        %7D%0A
     %7D%0A%7D

make shadow reference fix handle plain expressions