/*=============================================================================#
 # Copyright (c) 2007, 2021 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.ecommons.text;

import java.util.Arrays;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.text.IIndentSettings.IndentationType;


/**
 * Util to compute and edit line indentations
 */
public class IndentUtil {
	
	public static final int COLUMN_IDX= 0;
	public static final int OFFSET_IDX= 1;
	
	public static final char[] repeat(final char c, final int n) {
		final char[] chars= new char[n];
		Arrays.fill(chars, c);
		return chars;
	}
	
	
	public interface ILineIndent extends TextRegion {
		
		int getIndentOffset();
		
		int getIndentColumn();
		
		boolean isBlank();
		
	}
	
	
	private static abstract class LineIndent implements ILineIndent {
		
		
		private static final class Blank extends LineIndent {
			
			public Blank(final int lineOffset, final int indentOffset, final int indentColumn) {
				super(lineOffset, indentOffset, indentColumn);
			}
			
			@Override
			public boolean isBlank() {
				return true;
			}
			
		}
		
		private static final class NonBlank extends LineIndent {
			
			public NonBlank(final int lineOffset, final int indentOffset, final int indentColumn) {
				super(lineOffset, indentOffset, indentColumn);
			}
			
			@Override
			public boolean isBlank() {
				return false;
			}
			
		}
		
		
		private final int lineOffset;
		
		private final int indentOffset;
		
		private final int indentColumn;
		
		
		public LineIndent(final int lineOffset, final int indentOffset, final int indentColumn) {
			this.lineOffset= lineOffset;
			this.indentOffset= indentOffset;
			this.indentColumn= indentColumn;
		}
		
		
		@Override
		public int getStartOffset() {
			return this.lineOffset;
		}
		
		@Override
		public int getEndOffset() {
			return this.indentOffset;
		}
		
		@Override
		public int getLength() {
			return this.indentOffset - this.lineOffset;
		}
		
		@Override
		public int getIndentOffset() {
			return this.indentOffset;
		}
		
		@Override
		public int getIndentColumn() {
			return this.indentColumn;
		}
		
		@Override
		public abstract boolean isBlank();
		
	}
	
	
	public static abstract class IndentEditAction {
		
		private int indentColumn;
		
		public IndentEditAction() {
		}
		public IndentEditAction(final int indentColumn) {
			this.indentColumn= indentColumn;
		}
		public int getIndentColumn(final int line, final int lineOffset)
				throws BadLocationException {
			return this.indentColumn;
		}
		public abstract void doEdit(int line, int lineOffset, int length, StringBuilder text)
				throws BadLocationException;
	}
	
	
	private static interface EditStrategy {
		
		public void editInIndent(int firstLine, int lastLine, IndentEditAction action)
				throws BadLocationException;
		
		public void changeIndent(final int firstLine, final int lastLine, IndentEditAction action)
				throws BadLocationException;
		
		public String copyLineIndent(int line) 
				throws BadLocationException;
		
	}
	
	private class ConserveStrategy implements EditStrategy {
		
