/*******************************************************************************
 * Copyright (c) 2010 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.wst.sse.ui.internal.comment;

import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.ui.internal.Logger;

/**
 * <p>Represents a Block Comment commenting strategy</p>
 */
public class BlockCommentingStrategy extends CommentingStrategy {
	/** the prefix of the block comment associated with this strategy */
	private String fPrefix;
	
	/** the suffix of the block comment associated with this strategy */
	private String fSuffix;
	
	/**
	 * @param prefix the prefix of the block comment associated with this strategy
	 * @param suffix the suffix of the block comment associated with this strategy
	 */
	public BlockCommentingStrategy(String prefix, String suffix) {
		super();
		this.fPrefix = prefix;
		this.fSuffix = suffix;
	}

	/**
	 * <p>When applying a block comment it also removes any block comments associated
	 * with this strategy that would now be enclosed by the new block comment</p>
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#apply(
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int)
	 */
	public void apply(IStructuredDocument document, int offset, int length) throws BadLocationException {
		int commentPrefixOffset = offset;
		int commentSuffixOffset = commentPrefixOffset + length;
		
		try {
			document.replace(commentSuffixOffset, 0, " " + this.fSuffix); //$NON-NLS-1$
			this.remove(document, commentPrefixOffset + this.fPrefix.length(), length, false);
			document.replace(commentPrefixOffset, 0, this.fPrefix + " "); //$NON-NLS-1$
		}
		catch (BadLocationException e) {
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#remove(
	 * 	org.eclipse.jface.text.IDocument, int, int)
	 */
	public void remove(IStructuredDocument document, int offset, int length, boolean removeEnclosing) throws BadLocationException {
		IRegion region = new Region(offset, length);
		ITypedRegion[] typedRegions = document.computePartitioning(region.getOffset(), region.getLength());
		List commentRegions = this.getAssociatedCommentedRegions(typedRegions);
		
		//remove in reverse order as to not effect offset of other regions
		for(int i = commentRegions.size()-1; i >= 0; --i) {
			try {
				//get the comment region
				ITypedRegion typedRegion = (ITypedRegion)commentRegions.get(i);
				IRegion commentRegion = new Region(typedRegion.getOffset(), typedRegion.getLength());

				/* because of the nature of structured regions the comment region could actually be a
				 * sub region that needs to be drilled down too
				 */
				if(!this.alreadyCommenting(document, commentRegion)) {
					IStructuredDocumentRegion structuredRegion =
						document.getRegionAtCharacterOffset(commentRegion.getOffset());
					
					commentRegion = new Region(structuredRegion.getStartOffset(), structuredRegion.getLength());
					
					if(!this.alreadyCommenting(document, commentRegion)) {
						ITextRegion enclosedRegion = structuredRegion.getRegionAtCharacterOffset(typedRegion.getOffset());
						int enclosedOffset = structuredRegion.getStartOffset(enclosedRegion);
						commentRegion = new Region(enclosedOffset, structuredRegion.getTextEndOffset(enclosedRegion)-enclosedOffset);
					}
				}
				
				//at this point should have found the comment region, if not there is an issue
				if(this.alreadyCommenting(document, commentRegion)) {
					String regionContent = document.get(commentRegion.getOffset(), commentRegion.getLength());
					
					//if found the comment prefix and suffix then uncomment, otherwise log error
					int commentPrefixOffset = commentRegion.getOffset() + regionContent.indexOf(this.fPrefix);
					int commentSuffixOffset = commentRegion.getOffset();
					commentSuffixOffset += regionContent.lastIndexOf(this.fSuffix);
					
					//remove comment block depending on if its an enclosing comment block and weather that is allowed
					if(removeEnclosing || (commentPrefixOffset >= offset && commentSuffixOffset <= offset+length)) {
						uncomment(document, commentPrefixOffset, this.fPrefix, commentSuffixOffset, this.fSuffix);
					}
				} else {
					Logger.log(Logger.ERROR,
							"BlockCommentingStrategy#remove could not find the commenting region to remove"); //$NON-NLS-1$
				}
			} catch(BadLocationException e) {
				Logger.logException("This should only ever happen if something has gone wrong with the partitioning", e); //$NON-NLS-1$
			}
		}
	}
	
	/**
	 * <p>A region is already commented by this strategy if it starts with the strategy's associated
	 * prefix and ends with its associated suffix, ignoring any trailing or leading whitespace</p>
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#alreadyCommenting(
	 * 	org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IRegion)
	 */
	public boolean alreadyCommenting(IStructuredDocument document, IRegion region) throws BadLocationException {
		String regionContent = document.get(region.getOffset(), region.getLength()).trim();
		return regionContent.startsWith(this.fPrefix) && regionContent.endsWith(this.fSuffix);
	}
	
	/**
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#clone()
	 */
	public Object clone() {
		return new BlockCommentingStrategy(this.fPrefix, this.fSuffix);
	}
}