/*******************************************************************************
 * Copyright (c) 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.wst.common.snippets.ui;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.common.snippets.core.ISnippetItem;
import org.eclipse.wst.common.snippets.internal.Logger;
import org.eclipse.wst.common.snippets.internal.SnippetsPlugin;
import org.eclipse.wst.common.snippets.internal.VariableItemHelper;
import org.eclipse.wst.common.snippets.internal.dnd.SnippetTextTransfer;
import org.eclipse.wst.common.snippets.internal.ui.EntrySerializer;
import org.eclipse.wst.common.snippets.internal.util.StringUtils;

/**
 * An insertion implementation that supports ISnippetVariables. The content
 * string of the item can contain markers, in the form ${+variable+}, that
 * will be replaced with user-supplied values at insertion time.
 * <p>
 * Clients may subclass this class.
 * </p>
 * @since 1.0
 */
public class DefaultSnippetInsertion implements ISnippetInsertion {
	private ISnippetItem fItem = null;
	private Transfer[] fSupportedTransfers = null;

	/**
	 * Default constructor. Subclasses may call, but only the Snippets view
	 * should ever instantiate an insertion.
	 */
	public DefaultSnippetInsertion() {
		super();
	}

	/**
	 * @return an array of Transfer types supported by this insertion
	 */
	protected Transfer[] createTransfers() {
		return new Transfer[]{SnippetTextTransfer.getTransferInstance(), TextTransfer.getInstance()};
	}