		@Override
		public void editInIndent(final int firstLine, final int lastLine, final IndentEditAction action)
				throws BadLocationException {
			final StringBuilder replacement= new StringBuilder(20);
			ITER_LINES : for (int line= firstLine; line <= lastLine; line++) {
				final IRegion lineInfo= IndentUtil.this.document.getLineInformation(line);
				final int indentColumn= action.getIndentColumn(line, lineInfo.getOffset());
				if (indentColumn < 0) {
					continue ITER_LINES;
				}
				if (indentColumn > 0) {
					replacement.setLength(0);
					int indentation= 0;
					int offset= lineInfo.getOffset();
					boolean changed= false;
					
					ITER_CHARS : while (indentation < indentColumn) {
						final int c= getDocumentChar(offset);
						int tabStart, tabEnd, spaceCount;
						switch (c) {
						case ' ':
							indentation++;
							offset++;
							replacement.append(' ');
							continue ITER_CHARS;
						case '\t':
							tabStart= (indentation/IndentUtil.this.tabWidth) * IndentUtil.this.tabWidth;
							tabEnd= tabStart + IndentUtil.this.tabWidth;
							if (tabEnd > indentColumn) {
								spaceCount= tabEnd - indentation;
								replacement.append(repeat(' ', spaceCount));
								changed= true;
							}
							else {
								replacement.append('\t');
							}
							indentation= tabEnd;
							offset++;
							continue ITER_CHARS;
						case '\r':
						case '\n':
						case -1:
							tabStart= (indentation/IndentUtil.this.tabWidth) * IndentUtil.this.tabWidth;
							tabEnd= tabStart + IndentUtil.this.tabWidth;
							if (IndentUtil.this.tabAsDefault && (tabEnd <= indentColumn)) {
								spaceCount= indentation-tabStart;
								replacement.delete(replacement.length()-spaceCount, replacement.length());
								replacement.append('\t');
								indentation= tabEnd;
								changed= true;
							}
							else {
								spaceCount= indentColumn-indentation;
								replacement.append(repeat(' ', spaceCount));
								indentation+= spaceCount;
								changed= true;
							}
							continue ITER_CHARS;
						default:
							throw new IllegalArgumentException(createNoIndentationCharMessage(c));
						}
					}
					if (changed) {
						action.doEdit(line, lineInfo.getOffset(), offset-lineInfo.getOffset(), replacement);
						continue ITER_LINES;
					}
				}
				action.doEdit(line, lineInfo.getOffset(), 0, null);
				continue ITER_LINES;
			}
		}
		
		@Override
		public void changeIndent(final int firstLine, final int lastLine, final IndentEditAction action)
				throws BadLocationException {
			final StringBuilder replacement= new StringBuilder(20);
			ITER_LINES : for (int line= firstLine; line <= lastLine; line++) {
				final IRegion lineInfo= IndentUtil.this.document.getLineInformation(line);
				final int indentColumn= action.getIndentColumn(line, lineInfo.getOffset());
				if (indentColumn < 0) {
					continue ITER_LINES;
				}
				replacement.setLength(0);
				int column= 0;
				int offset= lineInfo.getOffset();
				
				ITER_CHARS : while (column < indentColumn) {
					final int c= getDocumentChar(offset);
					int tabStart, tabEnd, spaceCount;
					switch (c) {
					case ' ':
						column++;
						offset++;
						replacement.append(' ');
						continue ITER_CHARS;
					case '\t':
						tabStart= (column/IndentUtil.this.tabWidth) * IndentUtil.this.tabWidth;
						tabEnd= tabStart + IndentUtil.this.tabWidth;
						if (tabEnd > indentColumn) {
							spaceCount= indentColumn - column;
							replacement.append(repeat(' ', spaceCount));
							column= indentColumn;
						}
						else {
							replacement.append('\t');
							column= tabEnd;
						}
						offset++;
						continue ITER_CHARS;
					default:
						break ITER_CHARS;
					}
				}
				ITER_CHARS : while (true) {
					final int c= getDocumentChar(offset);
					if (c != ' ' && c != '\t') {
						break ITER_CHARS;
					}
					offset++;
				}
				if (column < indentColumn) {
					appendIndent(replacement, column, indentColumn);
				}
				
				action.doEdit(line, lineInfo.getOffset(), offset-lineInfo.getOffset(), replacement);
				continue ITER_LINES;
			}
		}
		
		@Override
		public String copyLineIndent(final int line) throws BadLocationException {
			final IRegion lineInfo= IndentUtil.this.document.getLineInformation(line);
			int offset= lineInfo.getOffset();
			ITERATE_CHAR : while (true) {
				final int c= getDocumentChar(offset++);
				switch (c) {
				case ' ':
					continue ITERATE_CHAR;
				case '\t':
					continue ITERATE_CHAR;
				default:
					--offset;
					break ITERATE_CHAR;
				}
			}
			return IndentUtil.this.document.get(lineInfo.getOffset(), offset-lineInfo.getOffset());
		}
		
	}
	
	private class CorrectStrategy implements EditStrategy {
		
