package org.antlr.intellij.plugin.preview;

import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import org.antlr.intellij.plugin.Icons;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;

public class PreviewFileRoot extends PsiFileBase {
    public PreviewFileRoot(@NotNull FileViewProvider viewProvider) {
        super(viewProvider, PreviewLanguage.INSTANCE);
    }

    @NotNull
    @Override
    public FileType getFileType() {
        return PreviewFileType.INSTANCE;
    }

    @Override
    public String toString() {
        return "Sample input file";
    }

    @Override
    public Icon getIcon(int flags) {
		return Icons.FILE;
    }

	@NotNull
	@Override
	public PsiElement[] getChildren() {
		return super.getChildren();
	}

//	@Override
//	public PsiElement findElementAt(int offset) {
//		System.out.println("looking for element at " + offset);
//		PsiElement p = dfs(this, offset);
//		if ( p!=null ) {
//			System.out.println("found at "+p+"="+p.getText());
//		}
//		return p;
//	}

//	private PsiElement MyFindElementAt(int offset) {
//		int offsetInElement = offset;
//		PsiElement child = getFirstChild();
//		while (child != null) {
//			final int length = child.getTextLength();
//			if (length <= offsetInElement) {
//				offsetInElement -= length;
//				child = child.getNextSibling();
//				continue;
//			}
//			return child.findElementAt(offsetInElement);
//		}
//		return null;
//	}

	public PsiElement dfs(PsiElement p, int offset) {
		if ( p==null ) return null;
		System.out.println(Thread.currentThread().getName()+": visit root "+p+
							   ", offset="+offset+
							   ", class="+p.getClass().getSimpleName()+
							   ", text="+p.getNode().getText()+
							   ", node range="+p.getTextRange());
		if ( p.getTextRange().contains(offset) && p instanceof PreviewTokenNode ) {
			return p;
		}
		PsiElement c = p.getFirstChild();
		while ( c!=null ) {
//			System.out.println("visit child "+c+", text="+c.getNode().getText());
			PsiElement result = dfs(c, offset);
			if ( result!=null ) {
				return result;
			}
			c = c.getNextSibling();
		}
		return null;
	}

//	@Override
//	public PsiReference findReferenceAt(int offset) {
////		return super.findReferenceAt(offset);
//		System.out.println("looking for reference at "+offset);
//		PsiElement node = findElementAt(offset);
//		if ( node==null ) {
//			return null;
//		}
//		return node.getReference();
//	}
}

@@ -867,1672 +867,7 @@
 ;%0A%09%7D
-%0A%0A//%09@Override%0A//%09public PsiElement findElementAt(int offset) %7B%0A//%09%09System.out.println(%22looking for element at %22 + offset);%0A//%09%09PsiElement p = dfs(this, offset);%0A//%09%09if ( p!=null ) %7B%0A//%09%09%09System.out.println(%22found at %22+p+%22=%22+p.getText());%0A//%09%09%7D%0A//%09%09return p;%0A//%09%7D%0A%0A//%09private PsiElement MyFindElementAt(int offset) %7B%0A//%09%09int offsetInElement = offset;%0A//%09%09PsiElement child = getFirstChild();%0A//%09%09while (child != null) %7B%0A//%09%09%09final int length = child.getTextLength();%0A//%09%09%09if (length %3C= offsetInElement) %7B%0A//%09%09%09%09offsetInElement -= length;%0A//%09%09%09%09child = child.getNextSibling();%0A//%09%09%09%09continue;%0A//%09%09%09%7D%0A//%09%09%09return child.findElementAt(offsetInElement);%0A//%09%09%7D%0A//%09%09return null;%0A//%09%7D%0A%0A%09public PsiElement dfs(PsiElement p, int offset) %7B%0A%09%09if ( p==null ) return null;%0A%09%09System.out.println(Thread.currentThread().getName()+%22: visit root %22+p+%0A%09%09%09%09%09%09%09   %22, offset=%22+offset+%0A%09%09%09%09%09%09%09   %22, class=%22+p.getClass().getSimpleName()+%0A%09%09%09%09%09%09%09   %22, text=%22+p.getNode().getText()+%0A%09%09%09%09%09%09%09   %22, node range=%22+p.getTextRange());%0A%09%09if ( p.getTextRange().contains(offset) && p instanceof PreviewTokenNode ) %7B%0A%09%09%09return p;%0A%09%09%7D%0A%09%09PsiElement c = p.getFirstChild();%0A%09%09while ( c!=null ) %7B%0A//%09%09%09System.out.println(%22visit child %22+c+%22, text=%22+c.getNode().getText());%0A%09%09%09PsiElement result = dfs(c, offset);%0A%09%09%09if ( result!=null ) %7B%0A%09%09%09%09return result;%0A%09%09%09%7D%0A%09%09%09c = c.getNextSibling();%0A%09%09%7D%0A%09%09return null;%0A%09%7D%0A%0A//%09@Override%0A//%09public PsiReference findReferenceAt(int offset) %7B%0A////%09%09return super.findReferenceAt(offset);%0A//%09%09System.out.println(%22looking for reference at %22+offset);%0A//%09%09PsiElement node = findElementAt(offset);%0A//%09%09if ( node==null ) %7B%0A//%09%09%09return null;%0A//%09%09%7D%0A//%09%09return node.getReference();%0A//%09%7D
 %0A%7D%0A

Revert "actually, need my tweak to reference object too."