/*******************************************************************************
 * Copyright (c) 2001, 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.actions;

import java.util.ResourceBundle;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.TextEditorAction;
import org.eclipse.wst.sse.core.IModelManager;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.ui.edit.util.StructuredTextEditorActionConstants;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;

public class CommentActionXML extends TextEditorAction {
	protected static final String CLOSE_COMMENT = "-->"; //$NON-NLS-1$
	protected static final String OPEN_COMMENT = "<!--"; //$NON-NLS-1$

	static IModelManager getModelManager() {
		return StructuredModelManager.getInstance().getModelManager();
	}

	protected IDocument fDocument;
	protected IStructuredModel fModel;
	protected ITextSelection fSelection;
	protected int fSelectionEndLine;
	protected int fSelectionEndLineOffset;
	protected int fSelectionEndOffset;
	protected Position fSelectionPosition;
	protected int fSelectionStartLine;
	protected int fSelectionStartLineOffset;
	protected int fSelectionStartOffset;
	protected boolean fUpdateSelection;


	public CommentActionXML(ResourceBundle bundle, String prefix, ITextEditor editor) {
		super(bundle, prefix, editor);
	}

	protected void comment(int openCommentOffset, int closeCommentOffset) {
		try {
			fDocument.replace(openCommentOffset, 0, OPEN_COMMENT);
			fDocument.replace(closeCommentOffset, 0, CLOSE_COMMENT);
			removeOpenCloseComments(openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
		}
		catch (BadLocationException e) {
			throw new SourceEditingRuntimeException();
		}
	}

	/**
	 * Release the current model
	 */
	void done() {
		if (fModel != null) {
			fModel.releaseFromEdit();
			fModel = null;
		}
	}

	protected ITextSelection getCurrentSelection() {
		ITextEditor editor = getTextEditor();
		if (editor != null) {
			ISelectionProvider provider = editor.getSelectionProvider();
			if (provider != null) {
				ISelection selection = provider.getSelection();
				if (selection instanceof ITextSelection)
					return (ITextSelection) selection;
			}
		}
		return TextSelection.emptySelection();
	}

	protected void init() {
		ITextEditor editor = getTextEditor();
		if (editor == null)
			return;

		IDocumentProvider docProvider = editor.getDocumentProvider();

		IEditorInput input = editor.getEditorInput();
		if (input == null)
			return;

		fDocument = docProvider.getDocument(input);
		if (fDocument == null)
			return;

		IModelManager modelManager = getModelManager();
		fModel = modelManager.getExistingModelForEdit(fDocument);
		if (fModel == null)
			return;

		fSelection = getCurrentSelection();
		if (fSelection.isEmpty())
			return;

		fSelectionStartOffset = fSelection.getOffset();
		fSelectionEndOffset = fSelectionStartOffset + fSelection.getLength();

		// add selection position to document
		fSelectionPosition = new Position(fSelection.getOffset(), fSelection.getLength());
		try {
			fDocument.addPosition(fSelectionPosition);
		}
		catch (BadLocationException e) {
			throw new SourceEditingRuntimeException();
		}

		try {
			fSelectionStartLine = fDocument.getLineOfOffset(fSelectionStartOffset);
			fSelectionEndLine = fDocument.getLineOfOffset(fSelectionEndOffset);
			fSelectionStartLineOffset = fDocument.getLineOffset(fSelectionStartLine);
			fSelectionEndLineOffset = fDocument.getLineOffset(fSelectionEndLine);
		}
		catch (BadLocationException e) {
			throw new SourceEditingRuntimeException();
		}

		// adjust selection end line
		if (fSelectionEndLine > fSelectionStartLine && fSelectionEndLineOffset == fSelectionEndOffset)
			fSelectionEndLine--;
	}

	protected boolean isCommentLine(int line) {
		try {
			IRegion region = fDocument.getLineInformation(line);
			String string = fDocument.get(region.getOffset(), region.getLength()).trim();
			return string.length() >= OPEN_COMMENT.length() + CLOSE_COMMENT.length() && string.startsWith(OPEN_COMMENT) && string.endsWith(CLOSE_COMMENT);
		}
		catch (BadLocationException e) {
			throw new SourceEditingRuntimeException();
		}
	}

	protected void prepareSelection() {
		fUpdateSelection = fSelection.getLength() > 0 && fSelectionStartLineOffset == fSelectionStartOffset && !isCommentLine(fSelectionStartLine);
	}

	protected void processAction() {
		fModel.beginRecording(this, SSEUIPlugin.getResourceString(StructuredTextEditorActionConstants.ACTION_NAME_COMMENT + ".tooltip")); //$NON-NLS-1$
		fModel.aboutToChangeModel();

		for (int i = fSelectionStartLine; i <= fSelectionEndLine; i++) {
			try {
				if (fDocument.getLineLength(i) > 0 && !isCommentLine(i)) {
					int openCommentOffset = fDocument.getLineOffset(i);
					int lineDelimiterLength = fDocument.getLineDelimiter(i) == null ? 0 : fDocument.getLineDelimiter(i).length();
					int closeCommentOffset = openCommentOffset + fDocument.getLineLength(i) - lineDelimiterLength + OPEN_COMMENT.length();
					comment(openCommentOffset, closeCommentOffset);
				}
			}
			catch (BadLocationException e) {
				throw new SourceEditingRuntimeException();
			}
		}

		fModel.changedModel();
		fModel.endRecording(this);
	}

	protected void removeOpenCloseComments(int offset, int length) {
		try {
			int adjusted_length = length;

			// remove open comments
			String string = fDocument.get(offset, length);
			int index = string.lastIndexOf(OPEN_COMMENT);
			while (index != -1) {
				fDocument.replace(offset + index, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
				index = string.lastIndexOf(OPEN_COMMENT, index - 1);
				adjusted_length -= OPEN_COMMENT.length();
			}

			// remove close comments
			string = fDocument.get(offset, adjusted_length);
			index = string.lastIndexOf(CLOSE_COMMENT);
			while (index != -1) {
				fDocument.replace(offset + index, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
				index = string.lastIndexOf(CLOSE_COMMENT, index - 1);
			}
		}
		catch (BadLocationException e) {
			throw new SourceEditingRuntimeException();
		}
	}

	public void run() {
		init();
		prepareSelection();
		processAction();
		updateSelection();
		done();
	}


	protected void setCurrentSelection(ITextSelection selection) {
		ITextEditor editor = getTextEditor();
		if (editor != null) {
			ISelectionProvider provider = editor.getSelectionProvider();
			if (provider != null) {
				provider.setSelection(selection);
			}
		}
	}

	protected void updateSelection() {
		if (fUpdateSelection) {
			ITextSelection selection = new TextSelection(fDocument, fSelectionPosition.getOffset() - OPEN_COMMENT.length(), fSelectionPosition.getLength() + OPEN_COMMENT.length());
			setCurrentSelection(selection);
		}
	}
}