		@Override
		public void editInIndent(final int firstLine, final int lastLine, final IndentEditAction action)
				throws BadLocationException {
			final StringBuilder replacement= new StringBuilder(20);
			ITER_LINES : for (int line= firstLine; line <= lastLine; line++) {
				final int lineOffset= IndentUtil.this.document.getLineOffset(line);
				final int indentColumn= action.getIndentColumn(line, lineOffset);
				if (indentColumn < 0) {
					continue ITER_LINES;
				}
				final int[] current= getLineIndent(line, true);
				replacement.setLength(0);
				appendIndent(replacement, indentColumn);
				if (current[COLUMN_IDX] >= 0) {
					appendSpaces(replacement, current[COLUMN_IDX]-indentColumn);
				}
				action.doEdit(line, lineOffset, current[OFFSET_IDX]-lineOffset, replacement);
				continue ITER_LINES;
			}
		}
		
		@Override
		public void changeIndent(final int firstLine, final int lastLine, final IndentEditAction action)
				throws BadLocationException {
			final StringBuilder replacement= new StringBuilder(20);
			ITER_LINES : for (int line= firstLine; line <= lastLine; line++) {
				final int lineOffset= IndentUtil.this.document.getLineOffset(line);
				final int indentColumn= action.getIndentColumn(line, lineOffset);
				if (indentColumn < 0) {
					continue ITER_LINES;
				}
				final int[] current= getLineIndent(line, false);
				replacement.setLength(0);
				appendIndent(replacement, indentColumn);
				action.doEdit(line, lineOffset, current[OFFSET_IDX]-lineOffset, replacement);
				continue ITER_LINES;
			}
			
		}
		
		@Override
		public String copyLineIndent(final int line) throws BadLocationException {
			final IRegion lineInfo= IndentUtil.this.document.getLineInformation(line);
			int column= 0;
			int offset= lineInfo.getOffset();
			ITERATE_CHAR : while (true) {
				final int c= getDocumentChar(offset++);
				switch (c) {
				case ' ':
					column++;
					continue ITERATE_CHAR;
				case '\t':
					column+= IndentUtil.this.tabWidth - (column % IndentUtil.this.tabWidth);
					continue ITERATE_CHAR;
				default:
					break ITERATE_CHAR;
				}
			}
			return createIndentString(column);
		}
		
	}
	
	
	private final IDocument document;
	private final int tabWidth;
	private final boolean tabAsDefault;
	private final int numOfSpaces;
	private final EditStrategy editStrategy;
	
	
//	public IndentUtil(final IDocument document, final booeditStrategy,
//			final boolean tabsAsDefault, final int tabWidth, final int numOfSpaces) {
//		document= document;
//		switch (editStrategy) {
//		case CONSERVE_STRATEGY:
//			fConservative= new ConserveStrategy();
//			break;
//		case CORRECT_STRATEGY:
//			fConservative= new CorrectStrategy();
//			break;
//		}
//		fTabAsDefault= tabsAsDefault;
//		fTabWidth= tabWidth;
//		fNumOfSpaces= numOfSpaces;
//	}
//	
	public IndentUtil(final IDocument document, final IIndentSettings settings) {
		this.document= document;
		this.editStrategy= (settings.getReplaceConservative()) ?
				new ConserveStrategy() : new CorrectStrategy();
		this.tabAsDefault= (settings.getIndentDefaultType() == IndentationType.TAB);
		this.tabWidth= settings.getTabSize();
		this.numOfSpaces= settings.getIndentSpacesCount();
	}
	
	
	public final IDocument getDocument() {
		return this.document;
	}
	
	public final int getTabWidth() {
		return this.tabWidth;
	}
	
	/**
	 * Return the indentation indentColumn of the specified line.
	 * 
	 * @param line line to check
	 * @param markBlankLine if true, empty lines have are marked with a indentColumn of -1
	 * @return column and offset of line indent
	 * @throws BadLocationException
	 */
	@Deprecated
	public int[] getLineIndent(final int line, final boolean markBlankLine) throws BadLocationException {
		final IRegion lineInfo= this.document.getLineInformation(line);
		int column= 0;
		int offset= lineInfo.getOffset();
		ITERATE_CHAR : while (true) {
			final int c= getDocumentChar(offset++);
			switch (c) {
			case ' ':
				column++;
				continue ITERATE_CHAR;
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITERATE_CHAR;
			case '\r':
			case '\n':
			case -1:
				if (markBlankLine) {
					return new int[] { -1, --offset };
				}
				//$FALL-THROUGH$
			default:
				return new int[] { column, --offset };
			}
		}
	}
	
