/*******************************************************************************
 * Copyright (c) 2004, 2011 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.internal.ui;

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

import org.eclipse.core.runtime.Platform;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.palette.DefaultPaletteViewerPreferences;
import org.eclipse.gef.ui.palette.PaletteContextMenuProvider;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gef.ui.palette.PaletteViewerPreferences;
import org.eclipse.gef.ui.palette.customize.PaletteCustomizerDialog;
import org.eclipse.gef.ui.parts.PaletteViewerKeyHandler;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.util.TransferDragSourceListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.wst.common.snippets.core.ISnippetCategory;
import org.eclipse.wst.common.snippets.core.ISnippetItem;
import org.eclipse.wst.common.snippets.core.ISnippetsEntry;
import org.eclipse.wst.common.snippets.internal.IHelpContextIds;
import org.eclipse.wst.common.snippets.internal.Logger;
import org.eclipse.wst.common.snippets.internal.PluginRecord;
import org.eclipse.wst.common.snippets.internal.SnippetDefinitions;
import org.eclipse.wst.common.snippets.internal.SnippetTransfer;
import org.eclipse.wst.common.snippets.internal.SnippetsMessages;
import org.eclipse.wst.common.snippets.internal.SnippetsPlugin;
import org.eclipse.wst.common.snippets.internal.SnippetsPluginImageHelper;
import org.eclipse.wst.common.snippets.internal.SnippetsPluginImages;
import org.eclipse.wst.common.snippets.internal.actions.DeleteCategoryAction;
import org.eclipse.wst.common.snippets.internal.actions.DeleteItemAction;
import org.eclipse.wst.common.snippets.internal.model.SnippetManager;
import org.eclipse.wst.common.snippets.internal.palette.SnippetCustomizerDialog;
import org.eclipse.wst.common.snippets.internal.palette.SnippetPaletteDrawer;
import org.eclipse.wst.common.snippets.internal.palette.SnippetPaletteItem;
import org.eclipse.wst.common.snippets.internal.palette.SnippetPaletteItemFactory;
import org.eclipse.wst.common.snippets.internal.palette.SnippetPaletteRoot;
import org.eclipse.wst.common.snippets.internal.util.UserDrawerSelector;
import org.eclipse.wst.common.snippets.internal.util.VisibilityUtil;
import org.eclipse.wst.common.snippets.ui.DefaultSnippetInsertion;
import org.eclipse.wst.common.snippets.ui.ISnippetInsertion;
import org.osgi.framework.Bundle;

public class SnippetsView extends ViewPart {

	protected class CopyAction extends Action {
		public CopyAction() {
			super(SnippetsMessages.Copy_2);
			setImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_ELCL_COPY));
			setHoverImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_CLCL_COPY));
			setDisabledImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_DLCL_COPY));
			setToolTipText(getText());
		}

		public void run() {
			super.run();
			byte[] stringData = EntrySerializer.getInstance().toXML(getSelectedEntry());
			getClipboard().setContents(new Object[]{stringData, getSelectedEntry().getLabel()}, new Transfer[]{SnippetTransfer.getTransferInstance(), TextTransfer.getInstance()});
		}
	}

	protected class CutAction extends Action {
		public CutAction() {
			super(SnippetsMessages.Cut_2);
			setImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_ELCL_CUT));
			setHoverImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_CLCL_CUT));
			setDisabledImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_DLCL_CUT));
			setToolTipText(getText());
		}

		public void run() {
			super.run();
			getCopyAction().run();
			getDeleteAction().run();
			SnippetsView.this.save();
		}
	}

	protected class DeleteAction extends Action {
		public DeleteAction() {
			super(SnippetsMessages.Delete_1);
			setImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_ELCL_DELETE));
			setHoverImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_CLCL_DELETE));
			setDisabledImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_DLCL_DELETE));
			setToolTipText(getText());
		}

		public void run() {
			super.run();
			if (getSelectedEntry() instanceof PaletteContainer)
				new DeleteCategoryAction(SnippetsView.this, (PaletteContainer) getSelectedEntry()).run();
			else if (getSelectedEntry() instanceof PaletteEntry)
				new DeleteItemAction(getViewer(), (PaletteEntry) getSelectedEntry()).run();
			SnippetsView.this.save();
		}
	}

	protected class InsertAction extends Action {
		public InsertAction() {
			super(SnippetsMessages.Insert___);
			setImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_ELCL_INSERT));
			setHoverImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_CLCL_INSERT));
			setDisabledImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_DLCL_INSERT));
			setToolTipText(getText());
			setAccelerator(SWT.CTRL | SWT.CR);
		}

		public void run() {
			super.run();
			insert();
		}
	}

	class InsertionHelper {
		protected InsertionHelper() {
			super();
		}

		protected ISnippetInsertion getInsertion(SnippetPaletteItem item) {
			ISnippetInsertion insertion = null;
			String className = item.getClassName();

			PluginRecord record = null;
			if (item.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_PLUGINS)
				record = (PluginRecord) item.getSourceDescriptor();
			// ignore the version
			if (record != null && record.getPluginName() != null && className != null) {
				Class theClass = null;
				Bundle bundle = Platform.getBundle(record.getPluginName());
				try {
					if (className != null && className.length() > 0)
						theClass = bundle.loadClass(className);
				}
				catch (ClassNotFoundException e) {
					try { // maybe it's local???
						theClass = Class.forName(className);
					}
					catch (ClassNotFoundException f) {
						Logger.logException("Could not load Insertion class", e); //$NON-NLS-1$
					}
					if (theClass == null)
						Logger.logException("Could not load Insertion class", e); //$NON-NLS-1$
				}
				if (theClass != null) {
					try {
						insertion = (ISnippetInsertion) theClass.newInstance();
					}
					catch (IllegalAccessException e) {
						Logger.logException("Could not access Insertion class", e); //$NON-NLS-1$
					}
					catch (InstantiationException e) {
						Logger.logException("Could not instantiate Insertion class", e); //$NON-NLS-1$
					}
				}
			}
			 
			if (insertion == null) {
				if (item.getProvider()!= null){
					insertion = item.getProvider().getSnippetInsertion();
				} else {
					insertion = new DefaultSnippetInsertion();
				}
			}
			return insertion;
		}

		public boolean insert(SnippetPaletteItem item, IEditorPart editorPart) {
			ISnippetInsertion insertion = getInsertion(item);
			if (insertion != null) {
				insertion.setItem(item);
				insertion.insert(editorPart);
				return true;
			}
			return false;
		}
	}

	protected class InsertMouseListener extends MouseAdapter {
		public void mouseDoubleClick(MouseEvent e) {
			// doesn't detect if hitpoint is on internal scrollbars
			if (e.button == 1) {
				EditPart part = SnippetsView.this.getViewer().findObjectAt(new Point(e.x, e.y));
				SnippetPaletteItem item = null;
				if (part != null) {
					if (part.getModel() instanceof SnippetPaletteItem)
						item = (SnippetPaletteItem) part.getModel();
				}
				if (item != null)
					insert(item);
			}
		}

	}

	private final class PartActivationListener implements IPartListener {
		public void partActivated(IWorkbenchPart part) {
			if (part instanceof IEditorPart) {
				IEditorPart editorPart = (IEditorPart) part;
				IEditorInput input = editorPart.getEditorInput();
				if (input.getName() != null) {
					SnippetDefinitions snippetDefinitions = SnippetManager.getInstance().getDefinitions();
					List categories = snippetDefinitions.getCategories();
					for (Iterator iter = categories.iterator(); iter.hasNext();) {
						SnippetPaletteDrawer drawer = (SnippetPaletteDrawer) iter.next();
						String[] filters = drawer.getFilters();
						boolean drawerVisibility = VisibilityUtil.isContentType(input, filters);
						drawer.setVisible(drawerVisibility);
					}
				}
			}
		}

		public void partBroughtToTop(IWorkbenchPart part) {
			// do nothing
		}

		public void partClosed(IWorkbenchPart part) {
			updateActions(getSelectedEntry());
		}

		public void partDeactivated(IWorkbenchPart part) {
			// do nothing
		}

		public void partOpened(IWorkbenchPart part) {
			updateActions(getSelectedEntry());
		}
	}

	protected class PasteAction extends Action {
		public PasteAction() {
			super(SnippetsMessages.Paste_4);
			setImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_ELCL_PASTE));
			setHoverImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_CLCL_PASTE));
			setDisabledImageDescriptor(SnippetsPluginImageHelper.getInstance().getImageDescriptor(SnippetsPluginImages.IMG_DLCL_PASTE));
			setToolTipText(getText());
		}

		protected String getFirstLine(String text) {
			if (text == null || text.length() < 1) {
				return text;
			}
			IDocument doc = new Document(text);
			try {
				int lineNumber = doc.getLineOfOffset(0);
				IRegion line = doc.getLineInformation(lineNumber);
				return doc.get(line.getOffset(), line.getLength());
			}
			catch (BadLocationException e) {
				// do nothing
			}
			return text;
		}

		protected void launchCustomizer(PaletteEntry entry) {
			PaletteCustomizerDialog dialog = getViewer().getCustomizerDialog();
			if (!(entry instanceof PaletteRoot)) {
				dialog.setDefaultSelection(entry);
			}
			dialog.open();
		}

		public void run() {
			super.run();
			byte[] itemDefinition = (byte[]) getClipboard().getContents(SnippetTransfer.getTransferInstance());
			if (itemDefinition != null) {
				ISnippetsEntry entry = EntryDeserializer.getInstance().fromXML(itemDefinition);
				ISnippetsEntry destination = getSelectedEntry();
				// if the selected entry isn't user owned
				if (destination == null || destination.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_PLUGINS) {
					UserDrawerSelector selector = new UserDrawerSelector(getSite().getShell());
					selector.setSelectionPrompt(SnippetsMessages.Cant_add_to_this);
					SnippetPaletteDrawer drawer = (SnippetPaletteDrawer) selector.getUserDrawer();
					if (drawer != null)
						destination = drawer;
					else
						return;
				}
				if (entry instanceof SnippetPaletteItem) {
					SnippetPaletteItem item = (SnippetPaletteItem) entry;
					if (destination instanceof SnippetPaletteDrawer) {
						item.setId(((SnippetPaletteDrawer) destination).getId() + System.currentTimeMillis());
						((SnippetPaletteDrawer) destination).add(item);
						EditPart container = (EditPart) getViewer().getEditPartRegistry().get(destination);
						container.refresh();
					}
					else if (destination instanceof ISnippetItem) {
						SnippetPaletteDrawer category = (SnippetPaletteDrawer) ((ISnippetItem) destination).getCategory();
						item.setId("item_" + System.currentTimeMillis()); //$NON-NLS-1$
						category.add(item);
						EditPart container = (EditPart) getViewer().getEditPartRegistry().get(category);
						container.refresh();
					}
					EditPart part = (EditPart) getViewer().getEditPartRegistry().get(item);
					if (part != null)
						getViewer().select(part);
				}
				SnippetsView.this.save();
			}
			else {
				String itemText = (String) getClipboard().getContents(TextTransfer.getInstance());
				if (itemText == null)
					itemText = ""; //$NON-NLS-1$

				ISnippetCategory category = null;
				ISnippetsEntry entry = SnippetsView.this.getSelectedEntry();
				if (entry == null || entry.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_PLUGINS) {
					UserDrawerSelector selector = new UserDrawerSelector(getSite().getShell());
					selector.setSelectionPrompt(SnippetsMessages.Cant_add_to_this);
					SnippetPaletteDrawer drawer = (SnippetPaletteDrawer) selector.getUserDrawer();
					if (drawer != null)
						entry = drawer;
					else
						return;
				}
				if (entry instanceof ISnippetItem)
					category = ((ISnippetItem) SnippetsView.this.getSelectedEntry()).getCategory();
				else if (entry instanceof ISnippetCategory)
					category = (ISnippetCategory) entry;
				if (category == null)
					return;
				SnippetPaletteItem item = (SnippetPaletteItem) new SnippetPaletteItemFactory().createNewEntry(getViewer().getControl().getShell(), (PaletteEntry) category);
				item.setDescription(getFirstLine(itemText));
				item.setContentString(itemText);
				launchCustomizer(item);
			}
		}

		public void update() {
			if (getClipboard().getContents(SnippetTransfer.getTransferInstance()) == null && getClipboard().getContents(TextTransfer.getInstance()) != null) {
				setText(SnippetsMessages.Paste_as_Snippet);
			}
			else {
				setText(SnippetsMessages.Paste_4);
			}
			setToolTipText(getText());
		}
	}

	protected class SnippetsContextMenuListener implements IMenuListener {
		protected PaletteContextMenuProvider baseProvider = null;
		protected IMenuManager manager = null;

		public SnippetsContextMenuListener(MenuManager mgr) {
			this.manager = mgr;
			baseProvider = new PaletteContextMenuProvider(SnippetsView.this.getViewer());
		}

		public void menuAboutToShow(IMenuManager menuManager) {
			SnippetsView.this.fillContextMenu(menuManager);
			baseProvider.buildContextMenu(menuManager);
		}
	}

	protected class TransferDragSourceListenerImpl implements TransferDragSourceListener {
		private Transfer fTransfer;

		public TransferDragSourceListenerImpl(Transfer xfer) {
			fTransfer = xfer;
		}

		public void dragFinished(DragSourceEvent event) {
			if (Logger.DEBUG_DRAG_AND_DROP)
				System.out.println("drag finished"); //$NON-NLS-1$
		}

		public void dragSetData(DragSourceEvent event) {
			if (getSelectedEntry() == null)
				return;
			if (getSelectedEntry() instanceof ISnippetItem) {
				ISnippetInsertion insertion = insertionHelper.getInsertion((SnippetPaletteItem) getSelectedEntry());
				insertion.setEditorPart(getSite().getPage().getActiveEditor());
				insertion.dragSetData(event, (ISnippetItem) getSelectedEntry());
			}
			else {
				if (getSelectedEntry() != null)
					event.data = getSelectedEntry().getLabel();
				else
					event.data = EMPTY_STRING;
			}
		}

		public void dragStart(DragSourceEvent event) {
			if (Logger.DEBUG_DRAG_AND_DROP)
				System.out.println("drag begun"); //$NON-NLS-1$
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.util.TransferDragSourceListener#getTransfer()
		 */
		public Transfer getTransfer() {
			return fTransfer;
		}
	}

	protected Clipboard clipboard = null;

	protected Action copyAction = null;
	protected Action cutAction = null;
	private Action deleteAction;

	private final String EMPTY_STRING = ""; //$NON-NLS-1$
	private PartActivationListener fPartActionUpdateListener = null;
	protected SnippetPaletteRoot fRoot = null;
	protected ISnippetsEntry fSelectedEntry;
	protected ISelectionChangedListener fSelectionChangedListener = null;

	protected List fTransferDragSourceListeners = null;

	protected PaletteViewer fViewer = null;
	protected Action insertAction = null;

	protected InsertionHelper insertionHelper = null;

	protected MouseListener insertListener = new InsertMouseListener();
	protected PasteAction pasteAction = null;

	/**
	 * Constructor for SnippetsView.
	 */
	public SnippetsView() {
		super();
		insertionHelper = new InsertionHelper();
	}

	protected void addTextTransferListener() {
		TransferDragSourceListener listener = new TransferDragSourceListenerImpl(TextTransfer.getInstance());
		getViewer().addDragSourceListener(listener);
		getTransferDragSourceListeners().add(listener);
	}

	private PaletteCustomizerDialog fPaletteCustomizerDialog = null;

	/*
	 * @see IWorkbenchPart#createPartControl(Composite)
	 */
	public void createPartControl(Composite parent) {
		fViewer = new PaletteViewer() {
			public PaletteCustomizerDialog getCustomizerDialog() {
				if (fPaletteCustomizerDialog == null) {
					fPaletteCustomizerDialog = new SnippetCustomizerDialog(getControl().getShell(), getCustomizer(), getPaletteRoot());
				}
				return fPaletteCustomizerDialog;
			}
		};

		fViewer.enableVerticalScrollbar(true);

		fViewer.createControl(parent);

		fViewer.setKeyHandler(new PaletteViewerKeyHandler(fViewer) {
			/* (non-Javadoc)
			 * @see org.eclipse.gef.KeyHandler#keyReleased(org.eclipse.swt.events.KeyEvent)
			 */
			public boolean keyPressed(KeyEvent event) {
				if (event.keyCode == SWT.CR && (event.stateMask & SWT.CTRL) > 0) {
					if (insertAction.isEnabled())
						insertAction.run();
				}
				return super.keyPressed(event);
			}
		});

		DefaultEditDomain domain = new DefaultEditDomain(null);
		fViewer.setEditDomain(domain);

		fillLocalMenu(getViewSite().getActionBars().getMenuManager());
		fillToolBar(getViewSite().getActionBars().getToolBarManager());

		getCopyAction().setEnabled(false);
		getCutAction().setEnabled(false);
		getPasteAction().setEnabled(false);
		getInsertAction().setEnabled(false);

		if (fViewer.getContextMenu() == null)
			fViewer.setContextMenu(new MenuManager("#popup", getClass().getName())); //$NON-NLS-1$
		fViewer.getContextMenu().addMenuListener(new SnippetsContextMenuListener(fViewer.getContextMenu()));
		fViewer.getContextMenu().setRemoveAllWhenShown(true);

		fViewer.setCustomizer(new SnippetsCustomizer());

		PaletteViewerPreferences palettePreferences = new DefaultPaletteViewerPreferences(SnippetsPlugin.getDefault().getPreferenceStore());
		SnippetsPlugin.getDefault().getPreferenceStore().setDefault(PaletteViewerPreferences.PREFERENCE_AUTO_COLLAPSE, PaletteViewerPreferences.COLLAPSE_ALWAYS);
		fViewer.setPaletteViewerPreferences(palettePreferences);

		fViewer.setPaletteRoot(getRoot());

		getViewer().addSelectionChangedListener(getSelectionChangedListener());

		fViewer.getControl().addMouseListener(insertListener);

		PlatformUI.getWorkbench().getHelpSystem().setHelp(getViewer().getControl(), IHelpContextIds.MAIN_VIEW_GENERAL);

		fPartActionUpdateListener = new PartActivationListener();
		getViewSite().getPage().addPartListener(fPartActionUpdateListener);
	}

	protected PaletteRoot createRoot(SnippetDefinitions defs) {
		fRoot = new SnippetPaletteRoot(defs);
		fRoot.connect();
		return fRoot;
	}

	/**
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	public void dispose() {
		super.dispose();
		if (fRoot != null)
			fRoot.disconnect();
		if (clipboard != null)
			clipboard.dispose();
		if (fPartActionUpdateListener != null)
			getViewSite().getPage().removePartListener(fPartActionUpdateListener);
		save();
	}

	protected void fillContextMenu(IMenuManager mgr) {
		ISnippetsEntry entry = null;
		EditPart part = getViewer().getFocusEditPart();
		if (part != null && part.getModel() instanceof ISnippetsEntry)
			entry = (ISnippetsEntry) part.getModel();

		if (entry != null) {
			if (getInsertAction().isEnabled()) {
				mgr.add(getInsertAction());
				mgr.add(new Separator());
			}
			// if (getCutAction().isEnabled())
			mgr.add(getCutAction());
			// if (getCopyAction().isEnabled())
			mgr.add(getCopyAction());
			// if (getPasteAction().isEnabled())
			mgr.add(getPasteAction());
		}
	}

	protected void fillLocalMenu(IMenuManager manager) {
		manager.add(getInsertAction());
		manager.add(new Separator());
		manager.add(getCutAction());
		manager.add(getCopyAction());
		manager.add(getPasteAction());
	}

	protected void fillToolBar(IToolBarManager manager) {
		manager.add(getInsertAction());
	}

	public Object getAdapter(Class adapter) {
		return super.getAdapter(adapter);
	}

	/**
	 * Returns the clipboard.
	 * 
	 * @return Clipboard
	 */
	protected Clipboard getClipboard() {
		if (clipboard == null && getViewer() != null && getViewer().getControl() != null && !getViewer().getControl().isDisposed())
			clipboard = new Clipboard(getViewer().getControl().getDisplay());
		return clipboard;
	}

	// protected CollapseCategoriesAction getCollapseAction() {
	// if(collapseCategoriesAction == null)
	// collapseCategoriesAction = new CollapseCategoriesAction();
	// return collapseCategoriesAction;
	// }

	/**
	 * Returns the copyAction.
	 * 
	 * @return Action
	 */
	public Action getCopyAction() {
		if (copyAction == null) {
			copyAction = new CopyAction();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(copyAction, IHelpContextIds.MENU_COPY_SNIPPET);
		}
		return copyAction;
	}

	/**
	 * Returns the cutAction.
	 * 
	 * @return Action
	 */
	public Action getCutAction() {
		if (cutAction == null) {
			cutAction = new CutAction();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(cutAction, IHelpContextIds.MENU_CUT_SNIPPET);
		}
		return cutAction;
	}

	/**
	 * Returns the deleteAction.
	 * 
	 * @return Action
	 */
	protected Action getDeleteAction() {
		if (deleteAction == null)
			deleteAction = new DeleteAction();
		return deleteAction;
	}

	// public void collapseCategories() {
	// Iterator categories =
	// getRoot().getDefinitions().getCategories().iterator();
	// while (categories.hasNext()) {
	// ISnippetCategory cat = (ISnippetCategory) categories.next();
	// if (!cat.isVisible())
	// continue;
	// GraphicalEditPart catPart = (GraphicalEditPart)
	// fViewer.getEditPartRegistry().get(cat);
	// if (catPart != null && catPart instanceof DrawerEditPart)
	// ((DrawerEditPart) catPart).setExpanded(false);
	// }
	// }

	protected ISnippetsEntry getEntryFromSelection(ISelection selection) {
		if (!selection.isEmpty()) {
			if (selection instanceof IStructuredSelection) {
				Object obj = ((IStructuredSelection) selection).getFirstElement();
				if (obj instanceof EditPart) {
					if (((EditPart) obj).getModel() instanceof ISnippetsEntry)
						return (ISnippetsEntry) ((EditPart) obj).getModel();
				}
				else if (obj instanceof ISnippetsEntry)
					return (ISnippetsEntry) obj;
			}
		}
		return null;
	}

	/**
	 * Returns the insertAction.
	 * 
	 * @return Action
	 */
	public Action getInsertAction() {
		if (insertAction == null)
			insertAction = new InsertAction();
		return insertAction;
	}

	/**
	 * Returns the pasteAction.
	 * 
	 * @return Action
	 */
	public PasteAction getPasteAction() {
		if (pasteAction == null) {
			pasteAction = new PasteAction();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(pasteAction, IHelpContextIds.MENU_PASTE_SNIPPET);
		}
		return pasteAction;
	}

	/**
	 * Gets the model root -- should be identical across all instances
	 * 
	 * @return Returns a SnippetPaletteRoot
	 */
	public SnippetPaletteRoot getRoot() {
		return SnippetManager.getInstance().getPaletteRoot();
	}

	/**
	 * Returns the selected ISnippetsEntry.
	 * 
	 * @return ISnippetsEntry
	 */
	public ISnippetsEntry getSelectedEntry() {
		return fSelectedEntry;
	}

	private ISelectionChangedListener getSelectionChangedListener() {
		if (fSelectionChangedListener == null)
			fSelectionChangedListener = new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					setSelectedEntry(getEntryFromSelection(event.getSelection()));
				}
			};
		return fSelectionChangedListener;
	}

	/**
	 * Returns the transferDragSourceListeners last set on the
	 * GraphicalViewer.
	 * 
	 * @return List
	 */
	public List getTransferDragSourceListeners() {
		if (fTransferDragSourceListeners == null)
			fTransferDragSourceListeners = new ArrayList();
		return fTransferDragSourceListeners;
	}

	/**
	 * Returns the PaletteViewer
	 * 
	 * @return PaletteViewer
	 */
	public PaletteViewer getViewer() {
		return fViewer;
	}

	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		if (fViewer != null)
			fViewer.restoreState(memento);
	}

	public void insert() {
		if (getSelectedEntry() != null && getSelectedEntry() instanceof ISnippetItem) {
			SnippetPaletteItem item = (SnippetPaletteItem) getSelectedEntry();
			insert(item);
		}
	}

	public void insert(SnippetPaletteItem item) {
		insertionHelper.insert(item, getSite().getPage().getActiveEditor());
	}

	public void save() {
		SnippetManager.getInstance().saveDefinitions();
	}

	public void saveState(IMemento memento) {
		fViewer.saveState(memento);
	}

	public void setFocus() {
		if (getViewer() != null && getViewer().getControl() != null && !getViewer().getControl().isDisposed())
			getViewer().getControl().setFocus();
	}

	/**
	 * Sets the root.
	 * 
	 * @param root
	 *            The root to set
	 */
	public void setRoot(SnippetPaletteRoot root) {
		fRoot = root;
		fViewer.setPaletteRoot(root);
	}

	public void setSelectedEntry(ISnippetsEntry entry) {
		if (Logger.DEBUG_PALETTE_SELECTION) {
			if (fSelectedEntry == entry)
				System.out.println("selection notification: " + entry + " (duplicated)"); //$NON-NLS-1$ //$NON-NLS-2$
			else
				System.out.println("selection notification: " + entry); //$NON-NLS-1$
		}
		if (fSelectedEntry == entry) {
			return;
		}
		if (Logger.DEBUG_PALETTE_SELECTION)
			System.out.println("processing selection: " + entry); //$NON-NLS-1$
		fSelectedEntry = entry;
		updateDragSource();
		updateActions(entry);
	}

	protected void updateActions(ISnippetsEntry entry) {
		boolean isItem = entry instanceof ISnippetItem;
		boolean isFromPlugin = entry != null && entry.getSourceType() == ISnippetsEntry.SNIPPET_SOURCE_PLUGINS;

		getCopyAction().setEnabled(entry != null && isItem);
		getCutAction().setEnabled(entry != null && isItem && !isFromPlugin);
		getPasteAction().setEnabled(getClipboard().getContents(TextTransfer.getInstance()) != null);
		getPasteAction().update();
		getInsertAction().setEnabled(entry != null && isItem && getSite().getPage().getEditorReferences().length > 0);
	}

	protected void updateDragSource() {
		Transfer[] supportedTypes = null;
		if (getSelectedEntry() != null && getSelectedEntry() instanceof ISnippetItem) {
			SnippetPaletteItem item = (SnippetPaletteItem) getSelectedEntry();
			ISnippetInsertion insertion = insertionHelper.getInsertion(item);
			if (insertion != null) {
				insertion.setItem(item);
				insertion.setEditorPart(getSite().getPage().getActiveEditor());
				supportedTypes = insertion.getTransfers();
			}
			else {
				supportedTypes = new Transfer[]{TextTransfer.getInstance()};
			}
		}
		else {
			// Keep a transfer registered so that GEF doesn't unhook the drag
			// source
			// from the control. Not unhooking it would make it look like
			// conditions
			// where drag isn't supported would be (the cursor looks like it's
			// dragging)
			// when they shouldn't be draggable at all.
			supportedTypes = new Transfer[]{TextTransfer.getInstance()};
		}

		/*
		 * TRH suggested use of the event's doit field by the fListeners, but
		 * there's no other way to guarantee that TextTransfer is considered
		 * last
		 */
		Iterator iterator = getTransferDragSourceListeners().iterator();
		ArrayList oldListeners = new ArrayList();
		while (iterator.hasNext()) {
			TransferDragSourceListener listener = (TransferDragSourceListener) iterator.next();
			oldListeners.add(listener);
			iterator.remove();
		}

		boolean addTextTransfer = false;
		for (int i = 0; i < supportedTypes.length; i++) {
			if (TextTransfer.class.equals(supportedTypes[i].getClass())) {
				addTextTransfer = true;
			}
			else {
				TransferDragSourceListener listener = new TransferDragSourceListenerImpl(supportedTypes[i]);
				getViewer().addDragSourceListener(listener);
				getTransferDragSourceListeners().add(listener);
			}
		}
		iterator = oldListeners.iterator();
		while (iterator.hasNext()) {
			TransferDragSourceListener listener = (TransferDragSourceListener) iterator.next();
			getViewer().removeDragSourceListener(listener);
			iterator.remove();
		}
		if (addTextTransfer) {
			addTextTransferListener();
		}
		if (Logger.DEBUG_DRAG_AND_DROP)
			System.out.println("" + getTransferDragSourceListeners().size() + " transfer types"); //$NON-NLS-1$ //$NON-NLS-2$
	}
}
