/*******************************************************************************
 * 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 Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.corext.text.comment;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.text.Position;

/**
 * Range in a comment region in comment region coordinates.
 * 
 * @since 3.0
 */
public class CommentRange extends Position implements ICommentAttributes, IHtmlTagDelimiters {

	/** The attributes of this range */
	private int fAttributes= 0;

	/**
	 * Creates a new comment range.
	 * 
	 * @param position offset of the range
	 * @param count length of the range
	 */
	public CommentRange(final int position, final int count) {
		super(position, count);
	}

	/**
	 * Is the attribute <code>attribute</code> true?
	 * 
	 * @param attribute the attribute to get
	 * @return <code>true</code> iff this attribute is <code>true</code>,
	 *         <code>false</code> otherwise
	 */
	protected final boolean hasAttribute(final int attribute) {
		return (fAttributes & attribute) == attribute;
	}

	/**
	 * Does this comment range contain a closing HTML tag?
	 * 
	 * @param token token belonging to the comment range
	 * @param tag the HTML tag to check
	 * @return <code>true</code> iff this comment range contains a closing
	 *         html tag, <code>false</code> otherwise
	 */
	protected final boolean isClosingTag(final String token, final String tag) {

		boolean result= token.startsWith(HTML_CLOSE_PREFIX) && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX;
		if (result) {

			setAttribute(COMMENT_CLOSE);
			result= token.substring(HTML_CLOSE_PREFIX.length(), token.length() - 1).equals(tag);
		}
		return result;
	}

	/**
	 * Does this comment range contain an opening HTML tag?
	 * 
	 * @param token token belonging to the comment range
	 * @param tag the HTML tag to check
	 * @return <code>true</code> iff this comment range contains an
	 *         opening html tag, <code>false</code> otherwise
	 */
	protected final boolean isOpeningTag(final String token, final String tag) {

		boolean result= token.length() > 0 && token.charAt(0) == HTML_TAG_PREFIX && !token.startsWith(HTML_CLOSE_PREFIX) && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX;
		if (result) {

			setAttribute(COMMENT_OPEN);
			result= token.startsWith(tag, 1);
		}
		return result;
	}

	/**
	 * Mark the comment range with the occurred HTML tags.
	 * 
	 * @param tags the HTML tags to test for their occurrence
	 * @param token token belonging to the comment range
	 * @param attribute attribute to set if a HTML tag is present
	 * @param open <code>true</code> iff opening tags should be marked,
	 *                <code>false</code> otherwise
	 * @param close <code>true</code> iff closing tags should be marked,
	 *                <code>false</code> otherwise
	 */
	protected final void markHtmlTag(final String[] tags, final String token, final int attribute, final boolean open, final boolean close) {

		if (token.charAt(0) == HTML_TAG_PREFIX && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX) {

			String tag= null;
			boolean isOpen= false;
			boolean isClose= false;

			for (int index= 0; index < tags.length; index++) {

				tag= tags[index];

				isOpen= isOpeningTag(token, tag);
				isClose= isClosingTag(token, tag);

				if ((open && isOpen) || (close && isClose)) {

					setAttribute(attribute);
					break;
				}
			}
		}
	}

	/**
	 * Mark the comment range with the occurred tags.
	 * 
	 * @param tags the tags to test for their occurrence
	 * @param prefix the prefix which is common to all the tags to test
	 * @param token the token belonging to the comment range
	 * @param attribute attribute to set if a tag is present
	 */
	protected final void markPrefixTag(final String[] tags, final char prefix, final String token, final int attribute) {

		if (token.charAt(0) == prefix) {

			String tag= null;
			for (int index= 0; index < tags.length; index++) {

				tag= tags[index];
				if (token.equals(tag)) {

					setAttribute(attribute);
					break;
				}
			}
		}
	}

	/**
	 * Marks the comment range with the HTML range tag.
	 * 
	 * @param token the token belonging to the comment range
	 * @param tag the HTML tag which confines the HTML range
	 * @param level the nesting level of the current HTML range
	 * @param key the key of the attribute to set if the comment range is in
	 *                the HTML range
	 * @param html <code>true</code> iff the HTML tags in this HTML range
	 *                should be marked too, <code>false</code> otherwise
	 * @return the new nesting level of the HTML range
	 */
	protected final int markTagRange(final String token, final String tag, int level, final int key, final boolean html) {

		if (isOpeningTag(token, tag)) {
			if (level++ > 0)
				setAttribute(key);
		} else if (isClosingTag(token, tag)) {
			if (--level > 0)
				setAttribute(key);
		} else if (level > 0) {
			if (html || !hasAttribute(COMMENT_HTML))
				setAttribute(key);
		}
		return level;
	}

	/**
	 * Moves this comment range.
	 * 
	 * @param delta the delta to move the range
	 */
	public final void move(final int delta) {
		offset += delta;
	}

	/**
	 * Set the attribute <code>attribute</code> to true.
	 * 
	 * @param attribute the attribute to set.
	 */
	protected final void setAttribute(final int attribute) {
		fAttributes |= attribute;
	}

	/**
	 * Trims this comment range at the beginning.
	 * 
	 * @param delta amount to trim the range
	 */
	public final void trimBegin(final int delta) {
		offset += delta;
		length -= delta;
	}

	/**
	 * Trims this comment range at the end.
	 * 
	 * @param delta amount to trim the range
	 */
	public final void trimEnd(final int delta) {
		length += delta;
	}
	
	/*
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		List attributes= new ArrayList();
		if (hasAttribute(COMMENT_BLANKLINE))
			attributes.add("COMMENT_BLANKLINE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_BREAK))
			attributes.add("COMMENT_BREAK"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_CLOSE))
			attributes.add("COMMENT_CLOSE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_CODE))
			attributes.add("COMMENT_CODE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_HTML))
			attributes.add("COMMENT_HTML"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_IMMUTABLE))
			attributes.add("COMMENT_IMMUTABLE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_NEWLINE))
			attributes.add("COMMENT_NEWLINE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_OPEN))
			attributes.add("COMMENT_OPEN"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_PARAGRAPH))
			attributes.add("COMMENT_PARAGRAPH"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_PARAMETER))
			attributes.add("COMMENT_PARAMETER"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_ROOT))
			attributes.add("COMMENT_ROOT"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_SEPARATOR))
			attributes.add("COMMENT_SEPARATOR"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_FIRST_TOKEN))
			attributes.add("COMMENT_FIRST_TOKEN"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER))
			attributes.add("COMMENT_STARTS_WITH_RANGE_DELIMITER"); //$NON-NLS-1$
		
		StringBuffer buf= new StringBuffer("CommentRange [" + offset + "+" + length + "] {"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		for (Iterator it= attributes.iterator(); it.hasNext();) {
			String string= (String) it.next();
			buf.append(string);
			if (it.hasNext())
				buf.append(", "); //$NON-NLS-1$
		}
		
		return buf.toString() + "}"; //$NON-NLS-1$
	}
}