	/**
	 * Creates a line indentation string with same depth as the given line.
	 * The exact string depends on the configured strategy.
	 * @param line the line number
	 * @return line indentation string
	 * @throws BadLocationException
	 */
	public String copyLineIndent(final int line) throws BadLocationException {
		return this.editStrategy.copyLineIndent(line);
	}
	
//	public int getIndentationindentColumn(String chars) throws BadLocationException {
//		
//		int indentation= 0;
//		ITER_CHARS : for (int i= 0; i < chars.length(); i++) {
//			char c= document.getChar(i);
//			switch (c) {
//			case ' ':
//				indentation++;
//				continue ITER_CHARS;
//			case '\t':
//				indentation+= fTabWidth;
//				continue ITER_CHARS;
//			default:
//				throw new IllegalArgumentException("No indentation char: '"+c+"'."); //$NON-NLS-1$ //$NON-NLS-2$
//			}
//		}
//		return indentation;
//	}
	
	/**
	 * Returns the common (min) indentation indentColumn of all lines. Empty lines are ignored.
	 * @param startLine line index of first line
	 * @param endLine line index of last line
	 * @return
	 * @throws BadLocationException
	 */
	public int getMultilineIndentColumn(final int startLine, final int endLine) throws BadLocationException {
		int indentation= Integer.MAX_VALUE;
		for (int line= startLine; line <= endLine; line++) {
			final int[] lineIndent= getLineIndent(line, true);
			if (lineIndent[COLUMN_IDX] >= 0) {
				indentation= Math.min(indentation, lineIndent[COLUMN_IDX]);
			}
		}
		if (indentation == Integer.MAX_VALUE) {
			indentation= 0;
		}
		return indentation;
	}
	
	/**
	 * Prepares the indentation of the line, so you can insert text at the
	 * given indentation indentColumn.
	 * 
	 * @param line line index
	 * @return the returned object of your action
	 * @throws BadLocationException
	 */
	public void editInIndent(final int firstLine, final int lastLine, final IndentEditAction action)
			throws BadLocationException {
		this.editStrategy.editInIndent(firstLine, lastLine, action);
	}
	
	public void changeIndent(final int firstLine, final int lastLine, final IndentEditAction action)
			throws BadLocationException {
		this.editStrategy.changeIndent(firstLine, lastLine, action);
	}
	
	
	/**
	 * Returns the indentation of the specified line.
	 * 
	 * @param line line to check
	 * @return the line indent
	 */
	public final ILineIndent getIndent(final CharSequence line) {
		int offset= 0;
		int column= 0;
		ITER_CHARS : for (; offset < line.length(); offset++) {
			final char c= line.charAt(offset);
			switch (c) {
			case ' ':
				column++;
				continue ITER_CHARS;
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITER_CHARS;
			case '\r':
			case '\n':
				break ITER_CHARS;
			default:
				return new LineIndent.NonBlank(0, offset, column);
			}
		}
		return new LineIndent.Blank(0, offset, column);
	}
	
	/**
	 * Returns the column of the specified offset.
	 * 
	 * Linebreak are not specially handled.
	 * 
	 * @param offset index in string
	 * @return char column
	 */
	public final int getColumn(final CharSequence line, final int offset) {
		int checkOffset= 0;
		int column= 0;
		ITER_CHARS : while (checkOffset < offset) {
			switch (line.charAt(checkOffset++)) {
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITER_CHARS;
			default:
				column++;
				continue ITER_CHARS;
			}
		}
		return column;
	}
	
	/**
	 * Returns the column of the specified offset.
	 * 
	 * Linebreak are not specially handled.
	 * 
	 * @param line text
	 * @param offset index in text
	 * @param startColumn column of the text
	 * @return char column
	 */
	public final int getColumn(final CharSequence line, final int offset, final int startColumn) {
		int checkOffset= 0;
		int column= startColumn;
		ITER_CHARS : while (checkOffset < offset) {
			switch (line.charAt(checkOffset++)) {
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITER_CHARS;
			default:
				column++;
				continue ITER_CHARS;
			}
		}
		return column;
	}
	
