/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.formatter.comment;

import java.util.Iterator;
import java.util.LinkedList;

import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ILineTracker;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;

import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
import org.eclipse.jdt.internal.formatter.Scribe;

/**
 * Comment region in a source code document.
 * 
 * @since 3.0
 */
public class CommentRegion extends Position implements IHtmlTagDelimiters, IBorderAttributes, ICommentAttributes {

	/** Default comment range delimiter */
	protected static final String COMMENT_RANGE_DELIMITER= " "; //$NON-NLS-1$

	/** Default line prefix length */
	private static final int COMMENT_PREFIX_LENGTH= 3;

	/** The borders of this region */
	private int fBorders= 0;

	/** Should all blank lines be cleared during formatting? */
	private final boolean fClear;

	/** The line delimiter used in this comment region */
	private final String fDelimiter;

	/** The document to format */
	private final IDocument fDocument;

	/** The lines in this comment region */
	private final LinkedList fLines= new LinkedList();
	
	/** The formatting preferences */
	protected final DefaultCodeFormatterOptions preferences;
	
	/** The comment ranges in this comment region */
	private final LinkedList fRanges= new LinkedList();

	/** Is this comment region a single line region? */
	private final boolean fSingleLine;

	/** Number of spaces representing tabulator */
	private int fTabSize;

	/**
	 * <code>true</code> if tabs, not spaces, should be used for indentation
	 * @since 3.1
	 */
	private boolean fUseTab;
	
	/** the scribe used to create edits */
	protected Scribe scribe;

	/**
	 * Creates a new comment region.
	 * 
	 * @param document the document which contains the comment region
	 * @param position the position of this comment region in the document
	 * @param formatter the given code formatter
	 */
	public CommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
		super(position.getOffset(), position.getLength());

		this.preferences = formatter.preferences;
		fDelimiter = this.preferences.line_separator;
		fDocument= document;
		
		fClear= this.preferences.comment_clear_blank_lines;
		
		fTabSize= this.preferences.tab_size;
		fUseTab = this.preferences.tab_char == DefaultCodeFormatterOptions.TAB;

		this.scribe = formatter.scribe;

		final ILineTracker tracker= new DefaultLineTracker();

		IRegion range= null;
		CommentLine line= null;

		tracker.set(getText(0, getLength()));
		final int lines= tracker.getNumberOfLines();

		fSingleLine= lines == 1;

