/*******************************************************************************
 * 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.handlers;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
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.swt.widgets.Display;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.comment.BlockCommentingStrategy;
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy;
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategyRegistry;
import org.eclipse.wst.sse.ui.internal.comment.LineCommentingStrategy;

/**
 * <p>A comment handler to toggle line comments, this means that if a
 * comment already exists on a line then toggling it will remove the comment,
 * if the line in question is not already commented then it will not be commented.
 * If multiple lines are selected each will be commented separately.  The handler
 * first attempts to find a {@link LineCommentingStrategy} for a line, if it can
 * not find one then it will try and find a {@link BlockCommentingStrategy} to
 * wrap just that line in.</p>
 * 
 * <p>If a great number of lines are being toggled then a progress dialog will be
 * displayed because this can be a timely process</p>
 */
public final class ToggleLineCommentHandler extends AbstractCommentHandler {
	/** if toggling more then this many lines then use a busy indicator */
	private static final int TOGGLE_LINES_MAX_NO_BUSY_INDICATOR = 10;
	
	/**
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(
	 * 	org.eclipse.ui.texteditor.ITextEditor, org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument,
	 * 	org.eclipse.jface.text.ITextSelection)
	 */
	protected void processAction(ITextEditor textEditor,
			final IStructuredDocument document, ITextSelection textSelection) {
		
		IStructuredModel model = null;
		DocumentRewriteSession session = null;
		boolean changed = false;
		
		try {
			// get text selection lines info
			int selectionStartLine = textSelection.getStartLine();
			int selectionEndLine = textSelection.getEndLine();
			
			int selectionEndLineOffset = document.getLineOffset(selectionEndLine);
			int selectionEndOffset = textSelection.getOffset() + textSelection.getLength();

			// adjust selection end line
			if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) {
				selectionEndLine--;
			}

			// save the selection position since it will be changing
			Position selectionPosition = null;
			selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength());
			document.addPosition(selectionPosition);

			
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
			if (model != null) {
				//makes it so one undo will undo all the edits to the document
				model.beginRecording(this, SSEUIMessages.ToggleComment_label, SSEUIMessages.ToggleComment_description);
				
				//keeps listeners from doing anything until updates are all done
				model.aboutToChangeModel();
				if(document instanceof IDocumentExtension4) {
					session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
				}
				changed = true;
				
				//get the display for the editor if we can
				Display display = null;
				if(textEditor instanceof StructuredTextEditor) {
					StructuredTextViewer viewer = ((StructuredTextEditor)textEditor).getTextViewer();
					if(viewer != null) {
						display = viewer.getControl().getDisplay();
					}
				}
				
				//create the toggling operation
				IRunnableWithProgress toggleCommentsRunnable = new ToggleLinesRunnable(
						model.getContentTypeIdentifier(), document, selectionStartLine, selectionEndLine, display);
				
				//if toggling lots of lines then use progress monitor else just run the operation
				if((selectionEndLine - selectionStartLine) > TOGGLE_LINES_MAX_NO_BUSY_INDICATOR && display != null) {
					ProgressMonitorDialog dialog = new ProgressMonitorDialog(display.getActiveShell());
					dialog.run(false, true, toggleCommentsRunnable);
				} else {
					toggleCommentsRunnable.run(new NullProgressMonitor());
				}
			}
		} catch (InvocationTargetException e) {
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
		} catch (InterruptedException e) {
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
		} catch (BadLocationException e) {
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
		} finally {
			//clean everything up
			if(session != null && document instanceof IDocumentExtension4) {
				((IDocumentExtension4)document).stopRewriteSession(session);
			}
			
			if(model != null) {
				model.endRecording(this);
				if(changed) {
					model.changedModel();
				}
				model.releaseFromEdit();
			}
		}
	}
	
	/**
	 * <p>The actual line toggling takes place in a runnable so it can be
	 * run as part of a progress dialog if there are many lines to toggle
	 * and thus the operation will take a noticeable amount of time the user
	 * should be aware of, this also allows for the operation to be canceled 
	 * by the user</p>
	 * 
	 */
	private static class ToggleLinesRunnable implements IRunnableWithProgress {
		/** the content type for the document being commented */
		private String fContentType;
		
		/** the document that the lines will be toggled on */
		private IStructuredDocument fDocument;
		
		/** the first line in the document to toggle */
		private int fSelectionStartLine;
		
		/** the last line in the document to toggle */
		private int fSelectionEndLine;
		
		/** the display, so that it can be updated during a long operation */
		private Display fDisplay;
		
		/**
		 * @param model {@link IStructuredModel} that the lines will be toggled on
		 * @param document {@link IDocument} that the lines will be toggled on
		 * @param selectionStartLine first line in the document to toggle
		 * @param selectionEndLine last line in the document to toggle
		 * @param display {@link Display}, so that it can be updated during a long operation
		 */
		protected ToggleLinesRunnable(String contentTypeIdentifier, IStructuredDocument document,
				int selectionStartLine, int selectionEndLine, Display display) {
			
			this.fContentType = contentTypeIdentifier;
			this.fDocument = document;
			this.fSelectionStartLine = selectionStartLine;
			this.fSelectionEndLine = selectionEndLine;
			this.fDisplay = display;
		}
		
		/**
		 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		public void run(IProgressMonitor monitor) {
			//start work
			monitor.beginTask(SSEUIMessages.ToggleComment_progress,
					this.fSelectionEndLine-this.fSelectionStartLine);
			try {
				//toggle each line so long as task not canceled
				for (int line = this.fSelectionStartLine;
						line <= this.fSelectionEndLine && !monitor.isCanceled(); ++line) {
					
					//allows the user to be able to click the cancel button
					readAndDispatch(this.fDisplay);
					
					//get the line region
					IRegion lineRegion = this.fDocument.getLineInformation(line);
					
					//don't toggle empty lines
					String content = this.fDocument.get(lineRegion.getOffset(), lineRegion.getLength());
					if (content.trim().length() > 0) {
						//try to get a line comment type
						ITypedRegion[] lineTypedRegions =
							this.fDocument.computePartitioning(lineRegion.getOffset(), lineRegion.getLength());
						CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getLineCommentingStrategy(
								this.fContentType, lineTypedRegions);
						
						//could not find line comment type so find block comment type to use on line
						if(commentType == null) {
							commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(
									this.fContentType, lineTypedRegions);
						}
						
						//toggle the comment on the line
						if(commentType != null) {
							if(commentType.alreadyCommenting(this.fDocument, lineTypedRegions)) {
								commentType.remove(this.fDocument, lineRegion.getOffset(), lineRegion.getLength(), true);
							} else {
								commentType.apply(this.fDocument, lineRegion.getOffset(), lineRegion.getLength());
							}
						}
					}
					monitor.worked(1);
				}
			} catch(BadLocationException e) {
				Logger.logException("Bad location while toggling comments.", e);  //$NON-NLS-1$
			}
			//done work
			monitor.done();
		}
		
		/**
		 * <p>When calling {@link Display#readAndDispatch()} the game is off as to whose code you maybe
		 * calling into because of event handling/listeners/etc.  The only important thing is that
		 * the UI has been given a chance to react to user clicks.  Thus the logging of most {@link Exception}s
		 * and {@link Error}s as caused by {@link Display#readAndDispatch()} because they are not caused
		 * by this code and do not effect it.</p>
		 * 
		 * @param display the {@link Display} to call <code>readAndDispatch</code>
		 * on with exception/error handling.
		 */
		private void readAndDispatch(Display display) {
			try {
				display.readAndDispatch();
			}
			catch (Exception e) {
				Logger.log(Logger.WARNING,
						"Exception caused by readAndDispatch, not caused by or fatal to caller", e);
			}
			catch (LinkageError e) {
				Logger.log(Logger.WARNING,
						"LinkageError caused by readAndDispatch, not caused by or fatal to caller", e);
			}
			catch (VirtualMachineError e) {
				// re-throw these
				throw e;
			}
			catch (ThreadDeath e) {
				// re-throw these
				throw e;
			}
			catch (Error e) {
				// catch every error, except for a few that we don't want to handle
				Logger.log(Logger.WARNING,
						"Error caused by readAndDispatch, not caused by or fatal to caller", e);
			}
		}
	}
}
