/*=============================================================================#
 # Copyright (c) 2007, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.r.ui.sourceediting;

import static org.eclipse.statet.ecommons.text.ui.BracketLevel.AUTODELETE;
import static org.eclipse.statet.r.core.source.IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT;
import static org.eclipse.statet.r.core.source.RHeuristicTokenScanner.CURLY_BRACKET_TYPE;
import static org.eclipse.statet.r.core.source.RHeuristicTokenScanner.ROUND_BRACKET_TYPE;
import static org.eclipse.statet.r.core.source.RHeuristicTokenScanner.SQUARE_BRACKET_TYPE;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedModeUI;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.texteditor.ITextEditorExtension3;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;
import org.eclipse.statet.jcommons.text.core.input.TextParserInput;

import org.eclipse.statet.ecommons.text.ITokenScanner;
import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartition;
import org.eclipse.statet.ecommons.text.ui.BracketLevel.InBracketPosition;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.ui.sourceediting.ISmartInsertSettings;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorAddon;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1;
import org.eclipse.statet.nico.ui.console.InputSourceViewer;
import org.eclipse.statet.r.core.IRCoreAccess;
import org.eclipse.statet.r.core.RCodeStyleSettings;
import org.eclipse.statet.r.core.rsource.RSourceIndenter;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.rsource.ast.RScanner;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.editors.REditorOptions;


/**
 * Auto edit strategy for R code:
 *  - auto indent on keys
 *  - special indent with tab key
 *  - auto indent on paste
 *  - auto close of pairs
 */