		try {

			for (int index= 0; index < lines; index++) {

				range= tracker.getLineInformation(index);
				line= createLine();
				line.append(new CommentRange(range.getOffset(), range.getLength()));

				fLines.add(line);
			}

		} catch (BadLocationException exception) {
			// Should not happen
		}
	}

	/**
	 * Appends the comment range to this comment region.
	 * 
	 * @param range comment range to append to this comment region
	 */
	protected final void append(final CommentRange range) {
		fRanges.addLast(range);
	}

	/**
	 * Can the comment range be appended to the comment line?
	 * 
	 * @param line comment line where to append the comment range
	 * @param previous comment range which is the predecessor of the current
	 *                comment range
	 * @param next comment range to test whether it can be appended to the
	 *                comment line
	 * @param index amount of space in the comment line used by already
	 *                inserted comment ranges
	 * @param width the maximal width of text in this comment region
	 *                measured in average character widths
	 * @return <code>true</code> iff the comment range can be added to the
	 *         line, <code>false</code> otherwise
	 */
	protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, final int width) {
		return index == 0 || index + next.getLength() <= width;
	}

	/**
	 * Can the whitespace between the two comment ranges be formatted?
	 * 
	 * @param previous previous comment range which was already formatted,
	 *                can be <code>null</code>
	 * @param next next comment range to be formatted
	 * @return <code>true</code> iff the next comment range can be
	 *         formatted, <code>false</code> otherwise.
	 */
	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
		return previous != null;
	}

	/**
	 * Formats the comment region with the given indentation level.
	 * 
	 * @param indentationLevel the indentation level
	 * @return the resulting text edit of the formatting process
	 * @since 3.1
	 */
	public final TextEdit format(int indentationLevel, boolean returnEdit) {
		final String probe= getText(0, CommentLine.NON_FORMAT_START_PREFIX.length());
		if (!probe.startsWith(CommentLine.NON_FORMAT_START_PREFIX)) {

			int margin= this.preferences.comment_line_length;
			String indentation= computeIndentation(indentationLevel);
			margin= Math.max(COMMENT_PREFIX_LENGTH + 1, margin - stringToLength(indentation) - COMMENT_PREFIX_LENGTH);

			tokenizeRegion();
			markRegion();
			wrapRegion(margin);
			formatRegion(indentation, margin);

		}
		if (returnEdit) {
			return this.scribe.getRootEdit();
		}
		return null;
	}

	/**
	 * Formats this comment region.
	 * 
	 * @param indentation the indentation of this comment region
	 * @param width the maximal width of text in this comment region
	 *                measured in average character widths
	 */
	protected void formatRegion(final String indentation, final int width) {

		final int last= fLines.size() - 1;
		if (last >= 0) {

			CommentLine lastLine= (CommentLine)fLines.get(last);
			CommentRange lastRange= lastLine.getLast();
			lastLine.formatLowerBorder(lastRange, indentation, width);

			CommentLine previous;
			CommentLine next= null;
			CommentRange range= null;
			for (int line= last; line >= 0; line--) {

				previous= next;
				next= (CommentLine)fLines.get(line);

				range= next.formatLine(previous, range, indentation, line);
			}
			next.formatUpperBorder(range, indentation, width);
		}
	}

	/**
	 * Returns the line delimiter used in this comment region.
	 * 
	 * @return the line delimiter for this comment region
	 */
	protected final String getDelimiter() {
		return fDelimiter;
	}

	/**
	 * Returns the line delimiter used in this comment line break.
	 * 
	 * @param predecessor the predecessor comment line after the line break
	 * @param successor the successor comment line before the line break
	 * @param previous the comment range after the line break
	 * @param next the comment range before the line break
	 * @param indentation indentation of the formatted line break
	 * @return the line delimiter for this comment line break
	 */
	protected String getDelimiter(final CommentLine predecessor, final CommentLine successor, final CommentRange previous, final CommentRange next, final String indentation) {
		return fDelimiter + indentation + successor.getContentPrefix();
	}

	/**
	 * Returns the range delimiter for this comment range break.
	 * 
	 * @param previous the previous comment range to the right of the range
	 *                delimiter
	 * @param next the next comment range to the left of the range delimiter
	 * @return the delimiter for this comment range break
	 */
	protected String getDelimiter(final CommentRange previous, final CommentRange next) {
		return COMMENT_RANGE_DELIMITER;
	}

	/**
	 * Returns the document of this comment region.
	 * 
	 * @return the document of this region
	 */
	protected final IDocument getDocument() {
		return fDocument;
	}

	/**
	 * Returns the comment ranges in this comment region
	 * 
	 * @return the comment ranges in this region
	 */
	protected final LinkedList getRanges() {
		return fRanges;
	}

	/**
	 * Returns the number of comment lines in this comment region.
	 * 
	 * @return the number of lines in this comment region
	 */
	protected final int getSize() {
		return fLines.size();
	}

	/**
	 * Returns the text of this comment region in the indicated range.
	 * 
	 * @param position the offset of the comment range to retrieve in
	 *                comment region coordinates
	 * @param count the length of the comment range to retrieve
	 * @return the content of this comment region in the indicated range
	 */
	protected final String getText(final int position, final int count) {

		String content= ""; //$NON-NLS-1$
		try {
			content= fDocument.get(getOffset() + position, count);
		} catch (BadLocationException exception) {
			// Should not happen
		}
		return content;
	}

	/**
	 * Does the border <code>border</code> exist?
	 * 
	 * @param border the type of the border, must be a border attribute of
	 *                <code>CommentRegion</code>
	 * @return <code>true</code> iff this border exists,
	 *         <code>false</code> otherwise
	 */
	protected final boolean hasBorder(final int border) {
		return (fBorders & border) == border;
	}

	/**
	 * Does the comment range consist of letters and digits only?
	 * 
	 * @param range the comment range to text
	 * @return <code>true</code> iff the comment range consists of letters
	 *         and digits only, <code>false</code> otherwise
	 */
	protected final boolean isAlphaNumeric(final CommentRange range) {

		final String token= getText(range.getOffset(), range.getLength());

		for (int index= 0; index < token.length(); index++) {
			if (!Character.isLetterOrDigit(token.charAt(index)))
				return false;
		}
		return true;
	}

	/**
	 * Does the comment range contain no letters and digits?
	 * 
	 * @param range the comment range to text
	 * @return <code>true</code> iff the comment range contains no letters
	 *         and digits, <code>false</code> otherwise
	 */
	protected final boolean isNonAlphaNumeric(final CommentRange range) {

		final String token= getText(range.getOffset(), range.getLength());

		for (int index= 0; index < token.length(); index++) {
			if (Character.isLetterOrDigit(token.charAt(index)))
				return false;
		}
		return true;
	}

	/**
	 * Should blank lines be cleared during formatting?
	 * 
	 * @return <code>true</code> iff blank lines should be cleared,
	 *         <code>false</code> otherwise
	 */
	protected final boolean isClearLines() {
		return fClear;
	}

	/**
	 * Is this comment region a single line region?
	 * 
	 * @return <code>true</code> iff this region is single line,
	 *         <code>false</code> otherwise
	 */
	protected final boolean isSingleLine() {
		return fSingleLine;
	}

	/**
	 * Logs a text edit operation occurred during the formatting process
	 * 
	 * @param change the changed text
	 * @param position offset measured in comment region coordinates where
	 *                to apply the changed text
	 * @param count length of the range where to apply the changed text
	 */
	protected final void logEdit(final String change, final int position, final int count) {
		try {
			final int base= getOffset() + position;
			final String content= fDocument.get(base, count);

			if (!change.equals(content)) {
				if (count > 0) {
					this.scribe.addReplaceEdit(base, base + count - 1, change);
				} else {
					this.scribe.addInsertEdit(base, change);
				}
			}
		} catch (BadLocationException exception) {
			// Should not happen
			CommentFormatterUtil.log(exception);
		} catch (MalformedTreeException exception) {
			// Do nothing
			CommentFormatterUtil.log(exception);
		}
	}

	/**
	 * Marks the comment ranges in this comment region.
	 */
	protected void markRegion() {
		// Do nothing
	}

	/**
	 * Set the border type <code>border</code> to true.
	 * 
	 * @param border the type of the border. Must be a border attribute of
	 *                <code>CommentRegion</code>
	 */
	protected final void setBorder(final int border) {
		fBorders |= border;
	}

	/**
	 * Returns the indentation of the given indentation level.
	 * 
	 * @param indentationLevel the indentation level
	 * @return the indentation of the given indentation level
	 * @since 3.1
	 */
	private String computeIndentation(int indentationLevel) {
		return replicate(fUseTab ? "\t" : replicate(" ", fTabSize), indentationLevel);  //$NON-NLS-1$//$NON-NLS-2$
	}
	
	/**
	 * Returns the given string n-times replicated.
	 * 
	 * @param string the string
	 * @param n n
	 * @return the given string n-times replicated
	 * @since 3.1
	 */
	private String replicate(String string, int n) {
		StringBuffer buffer= new StringBuffer(n*string.length());
		for (int i= 0; i < n; i++)
			buffer.append(string);
		return buffer.toString();
	}

	/**
	 * Computes the equivalent indentation for a string
	 * 
	 * @param reference the string to compute the indentation for
	 * @param tabs <code>true</code> iff the indentation should use tabs,
	 *                <code>false</code> otherwise.
	 * @return the indentation string
	 */
	protected final String stringToIndent(final String reference, final boolean tabs) {

		int spaceWidth= 1;
		int referenceWidth= expandTabs(reference).length();

		final StringBuffer buffer= new StringBuffer();
		final int spaces= referenceWidth / spaceWidth;

		if (tabs) {

			final int count= spaces / fTabSize;
			final int modulo= spaces % fTabSize;

			for (int index= 0; index < count; index++)
				buffer.append('\t');

			for (int index= 0; index < modulo; index++)
				buffer.append(' ');

		} else {

			for (int index= 0; index < spaces; index++)
				buffer.append(' ');
		}
		return buffer.toString();
	}

	/**
	 * Returns the length of the string in expanded characters.
	 * 
	 * @param reference the string to get the length for
	 * @return the length of the string in expanded characters
	 */
	protected final int stringToLength(final String reference) {
		return expandTabs(reference).length();
	}

	/**
	 * Expands the given string's tabs according to the given tab size.
	 * 
	 * @param string the string
	 * @return the expanded string
	 * @since 3.1
	 */
	private String expandTabs(String string) {
		StringBuffer expanded= new StringBuffer();
		for (int i= 0, n= string.length(), chars= 0; i < n; i++) {
			char ch= string.charAt(i);
			if (ch == '\t') {
				for (; chars < fTabSize; chars++)
					expanded.append(' ');
				chars= 0;
			} else {
				expanded.append(ch);
				chars++;
				if (chars >= fTabSize)
					chars= 0;
			}
		
		}
		return expanded.toString();
	}

	/**
	 * Tokenizes the comment region.
	 */
	protected void tokenizeRegion() {

		int index= 0;
		CommentLine line= null;

		for (final Iterator iterator= fLines.iterator(); iterator.hasNext(); index++) {

			line= (CommentLine)iterator.next();

			line.scanLine(index);
			line.tokenizeLine(index);
		}
	}

	/**
	 * Wraps the comment ranges in this comment region into comment lines.
	 * 
	 * @param width the maximal width of text in this comment region
	 *                measured in average character widths
	 */
	protected void wrapRegion(final int width) {

		fLines.clear();

		int index= 0;
		boolean adapted= false;

		CommentLine successor= null;
		CommentLine predecessor= null;

		CommentRange previous= null;
		CommentRange next= null;

		while (!fRanges.isEmpty()) {

			index= 0;
			adapted= false;

			predecessor= successor;
			successor= createLine();
			fLines.add(successor);

			while (!fRanges.isEmpty()) {
				next= (CommentRange)fRanges.getFirst();

				if (canAppend(successor, previous, next, index, width)) {

					if (!adapted && predecessor != null) {

						successor.adapt(predecessor);
						adapted= true;
					}

					fRanges.removeFirst();
					successor.append(next);

					index += (next.getLength() + 1);
					previous= next;
				} else
					break;
			}
		}
	}

	/**
	 * Creates a new line for this region.
	 * 
	 * @return a new line for this region
	 * @since 3.1
	 */
	protected CommentLine createLine() {
		return new SingleCommentLine(this);
	}
}