	/**
	 * Returns the char offset in indentation with column ≥ the specified column.
	 * 
	 * @param line text to check
	 * @param column indentColumn to search for
	 * @return the offset
	 */
	public final int getIndentedOffsetAt(final CharSequence line, final int column) {
		int currentOffset= 0;
		int currentColumn= 0;
		ITER_CHARS : for (; currentOffset < line.length() && currentColumn < column; currentOffset++) {
			final char c= line.charAt(currentOffset);
			switch (c) {
			case ' ':
				currentColumn++;
				continue ITER_CHARS;
			case '\t':
				currentColumn+= this.tabWidth - (currentColumn % this.tabWidth);
				continue ITER_CHARS;
			default:
				throw new IllegalArgumentException(createNoIndentationCharMessage(c));
			}
		}
		return currentOffset;
	}
	
	
	/**
	 * Returns the indentation of the specified line.
	 * 
	 * @param lineNum the index of the line to check
	 * @return the line indent
	 * @throws BadLocationException 
	 */
	public final ILineIndent getIndent(final int lineNum) throws BadLocationException {
		int offset= this.document.getLineOffset(lineNum);
		int column= 0;
		final int bound= this.document.getLength();
		ITER_CHARS : for (; offset < bound; offset++) {
			final char c= this.document.getChar(offset);
			switch (c) {
			case ' ':
				column++;
				continue ITER_CHARS;
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITER_CHARS;
			case '\r':
			case '\n':
				break ITER_CHARS;
			default:
				return new LineIndent.NonBlank(0, offset, column);
			}
		}
		return new LineIndent.Blank(0, offset, column);
	}
	
	/**
	 * Returns the column of the specified offset.
	 * 
	 * Linebreaks are not specially handled.
	 * 
	 * @param offset offset in document
	 * @return the column
	 * @throws BadLocationException
	 */
	public final int getColumn(final int offset) throws BadLocationException {
		return getColumn(this.document.getLineOfOffset(offset), offset);
	}
	
	/**
	 * Returns the column of the specified offset.
	 * 
	 * Linebreaks are not specially handled.
	 * 
	 * @param lineNum the index of the line to check
	 * @param offset the offset in document
	 * @return the column
	 * @throws BadLocationException
	 */
	public final int getColumn(final int lineNum, final int offset) throws BadLocationException {
		int checkOffset= this.document.getLineOffset(lineNum);
		int column= 0;
		ITER_CHARS : while (checkOffset < offset) {
			switch (this.document.getChar(checkOffset++)) {
			case '\t':
				column+= this.tabWidth - (column % this.tabWidth);
				continue ITER_CHARS;
			default:
				column++;
				continue ITER_CHARS;
			}
		}
		return column;
	}
	
	/**
	 * Returns the document offset in indentation with column ≥ the specified column.
	 * 
	 * @param lineNum the index of the line to check
	 * @param column the column
	 * @return the offset of the column
	 * @throws BadLocationException
	 * @throws IllegalArgumentException
	 */
	public final int getIndentedOffsetAt(final int lineNum, final int column)
			throws BadLocationException {
		final IRegion lineInfo= this.document.getLineInformation(lineNum);
		int currentOffset= lineInfo.getOffset();
		int currentColumn= 0;
		ITER_CHARS : while (currentColumn < column) {
			final char c= this.document.getChar(currentOffset++);
			switch (c) {
			case ' ':
				currentColumn++;
				continue ITER_CHARS;
			case '\t':
				currentColumn+= this.tabWidth - (currentColumn % this.tabWidth);
				continue ITER_CHARS;
			default:
				throw new IllegalArgumentException(createNoIndentationCharMessage(c));
			}
		}
		return currentOffset;
	}
	
	/**
	 * Returns the last document offset with column ≤ the specified column.
	 * 
	 * @param lineNum the index of the line to check
	 * @param column the column
	 * @return the offset of the column or -1 if line is shorter
	 * @throws BadLocationException
	 */
	public final int getOffsetAtMax(final int lineNum, final int column)
			throws BadLocationException {
		final IRegion lineInfo= this.document.getLineInformation(lineNum);
		int offset= lineInfo.getOffset();
		final int bound= lineInfo.getLength();
		int current= 0;
		ITER_CHARS : while (current < column) {
			if (offset >= bound) {
				return -1;
			}
			switch (this.document.getChar(offset++)) {
			case '\t':
				current+= this.tabWidth - (current % this.tabWidth);
				continue ITER_CHARS;
			default:
				current++;
				continue ITER_CHARS;
			}
		}
		return (current > column) ? offset - 1 : offset;
	}
	
	
	/**
	 * Returns the configured width of a default indentation.
	 * 
	 * @return number of visual char columns
	 */
	public int getLevelColumns() {
		if (this.tabAsDefault) {
			return this.tabWidth;
		}
		else {
			return this.numOfSpaces;
		}
	}
	