public class RAutoEditStrategy extends DefaultIndentLineAutoEditStrategy
		implements ISourceEditorAddon {
	
	private static final char[] CURLY_BRACKETS= new char[] { '{', '}' };
	
	private static final StringParserInput DEFAULT_PARSER_INPUT= new StringParserInput();
	
	
	private class RealTypeListener implements VerifyKeyListener {
		@Override
		public void verifyKey(final VerifyEvent event) {
			if (!event.doit) {
				return;
			}
			switch (event.character) {
			case '{':
			case '}':
			case '(':
			case ')':
			case '[':
			case '%':
			case '"':
			case '\'':
			case '`':
			case '#':
				event.doit= !customizeKeyPressed(event.character);
				return;
			case '\t':
				if (event.stateMask == 0) {
					event.doit= !customizeKeyPressed(event.character);
				}
				return;
			case 0x0A:
			case 0x0D:
				if (RAutoEditStrategy.this.editor3 != null) {
					event.doit= !customizeKeyPressed('\n');
				}
				return;
			default:
				return;
			}
		}
	}
	
	
	private final ISourceEditor editor;
	private final ITextEditorExtension3 editor3;
	private final DocContentSections documentContentInfo;
	private final SourceViewer viewer;
	private final RealTypeListener typeListener;
	
	private final IRCoreAccess rCoreAccess;
	private final REditorOptions editorOptions;
	
	private AbstractDocument document;
	private TextRegion validRange;
	private RHeuristicTokenScanner scanner;
	private RCodeStyleSettings rCodeStyle;
	private RSourceIndenter indenter;
	
	private boolean ignoreCommands= false;
	
	
	public RAutoEditStrategy(final IRCoreAccess rCoreAccess, final ISourceEditor editor) {
		assert (rCoreAccess != null);
		assert (editor != null);
		
		this.editor= editor;
		this.documentContentInfo= editor.getDocumentContentInfo();
		
		this.rCoreAccess= rCoreAccess;
		this.editorOptions= RUIPlugin.getInstance().getREditorSettings(rCoreAccess.getPrefs());
		assert (this.editorOptions != null);
		
		this.viewer= this.editor.getViewer();
		this.editor3= (editor instanceof SourceEditor1) ? (SourceEditor1) editor : null;
		this.typeListener= new RealTypeListener();
	}
	
	@Override
	public void install(final ISourceEditor editor) {
		assert (editor.getViewer() == this.viewer);
		this.viewer.prependVerifyKeyListener(this.typeListener);
	}
	
	@Override
	public void uninstall() {
		this.viewer.removeVerifyKeyListener(this.typeListener);
	}
	
	
	private final ITypedRegion initCustomization(final int offset, final int c)
			throws BadLocationException, BadPartitioningException {
		assert(this.document != null);
		if (this.scanner == null) {
			this.scanner= createScanner();
		}
		this.rCodeStyle= this.rCoreAccess.getRCodeStyle();
		
		final ITypedRegion partition= this.document.getPartition(
				this.scanner.getDocumentPartitioning(), offset, true );
		// InputDocument of console does not (yet) return a TreePartition
		this.validRange= (partition instanceof TreePartition) ?
				getValidRange(offset, (TreePartition) partition, c) :
				new BasicTextRegion(0, this.document.getLength());
		return (this.validRange != null) ? partition : null;
	}
	
	protected RHeuristicTokenScanner createScanner() {
		return RHeuristicTokenScanner.create(this.documentContentInfo);
	}
	
	protected TextRegion getValidRange(final int offset, final TreePartition partition, final int c) {
		return new BasicTextRegion(0, this.document.getLength());
	}
	
	protected final IDocument getDocument() {
		return this.document;
	}
	
	protected final DocContentSections getDocumentContentInfo() {
		return this.documentContentInfo;
	}
	
	private final void quitCustomization() {
		this.document= null;
		this.rCodeStyle= null;
	}
	
	
	private final boolean isSmartInsertEnabled() {
		return ((this.editor3 != null) ?
				(this.editor3.getInsertMode() == ITextEditorExtension3.SMART_INSERT) :
				this.editorOptions.isSmartInsertEnabledByDefault() );
	}
	
	private final boolean isBlockSelection() {
		final StyledText textWidget= this.viewer.getTextWidget();
		return (textWidget.getBlockSelection() && textWidget.getSelectionRanges().length > 2);
	}
	
	private final boolean isClosedBracket(final int backwardOffset, final int forwardOffset, final int searchType) {
		int[] balance= new int[3];
		balance[searchType]++;
		this.scanner.configureDefaultPartitions(this.document);
		balance= this.scanner.computeBracketBalance(backwardOffset, forwardOffset, balance, searchType);
		return (balance[searchType] <= 0);
	}
	
	private final boolean isClosedString(int offset, final int end, final boolean endVirtual, final char sep) {
		this.scanner.configure(this.document);
		boolean in= true; // we start always inside after a sep
		final char[] chars= new char[] { sep, '\\' };
		while (offset < end) {
			offset= this.scanner.scanForward(offset, end, chars);
			if (offset == RHeuristicTokenScanner.NOT_FOUND) {
				offset= end;
				break;
			}
			offset++;
			if (this.scanner.getChar() == '\\') {
				offset++;
			}
			else {
				in= !in;
			}
		}
		return (offset == end) && (!in ^ endVirtual);
	}
	
	private boolean isCharAt(final int offset, final char c) throws BadLocationException {
		return (offset >= this.validRange.getStartOffset() && offset < this.validRange.getEndOffset()
				&& this.document.getChar(offset) == c);
	}
	
	private boolean isValueChar(final int offset) throws BadLocationException {
		if (offset >= this.validRange.getStartOffset() && offset < this.validRange.getEndOffset()) {
			final int c= this.document.getChar(offset);
			return (c == '"' || c == '\'' || c == '`' || Character.isLetterOrDigit(c));
		}
		return false;
	}
	
	private boolean isAfterRoxygen(final int offset) throws BadLocationException {
		this.scanner.configure(this.document);
		final int line= this.document.getLineOfOffset(offset);
		if (line > 0 && this.scanner.findAnyNonBlankBackward(offset, this.document.getLineOffset(line)-1, false) == ITokenScanner.NOT_FOUND) {
			final IRegion prevLineInfo= this.document.getLineInformation(line-1);
			if (prevLineInfo.getLength() > 0 && TextUtilities.getPartition(this.document,
					this.scanner.getDocumentPartitioning(),
					prevLineInfo.getOffset()+prevLineInfo.getLength()-1, false).getType() == IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE) {
				return true;
			}
		}
		return false;
	}
	
	
	@Override
	public void customizeDocumentCommand(final IDocument d, final DocumentCommand c) {
		if (this.ignoreCommands || c.doit == false || c.text == null) {
			return;
		}
		if (!isSmartInsertEnabled() || isBlockSelection()) {
			super.customizeDocumentCommand(d, c);
			return;
		}
		
		try {
			this.document= (AbstractDocument) d;
			final ITypedRegion partition= initCustomization(c.offset, -1);
			if (partition == null) {
				return;
			}
			final String contentType= partition.getType();
			
			if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
				if (c.length == 0 && TextUtilities.equals(d.getLegalLineDelimiters(), c.text) != -1) {
					smartIndentOnNewLine(c, contentType);
				}
				else if (c.text.length() > 1 && this.editorOptions.isSmartPasteEnabled()) {
					smartPaste(c);
				}
			}
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
					"An error occurred when customizing action for document command in R auto edit strategy.", e )); //$NON-NLS-1$
		}
		finally {
			quitCustomization();
		}
	}
	
	/**
	 * Second main entry method for real single key presses.
	 * 
	 * @return <code>true</code>, if key was processed by method
	 */
	private boolean customizeKeyPressed(final char c) {
		if (!isSmartInsertEnabled() || !UIAccess.isOkToUse(this.viewer) || isBlockSelection()) {
			return false;
		}
		
		try {
			this.document= (AbstractDocument) this.viewer.getDocument();
			ITextSelection selection= (ITextSelection) this.viewer.getSelection();
			final ITypedRegion partition= initCustomization(selection.getOffset(), c);
			if (partition == null) {
				return false;
			}
			final String contentType= partition.getType();
			this.ignoreCommands= true;
			
			final DocumentCommand command= new DocumentCommand() {};
			command.offset= selection.getOffset();
			command.length= selection.getLength();
			command.doit= true;
			command.shiftsCaret= true;
			command.caretOffset= -1;
			int linkedMode= -1;
			int linkedModeOffset= -1;
			boolean contextInfo= false;
			final int cEnd= command.offset + command.length;
			
			KEY: switch (c) {
			case '\t':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)
						|| contentType == IRDocumentConstants.R_COMMENT_CONTENT_TYPE
						|| contentType == IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE ) {
					if (command.length == 0 || this.document.getLineOfOffset(command.offset) == this.document.getLineOfOffset(cEnd)) {
						command.text= "\t"; //$NON-NLS-1$
						switch (smartIndentOnTab(command)) {
						case -1:
							return false;
						case 0:
							break;
						case 1:
							break KEY;
						}
						
						if (this.rCodeStyle.getReplaceOtherTabsWithSpaces()) {
							final IndentUtil indentation= new IndentUtil(this.document, this.rCodeStyle);
							command.text= indentation.createTabSpacesCompletionString(indentation.getColumn(command.offset));
							break KEY;
						}
					}
				}
				return false;
			case '}':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
					command.text= "}"; //$NON-NLS-1$
					smartIndentOnClosingBracket(command);
					break KEY;
				}
				return false;
			case '{':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
					command.text= "{"; //$NON-NLS-1$
					if (this.editorOptions.isSmartCurlyBracketsEnabled() && !isValueChar(cEnd)) {
						if (!isClosedBracket(command.offset, cEnd, CURLY_BRACKET_TYPE)) {
							command.text= "{}"; //$NON-NLS-1$
							linkedMode= 1 | AUTODELETE;
						}
						else if (isCharAt(cEnd, '}')) {
							linkedMode= 1;
						}
					}
					linkedModeOffset= smartIndentOnFirstLineCharDefault2(command);
					break KEY;
				}
				return false;
			case '(':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
					command.text= "("; //$NON-NLS-1$
					if (this.editorOptions.isSmartRoundBracketsEnabled() && !isValueChar(cEnd)) {
						if (!isClosedBracket(command.offset, cEnd, ROUND_BRACKET_TYPE)) {
							command.text= "()"; //$NON-NLS-1$
							linkedMode= 2 | AUTODELETE;
						}
						else if (isCharAt(cEnd, ')')) {
							linkedMode= 2;
						}
					}
					if (isValueChar(command.offset - 1)) {
						contextInfo= true;
					}
					break KEY;
				}
				return false;
			case ')':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
					command.text= ")"; //$NON-NLS-1$
					smartIndentOnFirstLineCharDefault2(command); // required?
					break KEY;
				}
				return false;
			case '[':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)) {
					command.text= "["; //$NON-NLS-1$
					if (this.editorOptions.isSmartSquareBracketsEnabled() && !isValueChar(cEnd)) {
						if (!isClosedBracket(command.offset, cEnd, SQUARE_BRACKET_TYPE)) {
							command.text= "[]"; //$NON-NLS-1$
							if (TextUtil.countBackward(this.document, command.offset, '[') % 2 == 1
									&& isCharAt(cEnd, ']') ) {
								linkedMode= 3 | AUTODELETE;
							}
							else {
								linkedMode= 2 | AUTODELETE;
							}
						}
						else if (isCharAt(cEnd, ']')) {
							linkedMode= 2;
						}
					}
					break KEY;
				}
				return false;
			case '%':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)
						&& this.editorOptions.isSmartSpecialPercentEnabled()) {
					final IRegion line= this.document.getLineInformationOfOffset(cEnd);
					this.scanner.configure(this.document, IRDocumentConstants.R_INFIX_OPERATOR_CONTENT_TYPE);
					if (this.scanner.count(cEnd, line.getOffset()+line.getLength(), '%') % 2 == 0) {
						command.text= "%%"; //$NON-NLS-1$
						linkedMode= 2 | AUTODELETE;
						break KEY;
					}
				}
				return false;
			case '"':
			case '\'':
			case '`':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)
						&& this.editorOptions.isSmartStringsEnabled()
						&& !isValueChar(cEnd) && !isValueChar(command.offset - 1) ) {
					final IRegion line= this.document.getLineInformationOfOffset(cEnd);
					if (!isClosedString(cEnd, line.getOffset() + line.getLength(), false, c)) {
						command.text= new String(new char[] { c, c });
						linkedMode= 2 | AUTODELETE;
						break KEY;
					}
				}
				return false;
			case '\n':
				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)
						|| contentType == IRDocumentConstants.R_COMMENT_CONTENT_TYPE) {
					command.text= TextUtilities.getDefaultLineDelimiter(this.document);
					smartIndentOnNewLine(command, contentType);
					break KEY;
				}
				else if (contentType == IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE) {
					command.text= TextUtilities.getDefaultLineDelimiter(this.document);
					smartIndentAfterNewLine1(command, command.text);
					break KEY;
				}
				return false;
			case '#':
 				if (R_DEFAULT_CONTENT_CONSTRAINT.matches(contentType)
						&& isAfterRoxygen(command.offset)) {
					command.text= "#' "; //$NON-NLS-1$
					break KEY;
				}
				return false;
			default:
				assert (false);
				return false;
			}
			
			if (command.text.length() > 0 && this.editor.isEditable(true)) {
				this.viewer.getTextWidget().setRedraw(false);
				try {
					this.document.replace(command.offset, command.length, command.text);
					final int cursor= (command.caretOffset >= 0) ? command.caretOffset :
							command.offset+command.text.length();
					selection= new TextSelection(this.document, cursor, 0);
					this.viewer.setSelection(selection, true);
					
					if (linkedMode >= 0) {
						if (linkedModeOffset < 0) {
							linkedModeOffset= command.offset;
						}
						createLinkedMode(linkedModeOffset, c, linkedMode).enter();
					}
				}
				finally {
					this.viewer.getTextWidget().setRedraw(true);
				}
				
				if (contextInfo
						&& this.viewer.canDoOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION)) {
					this.viewer.doOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
				}
			}
			return true;
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
					"An error occurred when customizing action for pressed key in R auto edit strategy.", e )); //$NON-NLS-1$
		}
		finally {
			this.ignoreCommands= false;
			quitCustomization();
		}
		return false;
	}
	
	/**
	 * Generic method to indent lines using the RSourceIndenter, called algorithm 2.
	 * @param c handle to read and save the document informations
	 * @param indentCurrentLine
	 * @param setCaret positive values indicates the line to set the caret
	 * @param traceCursor offset to update and return (offset at state after insertion of c.text)
	 */
	private Position[] smartIndentLine2(final DocumentCommand c, final boolean indentCurrentLine, final int setCaret, final Position[] tracePos) throws BadLocationException, BadPartitioningException, CoreException {
		if (this.editor3 == null) {
			return tracePos;
		}
		final TextRegion validRegion= this.validRange;
		
		// new algorithm using RSourceIndenter
		final int cEnd= c.offset+c.length;
		if (cEnd > validRegion.getEndOffset()) {
			return tracePos;
		}
		this.scanner.configure(this.document);
		final int smartEnd;
		final String smartAppend;
		if (endsWithNewLine(c.text)) {
			final IRegion cEndLine= this.document.getLineInformationOfOffset(cEnd);
			final int validEnd= (cEndLine.getOffset() + cEndLine.getLength() <= validRegion.getEndOffset()) ?
					cEndLine.getOffset() + cEndLine.getLength() :
					validRegion.getEndOffset();
			final int next= this.scanner.findAnyNonBlankForward(cEnd, validEnd, false);
			smartEnd= (next >= 0) ? next : validEnd;
			switch(this.scanner.getChar()) {
			case '}':
			case '{':
			case '|':
			case '&':
				smartAppend= ""; //$NON-NLS-1$
				break;
			default:
				smartAppend= "DUMMY+"; //$NON-NLS-1$
				break;
			}
		}
		else {
			smartEnd= cEnd;
			smartAppend= ""; //$NON-NLS-1$
		}
		
		int shift= 0;
		if (c.offset < validRegion.getStartOffset()
				|| c.offset > validRegion.getEndOffset()) {
			return tracePos;
		}
		if (c.offset > 2500) {
			final int line= this.document.getLineOfOffset(c.offset) - 40;
			if (line >= 10) {
				shift= this.document.getLineOffset(line);
				final ITypedRegion partition= this.document.getPartition(
						this.scanner.getDocumentPartitioning(), shift, true );
				if (!R_DEFAULT_CONTENT_CONSTRAINT.matches(partition.getType())) {
					shift= partition.getOffset();
				}
			}
		}
		if (shift < validRegion.getStartOffset()) {
			shift= validRegion.getStartOffset();
		}
		int dummyDocEnd= cEnd+1500;
		if (dummyDocEnd > validRegion.getEndOffset()) {
			dummyDocEnd= validRegion.getEndOffset();
		}
		final String text;
		{	final StringBuilder s= new StringBuilder(
					(c.offset-shift) +
					c.text.length() +
					(smartEnd-cEnd) +
					smartAppend.length() +
					(dummyDocEnd-smartEnd) );
			s.append(this.document.get(shift, c.offset-shift));
			s.append(c.text);
			if (smartEnd-cEnd > 0) {
				s.append(this.document.get(cEnd, smartEnd-cEnd));
			}
			s.append(smartAppend);
			s.append(this.document.get(smartEnd, dummyDocEnd-smartEnd));
			text= s.toString();
		}
		
		// Create temp doc to compute indent
		int dummyCoffset= c.offset-shift;
		int dummyCend= dummyCoffset+c.text.length();
		final AbstractDocument dummyDoc= new Document(text);
		final TextParserInput parserInput= (Display.getCurrent() == Display.getDefault()) ?
				DEFAULT_PARSER_INPUT.reset(text) : new StringParserInput(text);
		
		// Lines to indent
		int dummyFirstLine= dummyDoc.getLineOfOffset(dummyCoffset);
		final int dummyLastLine= dummyDoc.getLineOfOffset(dummyCend);
		if (!indentCurrentLine) {
			dummyFirstLine++;
		}
		if (dummyFirstLine > dummyLastLine) {
			return tracePos;
		}
		
		// Compute indent
		final RScanner scanner= new RScanner(AstInfo.LEVEL_MINIMAL);
		final RAstNode rootNode= scanner.scanSourceUnit(parserInput.init());
		if (this.indenter == null) {
			this.indenter= new RSourceIndenter(this.scanner);
		}
		this.indenter.setup(this.rCoreAccess);
		final TextEdit edit= this.indenter.getIndentEdits(dummyDoc, rootNode, 0, dummyFirstLine, dummyLastLine);
		
		// Apply indent to temp doc
		final Position cPos= new Position(dummyCoffset, c.text.length());
		dummyDoc.addPosition(cPos);
		if (tracePos != null) {
			for (int i= 0; i < tracePos.length; i++) {
				tracePos[i].offset -= shift;
				dummyDoc.addPosition(tracePos[i]);
			}
		}
		
		c.length= c.length+edit.getLength()
				// add space between two replacement regions
				// minus overlaps with c.text
				-TextUtil.overlaps(edit.getOffset(), edit.getExclusiveEnd(), dummyCoffset, dummyCend);
		if (edit.getOffset() < dummyCoffset) { // move offset, if edit begins before c
			dummyCoffset= edit.getOffset();
			c.offset= shift+dummyCoffset;
		}
		edit.apply(dummyDoc, TextEdit.NONE);
		
		// Read indent for real doc
		int dummyChangeEnd= edit.getExclusiveEnd();
		dummyCend= cPos.getOffset()+cPos.getLength();
		if (!cPos.isDeleted && dummyCend > dummyChangeEnd) {
			dummyChangeEnd= dummyCend;
		}
		c.text= dummyDoc.get(dummyCoffset, dummyChangeEnd-dummyCoffset);
		if (setCaret != 0) {
			c.caretOffset= shift+this.indenter.getNewIndentOffset(dummyFirstLine+setCaret-1);
			c.shiftsCaret= false;
		}
		this.indenter.clear();
		if (tracePos != null) {
			for (int i= 0; i < tracePos.length; i++) {
				tracePos[i].offset += shift;
			}
		}
		return tracePos;
	}
	
	private final boolean endsWithNewLine(final String text) {
		for (int i= text.length()-1; i >= 0; i--) {
			final char c= text.charAt(i);
			if (c == '\r' || c == '\n') {
				return true;
			}
			if (c != ' ' && c != '\t') {
				return false;
			}
		}
		return false;
	}
	
	
	private void smartIndentOnNewLine(final DocumentCommand c, final String partitionType)
			throws BadLocationException, BadPartitioningException, CoreException {
		final int before= c.offset - 1;
		final int behind= c.offset + c.length;
		final String lineDelimiter= c.text;
		if (R_DEFAULT_CONTENT_CONSTRAINT.matches(partitionType)
				&& before >= 0 && behind < this.validRange.getEndOffset()
				&& this.document.getChar(before) == '{' && this.document.getChar(behind) == '}') {
			c.text= c.text + c.text;
		}
		try {
			smartIndentLine2(c, false, 1, null);
		}
		catch (final Exception e) {
			RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while customize a command in R auto edit strategy (algorithm 2).", e); //$NON-NLS-1$
			smartIndentAfterNewLine1(c, lineDelimiter);
		}
	}
	
	private void smartIndentAfterNewLine1(final DocumentCommand c, final String lineDelimiter)
			throws BadLocationException, BadPartitioningException, CoreException {
		final StringBuilder sb= new StringBuilder(c.text);
		int nlIndex= lineDelimiter.length();
		
		final int line= this.document.getLineOfOffset(c.offset);
		int checkOffset= Math.max(0, c.offset);
		
		final ITypedRegion partition= this.document.getPartition(
				this.scanner.getDocumentPartitioning(), checkOffset, true );
		if (partition.getType() == IRDocumentConstants.R_COMMENT_CONTENT_TYPE) {
			checkOffset= partition.getOffset();
		}
		else if (partition.getType() == IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE) {
			checkOffset= -1;
			if (c.length == 0 && line + 1 < this.document.getNumberOfLines()) {
				final int offset= this.document.getLineOffset(line + 1);
				this.scanner.configure(this.document);
				final int next= this.scanner.findAnyNonBlankForward(offset, ITokenScanner.UNBOUND, true);
				if (next >= 0 && this.scanner.getPartition(next).getType() == IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE) {
					sb.append("#' "); //$NON-NLS-1$
				}
			}
			this.scanner.configure(this.document);
		}
		
		final IndentUtil util= new IndentUtil(this.document, this.rCodeStyle);
		final int column= util.getLineIndent(line, false)[IndentUtil.COLUMN_IDX];
		
		if (checkOffset > 0) {
			// new block?:
			this.scanner.configure(this.document);
			final int match= this.scanner.findAnyNonBlankBackward(checkOffset, this.document.getLineOffset(line) - 1, false);
			if (match >= 0 && this.document.getChar(match) == '{') {
				final String indent= util.createIndentString(util.getNextLevelColumn(column, 1));
				sb.insert(nlIndex, indent);
				nlIndex+= indent.length() + lineDelimiter.length();
			}
		}
		
		if (nlIndex <= sb.length()) {
			sb.insert(nlIndex, util.createIndentString(column));
		}
		c.text= sb.toString();
	}
	
	private int smartIndentOnTab(final DocumentCommand c) throws BadLocationException {
		final IRegion line= this.document.getLineInformation(this.document.getLineOfOffset(c.offset));
		int first;
		this.scanner.configure(this.document);
		first= this.scanner.findAnyNonBlankBackward(c.offset, line.getOffset()-1, false);
		if (first != ITokenScanner.NOT_FOUND) { // not first char
			return 0;
		}
//		first= scanner.findAnyNonBlankForward(c.offset, line.getOffset()+line.getLength(), false);
//		if (c.offset == line.getOffset() || c.offset != first) {
//			try {
//				final Position cursorPos= new Position(first, 0);
//				smartIndentLine2(c, true, 0, new Position[] { cursorPos });
//				c.caretOffset= cursorPos.getOffset();
//				return 1;
//			}
//			catch (final Exception e) {
//				RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while customize a command in R auto edit strategy (algorithm 2).", e); //$NON-NLS-1$
//				return -1;
//			}
//		}
		final IndentUtil indentation= new IndentUtil(this.document, this.rCodeStyle);
		final int column= indentation.getColumn(c.offset);
		if (this.editorOptions.getSmartInsertTabAction() != ISmartInsertSettings.TabAction.INSERT_TAB_CHAR) {
			c.text= indentation.createIndentCompletionString(column);
		}
		return 1;
	}
	
	private void smartIndentOnClosingBracket(final DocumentCommand c) throws BadLocationException {
		final int lineOffset= this.document.getLineOffset(this.document.getLineOfOffset(c.offset));
		this.scanner.configure(this.document);
		if (this.scanner.findAnyNonBlankBackward(c.offset, lineOffset-1, false) != ITokenScanner.NOT_FOUND) {
			// not first char
			return;
		}
		
		try {
			final Position cursorPos= new Position(c.offset+1, 0);
			smartIndentLine2(c, true, 0, new Position[] { cursorPos });
			c.caretOffset= cursorPos.getOffset();
			return;
		}
		catch (final Exception e) {
			RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while customize a command in R auto edit strategy (algorithm 2).", e); //$NON-NLS-1$
			smartIndentOnClosingBracket1(c);
		}
	}
	
	private void smartIndentOnClosingBracket1(final DocumentCommand c) throws BadLocationException {
		final int lineOffset= this.document.getLineOffset(this.document.getLineOfOffset(c.offset));
		final int blockStart= this.scanner.findOpeningPeer(lineOffset, CURLY_BRACKETS);
		if (blockStart == ITokenScanner.NOT_FOUND) {
			return;
		}
		final IndentUtil util= new IndentUtil(this.document, this.rCodeStyle);
		final int column= util.getLineIndent(this.document.getLineOfOffset(blockStart), false)[IndentUtil.COLUMN_IDX];
		c.text= util.createIndentString(column) + c.text;
		c.length += c.offset - lineOffset;
		c.offset= lineOffset;
	}
	
	private int smartIndentOnFirstLineCharDefault2(final DocumentCommand c) throws BadLocationException {
		final int lineOffset= this.document.getLineOffset(this.document.getLineOfOffset(c.offset));
		this.scanner.configure(this.document);
		if (this.scanner.findAnyNonBlankBackward(c.offset, lineOffset-1, false) != ITokenScanner.NOT_FOUND) {
			// not first char
			return c.offset;
		}
		
		try {
			final Position cursorPos= new Position(c.offset+1, 0);
			smartIndentLine2(c, true, 0, new Position[] { cursorPos });
			return (c.caretOffset= cursorPos.getOffset()) -1;
		}
		catch (final Exception e) {
			RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while customize a command in R auto edit strategy (algorithm 2).", e); //$NON-NLS-1$
			return -1;
		}
	}
	
	private void smartPaste(final DocumentCommand c) throws BadLocationException {
		final int lineOffset= this.document.getLineOffset(this.document.getLineOfOffset(c.offset));
		this.scanner.configure(this.document);
		final boolean firstLine= (this.scanner.findAnyNonBlankBackward(c.offset, lineOffset-1, false) == ITokenScanner.NOT_FOUND);
		try {
			smartIndentLine2(c, firstLine, 0, null);
		}
		catch (final Exception e) {
			RUIPlugin.logError(RUIPlugin.INTERNAL_ERROR, "An error occurred while customize a command in R auto edit strategy (algorithm 2).", e); //$NON-NLS-1$
		}
	}
	
	
	private LinkedModeUI createLinkedMode(final int offset, final char type, final int mode)
			throws BadLocationException {
		final LinkedModeModel model= new LinkedModeModel();
		int pos= 0;
		
		final LinkedPositionGroup group= new LinkedPositionGroup();
		final InBracketPosition position= RBracketLevel.createPosition(type, this.document,
				offset + 1, 0, pos++);
		group.addPosition(position);
		model.addGroup(group);
		
		model.forceInstall();
		
		final RBracketLevel level= new RBracketLevel(model,
				getDocument(), getDocumentContentInfo(),
				ImCollections.<LinkedPosition>newList(position), (mode & 0xffff0000) |
						((this.viewer instanceof InputSourceViewer) ? RBracketLevel.CONSOLE_MODE : 0) );
		
		/* create UI */
		final LinkedModeUI ui= new LinkedModeUI(model, this.viewer);
		ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
		ui.setExitPosition(this.viewer, offset + (mode & 0xff), 0, pos);
		ui.setSimpleMode(true);
		ui.setExitPolicy(level);
		return ui;
	}
	
}
