package bndtools.editor.completion;

import java.util.Properties;

import org.bndtools.api.editor.IBndEditor;
import org.bndtools.core.editors.BndMarkerAnnotationHover;
import org.bndtools.core.editors.BndMarkerQuickAssistProcessor;
import org.eclipse.jdt.ui.text.IColorManager;
import org.eclipse.jdt.ui.text.IJavaColorConstants;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;

public class BndSourceViewerConfiguration extends SourceViewerConfiguration {

	Token					T_DEFAULT;
	Token					T_MACRO;
	Token					T_ERROR;
	Token					T_COMMENT;
	Token					T_INSTRUCTION;
	Token					T_OPTION;
	Token					T_DIRECTIVE;

	static final String		SINGLELINE_COMMENT_TYPE	= "___slc";
	static Properties		syntax					= null;

	BndScanner				scanner;
	MultiLineCommentScanner	multiLineCommentScanner;
	private IBndEditor		bndEditor;

	public BndSourceViewerConfiguration(IBndEditor bndEditor, IColorManager colorManager) {
		this.bndEditor = bndEditor;
		T_DEFAULT = new Token(new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVA_DEFAULT)));
		T_MACRO = new Token(new TextAttribute(colorManager.getColor(IJavaColorConstants.TASK_TAG), null, SWT.BOLD));
		T_ERROR = new Token(new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVA_KEYWORD), null, SWT.BOLD));
		T_COMMENT = new Token(new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT)));
		T_INSTRUCTION = new Token(
			new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVADOC_KEYWORD), null, SWT.BOLD));
		T_OPTION = new Token(
			new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVADOC_LINK), null, SWT.BOLD));
		T_DIRECTIVE = new Token(
			new TextAttribute(colorManager.getColor(IJavaColorConstants.JAVADOC_KEYWORD), null, SWT.BOLD));
	}

	@Override
	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
		PresentationReconciler reconciler = new PresentationReconciler();
		configureReconciler(reconciler, IDocument.DEFAULT_CONTENT_TYPE, getBndScanner());
		configureReconciler(reconciler, SINGLELINE_COMMENT_TYPE, getMultiLineCommentScanner());
		return reconciler;
	}

	private static void configureReconciler(PresentationReconciler reconciler, String partitionType,
		ITokenScanner scanner) {
		DefaultDamagerRepairer dr;
		dr = new DefaultDamagerRepairer(scanner);
		reconciler.setDamager(dr, partitionType);
		reconciler.setRepairer(dr, partitionType);
	}

	protected BndScanner getBndScanner() {
		if (scanner == null) {
			scanner = new BndScanner(this);
		}
		return scanner;
	}

	class MultiLineCommentScanner extends RuleBasedScanner {

		public MultiLineCommentScanner() {
			setDefaultReturnToken(T_COMMENT);
		}

	}

	protected MultiLineCommentScanner getMultiLineCommentScanner() {
		if (multiLineCommentScanner == null) {
			multiLineCommentScanner = new MultiLineCommentScanner();
		}
		return multiLineCommentScanner;
	}

	@Override
	public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) {
		if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) || SINGLELINE_COMMENT_TYPE.equals(contentType)) {
			return new String[] {
				"#", "//"
			};
		}
		return null;
	}

	@Override
	public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
		return new BndHover(bndEditor, sourceViewer);
	}

	@Override
	public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
		return new BndMarkerAnnotationHover();
	}

	@Override
	public IContentAssistant getContentAssistant(ISourceViewer viewer) {
		ContentAssistant assistant = new ContentAssistant();
		assistant.setContentAssistProcessor(new BndCompletionProcessor(), IDocument.DEFAULT_CONTENT_TYPE);
		assistant.setContentAssistProcessor(new BndCompletionProcessor(), SINGLELINE_COMMENT_TYPE);
		assistant.enableAutoActivation(true);
		return assistant;
	}

	@Override
	public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
		QuickAssistAssistant assistant = new QuickAssistAssistant();

		assistant.setQuickAssistProcessor(new BndMarkerQuickAssistProcessor());

		return assistant;
	}

}