	/**
	 * Computes the indentation column adding the specified levels to the current indentColumn.
	 * 
	 * @param currentColumn indentColumn in visual char columns
	 * @param levels number of indentation levels
	 * @return indentColumn in visual char columns
	 */
	public int getNextLevelColumn(final int currentColumn, final int levels) {
		final int columns= getLevelColumns();
		return ((currentColumn / columns + levels) * columns);
	}
	
	/**
	 * Creates a string for indentation of specified indentColumn (respects the preferences).
	 * @param indentColumn
	 * @return
	 */
	public String createIndentString(final int indentColumn) {
		if (this.tabAsDefault) {
			return new StringBuilder(indentColumn)
					.append(repeat('\t', indentColumn / this.tabWidth))
					.append(repeat(' ', indentColumn % this.tabWidth))
					.toString();
		}
		else {
			return new String(repeat(' ', indentColumn));
		}
	}
	
	public final String createIndentCompletionString(final int currentColumn) {
		if (this.tabAsDefault) {
			return "\t"; //$NON-NLS-1$
		}
		else {
			final int rest= currentColumn % this.numOfSpaces;
			return new String(repeat(' ', this.numOfSpaces - rest));
		}
	}
	
	public final String createTabCompletionString(final int currentColumn) {
		if (this.tabAsDefault) {
			return "\t"; //$NON-NLS-1$
		}
		else {
			return createTabSpacesCompletionString(currentColumn);
		}
	}
	
	public final String createTabSpacesCompletionString(final int currentColumn) {
		final int rest= currentColumn % this.tabWidth;
		return new String(repeat(' ', this.tabWidth - rest));
	}
	
	
	protected final int getDocumentChar(final int idx) throws BadLocationException {
		if (idx >= 0 && idx < this.document.getLength()) {
			return this.document.getChar(idx);
		}
		if (idx == -1 || idx == this.document.getLength()) {
			return -1;
		}
		throw new BadLocationException();
	}
	
	public final void appendIndent(final StringBuilder sb, final int indentColumn) {
		if (this.tabAsDefault) {
			sb.append(repeat('\t', indentColumn / this.tabWidth));
			sb.append(repeat(' ', indentColumn % this.tabWidth));
		}
		else {
			sb.append(repeat(' ', indentColumn));
		}
	}
	
	public final void appendIndent(final StringBuilder sb, final int currentColumn, final int indentColumn) {
		if (this.tabAsDefault) {
			final int tabDiff= (indentColumn / this.tabWidth) - (currentColumn / this.tabWidth) ;
			if (tabDiff > 0) {
				final int spaces= currentColumn % this.tabWidth;
				if (spaces > 0) {
					sb.append(repeat(' ', this.tabWidth - spaces));
					sb.append(repeat('\t', tabDiff - 1));
				}
				else {
					sb.append(repeat('\t', tabDiff));
				}
				sb.append(repeat(' ', indentColumn % this.tabWidth));
			}
			else {
				sb.append(repeat(' ', indentColumn - currentColumn));
			}
		}
		else {
			sb.append(repeat(' ', indentColumn));
		}
	}
	
//	protected final void appendIndentCompletion(final StringBuilder s, final int currentColumn) {
//		if (fTabAsDefault) {
//			s.append('\t');
//		}
//		else {
//			s.append(repeat(' ', fNumOfSpaces-(currentColumn % fNumOfSpaces)));
//		}
//	}
	
	protected final void appendSpaces(final StringBuilder s, final int num) {
		s.append(repeat(' ', num));
	}
	
	private String createNoIndentationCharMessage(final int c) {
		return NLS.bind("No indentation char: ''{0}''.", ((char)c)); //$NON-NLS-1$
	}
	
}