	/**
	 * Insert the current snippet item.
	 * 
	 * @param editorPart
	 *            the editor part that is active
	 * @param textEditor
	 *            the text editor (or adapter) with which to interact (may be
	 *            the same as editorPart)
	 * @param document
	 *            the text document to update
	 * @param textSelection
	 *            the selection of text within the document to be replaced by
	 *            the inserted snippet
	 * @throws BadLocationException
	 */
	protected void doInsert(IEditorPart editorPart, ITextEditor textEditor, IDocument document, ITextSelection textSelection) throws BadLocationException {
		String replacement = getInsertString(editorPart.getEditorSite().getShell());
		if (replacement != null && (replacement.length() > 0 || textSelection.getLength() > 0)) {
			// Update EOLs (bug 80231)
			replacement = StringUtils.replace(replacement, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			replacement = StringUtils.replace(replacement, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$

			String preferredEOL = null;
			if (document instanceof IDocumentExtension4) {
				preferredEOL = ((IDocumentExtension4) document).getDefaultLineDelimiter();
			}
			else {
				Method getLineDelimiter = null;
				try {
					getLineDelimiter = document.getClass().getMethod("getLineDelimiter", new Class[0]); //$NON-NLS-1$
				}
				catch (NoSuchMethodException e) {
					// nothing, not unusual
				}
				if (getLineDelimiter != null) {
					try {
						preferredEOL = (String) getLineDelimiter.invoke(document, new Object[0]);
					}
					catch (IllegalAccessException e) {
						// nothing, not unusual for a non-visible method
					}
					catch (InvocationTargetException e) {
						// nothing, not unusual for a protected implementation
					}
				}

			}
			if (preferredEOL == null) {
				preferredEOL = System.getProperty("line.separator"); //$NON-NLS-1$
			}
			if (!"\n".equals(preferredEOL) && preferredEOL != null) { //$NON-NLS-1$
				replacement = StringUtils.replace(replacement, "\n", preferredEOL); //$NON-NLS-1$
			}

			document.replace(textSelection.getOffset(), textSelection.getLength(), replacement);
		}
	}

	public void dragSetData(DragSourceEvent event, ISnippetItem item) {
		boolean isSimpleText = TextTransfer.getInstance().isSupportedType(event.dataType);
		if (isSimpleText) {
			// set variable values to ""
			IWorkbenchWindow window = SnippetsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
			Shell shell = null;
			if (window != null) {
				shell = window.getShell();
			}
			String content = VariableItemHelper.getInsertString(shell, item);
			// Update EOLs (bug 80231)
			String systemEOL = System.getProperty("line.separator"); //$NON-NLS-1$
			content = StringUtils.replace(content, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			content = StringUtils.replace(content, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
			if (!"\n".equals(systemEOL) && systemEOL != null) { //$NON-NLS-1$
				content = StringUtils.replace(content, "\n", systemEOL); //$NON-NLS-1$
			}
			event.data = content;
		}
		else {
			/*
			 * All complex insertions send an XML encoded version of the item
			 * itself as the data. The drop action must use this to prompt the
			 * user for the correct insertion data
			 */
			event.data = EntrySerializer.getInstance().toXML(item);
		}
	}

	/**
	 * Gets the string to be inserted by interacting further with the user if
	 * needed.
	 * 
	 * @param host
	 *            Shell to use for creating dialogs
	 * @return the string to be inserted
	 */
	protected String getInsertString(Shell host) {
		if (fItem == null)
			return ""; //$NON-NLS-1$
		String insertString = null;
		if (fItem.getVariables().length > 0) {
			insertString = VariableItemHelper.getInsertString(host, fItem);
		}
		else {
			insertString = StringUtils.replace(fItem.getContentString(), "${cursor}", ""); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (insertString == null)
			insertString = "";
		return insertString;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#getTransfers()
	 */
	public Transfer[] getTransfers() {
		if (fSupportedTransfers == null)
			fSupportedTransfers = createTransfers();
		return fSupportedTransfers;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#insert(org.eclipse.ui.IEditorPart)
	 */
	public void insert(IEditorPart editorPart) {
		if (editorPart == null)
			return;
		ITextEditor textEditor = null;

		if (editorPart instanceof ITextEditor) {
			textEditor = (ITextEditor) editorPart;
		}
		if (textEditor == null) {
			// MultiPageEditorPart has no accessors for the source
			textEditor = (ITextEditor) editorPart.getAdapter(ITextEditor.class);
		}
		if (textEditor == null) {
			// any errors here probably aren't really exceptional
			Method getTextEditor = null;
			try {
				getTextEditor = editorPart.getClass().getMethod("getTextEditor", new Class[0]); //$NON-NLS-1$
			}
			catch (NoSuchMethodException e) {
				// nothing, not unusual
			}
			Object editor = null;
			if (getTextEditor != null) {
				try {
					editor = getTextEditor.invoke(editorPart, new Object[0]);
				}
				catch (IllegalAccessException e) {
					// nothing, not unusual for a non-visible method
				}
				catch (InvocationTargetException e) {
					// nothing, not unusual for a protected implementation
				}
				if (editor instanceof IEditorPart && editor != editorPart && editor instanceof ITextEditor) {
					textEditor = (ITextEditor) editor;
				}
			}
		}
		if (textEditor != null) {
			insertIntoTextEditor(textEditor);
		}
	}

	private void insertIntoTextEditor(ITextEditor editor) {
		// find the text widget, its Document, and the current selection
		if (editor.isEditable()) {
			IDocumentProvider docprovider = editor.getDocumentProvider();
			ISelectionProvider selprovider = editor.getSelectionProvider();
			if (docprovider != null && selprovider != null) {
				IDocument document = docprovider.getDocument(editor.getEditorInput());
				ISelection selection = selprovider.getSelection();
				if (document != null && selection != null && selection instanceof ITextSelection) {
					ITextSelection textSel = (ITextSelection) selection;
					try {
						doInsert(editor, editor, document, textSel);
					}
					catch (Exception t) {
						Logger.logException("Could not insert " + fItem, t); //$NON-NLS-1$
						editor.getSite().getShell().getDisplay().beep();
					}
				}
			}
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#setEditorPart(org.eclipse.ui.IEditorPart)
	 */
	public void setEditorPart(IEditorPart editorPart) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.snippets.ui.ISnippetInsertion#setItem(org.eclipse.wst.common.snippets.core.ISnippetItem)
	 */
	public void setItem(ISnippetItem item) {
		fItem = item;
	}
}