package org.eclipse.dltk.ui.text.folding;

import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IModelElementVisitor;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ISourceReference;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.SourceType;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;

public class DefaultElementCommentResolver implements IElementCommentResolver {

	private final ISourceModule fModule;
	private final String fContent;
	private Document fDocument = null;

	public DefaultElementCommentResolver(ISourceModule module) {
		this(module, null);
	}

	/**
	 * @param modelElement
	 * @param contents
	 */
	public DefaultElementCommentResolver(ISourceModule module, String contents) {
		this.fModule = module;
		this.fContent = contents;
	}

	/**
	 * Determines the element that contains the clicked comment
	 *
	 * @throws ModelException
	 */
	protected IModelElement getContainingElement(IModelElement el, int offset,
			int length) throws ModelException {
		final PositionVisitor visitor = new PositionVisitor(offset, length);
		el.accept(visitor);
		return visitor.result;
	}

	/**
	 * Returns the model element that the comment corresponds to
	 */
	@Override
	public IModelElement getElementByCommentPosition(int offset, int length) {
		try {
			return getElementByCommentPositionImpl(offset, length);
		} catch (BadLocationException e1) {
			return null;
		} catch (ModelException e) {
			return null;
		}
	}

	protected IModelElement getElementByCommentPositionImpl(int offset,
			int length) throws BadLocationException, ModelException {

		if (fDocument == null) {
			fDocument = new Document(getSource());
		}

		// Determine that the desired position is inside a comment
		if (!checkIfPositionIsComment(fDocument, offset))
			return null;

		// Determine the innermost element that contains the clicked comment
		// (for example, class declaration)
		IModelElement el = getContainingElement(fModule, offset, length);

		// If the comment is inside a method, we do not need to process further
		if (el != null && el.getElementType() == IModelElement.METHOD)
			return el;

		// Determine the position after which the search will be stopped - for
		// example, EOF or end of the class declaration
		int sourceRangeEnd = getSourceRangeEnd(fDocument, el);

		// Search for first non-comment element after the clicked comment
		IModelElement res = searchForNonCommentElement(fDocument, fModule,
				offset + length, sourceRangeEnd);
		if (res == null)
			return el;
		return res;
	}

	/**
	 * @return
	 * @throws ModelException
	 */
	protected String getSource() throws ModelException {
		return fContent != null ? fContent : fModule.getSource();
	}

	protected int getSourceRangeEnd(Document d, IModelElement el)
			throws ModelException {

		int sourceRangeEnd = d.getLength();

		// If the comment is inside a class, we need to stop searching the
		// element once we leave the class boundaries
		if (el != null && el.getElementType() == IModelElement.TYPE) {
			SourceType t = (SourceType) el;
			sourceRangeEnd = t.getSourceRange().getOffset()
					+ t.getSourceRange().getLength();

		}
		return sourceRangeEnd;
	}

	protected boolean checkIfPositionIsComment(Document d, int offset)
			throws BadLocationException {
		int line = d.getLineOfOffset(offset);
		int q = d.getLineOffset(line);

		while (q < d.getLength() && Character.isWhitespace(d.getChar(q))
				&& q <= offset) {
			q++;
		}

		if (d.getChar(q) != '#') {
			/* First non-space char is not a comment start, so stop processing */
			return false;
		}

		return true;
	}

	protected IModelElement searchForNonCommentElement(Document d,
			ISourceModule content, int endOfCommentOffset, int lowerbound)
			throws BadLocationException, ModelException {
		IModelElement res = null;
		int off = endOfCommentOffset;
		int line = d.getLineOfOffset(off);
		off = d.getLineOffset(line);
		while (off < lowerbound) {

			while (off < lowerbound - 1
					&& Character.isWhitespace(d.getChar(off))) {
				off++;
			}

			if (d.getChar(off) != '#') {
				// It's neither a comment nor whitespace, so we can get the
				// model element at this position
				res = content.getElementAt(off);
				break;
			}
			line++;
			off = d.getLineOffset(line);

		}

		return res;
	}

	/**
	 * Visitor to search the AST for elements that contain the clicked comment
	 */
	private static class PositionVisitor implements IModelElementVisitor {

		IModelElement result = null;
		private final int offset;
		private final int length;

		public PositionVisitor(int offset, int length) {
			this.offset = offset;
			this.length = length;
		}

		@Override
		public boolean visit(IModelElement element) {
			if (element instanceof ISourceReference) {
				final ISourceRange range;
				try {
					range = ((ISourceReference) element).getSourceRange();
				} catch (ModelException e) {
					return true;
				}
				// The comment is entirely inside the element
				if (offset >= range.getOffset()
						&& offset + length <= range.getOffset()
								+ range.getLength()) {
					if (element.getElementType() == IModelElement.METHOD
							|| element.getElementType() == IModelElement.TYPE)
						result = element;
				}
			}

			return true;
		}

	}

}
