/*******************************************************************************
 * Copyright (c) 2000, 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.gef.ui.parts;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;

import org.eclipse.draw2d.ExclusionSearch;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.geometry.Point;

import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ExposeHelper;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Handle;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.MouseWheelHandler;
import org.eclipse.gef.MouseWheelHelper;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableRootEditPart;

/**
 * An EditPartViewer implementation based on {@link org.eclipse.draw2d.IFigure
 * Figures}.
 * 
 * @author hudsonr
 */
public class GraphicalViewerImpl extends AbstractEditPartViewer implements
		GraphicalViewer {

	private final LightweightSystem lws = createLightweightSystem();
	IFigure rootFigure;
	private DomainEventDispatcher eventDispatcher;
	private FocusListener lFocus;

	/**
	 * Constructs a GraphicalViewerImpl with the default root editpart.
	 */
	public GraphicalViewerImpl() {
		createDefaultRoot();
		setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.NONE),
				MouseWheelDelegateHandler.SINGLETON);
	}

	/**
	 * @see org.eclipse.gef.EditPartViewer#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public Control createControl(Composite composite) {
		setControl(new Canvas(composite, SWT.NO_BACKGROUND));
		return getControl();
	}

	/**
	 * Creates the default root editpart. Called during construction.
	 */
	protected void createDefaultRoot() {
		setRootEditPart(new ScalableRootEditPart());
	}

	/**
	 * Creates the lightweight system used to host figures. Subclasses should
	 * not need to override this method.
	 * 
	 * @return the lightweight system
	 */
	protected LightweightSystem createLightweightSystem() {
		return new LightweightSystem();
	}

	/**
	 * @see AbstractEditPartViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
	 */
	protected void handleDispose(DisposeEvent e) {
		super.handleDispose(e);
		getLightweightSystem().getUpdateManager().dispose();
	}

	/**
	 * This method is invoked when this viewer's control gains focus. It gives
	 * focus to the {@link AbstractEditPartViewer#focusPart focusPart}, if there
	 * is one.
	 * 
	 * @param fe
	 *            the focusEvent received by this viewer's control
	 */
	protected void handleFocusGained(FocusEvent fe) {
		if (focusPart != null)
			focusPart.setFocus(true);
	}

	/**
	 * This method is invoked when this viewer's control loses focus. It removes
	 * focus from the {@link AbstractEditPartViewer#focusPart focusPart}, if
	 * there is one.
	 * 
	 * @param fe
	 *            the focusEvent received by this viewer's control
	 */
	protected void handleFocusLost(FocusEvent fe) {
		if (focusPart != null)
			focusPart.setFocus(false);
	}

	/**
	 * @see GraphicalViewer#findHandleAt(org.eclipse.draw2d.geometry.Point)
	 */
	public Handle findHandleAt(Point p) {
		LayerManager layermanager = (LayerManager) getEditPartRegistry().get(
				LayerManager.ID);
		if (layermanager == null)
			return null;
		List list = new ArrayList(3);
		list.add(layermanager.getLayer(LayerConstants.PRIMARY_LAYER));
		list.add(layermanager.getLayer(LayerConstants.CONNECTION_LAYER));
		list.add(layermanager.getLayer(LayerConstants.FEEDBACK_LAYER));
		IFigure handle = getLightweightSystem().getRootFigure()
				.findFigureAtExcluding(p.x, p.y, list);
		if (handle instanceof Handle)
			return (Handle) handle;
		return null;
	}

	/**
	 * @see EditPartViewer#findObjectAtExcluding(Point, Collection,
	 *      EditPartViewer.Conditional)
	 */
	public EditPart findObjectAtExcluding(Point pt, Collection exclude,
			final Conditional condition) {
		class ConditionalTreeSearch extends ExclusionSearch {
			ConditionalTreeSearch(Collection coll) {
				super(coll);
			}

			public boolean accept(IFigure figure) {
				EditPart editpart = null;
				while (editpart == null && figure != null) {
					editpart = (EditPart) getVisualPartMap().get(figure);
					figure = figure.getParent();
				}
				return editpart != null
						&& (condition == null || condition.evaluate(editpart));
			}
		}
		IFigure figure = getLightweightSystem().getRootFigure().findFigureAt(
				pt.x, pt.y, new ConditionalTreeSearch(exclude));
		EditPart part = null;
		while (part == null && figure != null) {
			part = (EditPart) getVisualPartMap().get(figure);
			figure = figure.getParent();
		}
		if (part == null)
			return getContents();
		return part;
	}

	/**
	 * Flushes and pending layouts and paints in the lightweight system.
	 * 
	 * @see org.eclipse.gef.EditPartViewer#flush()
	 */
	public void flush() {
		getLightweightSystem().getUpdateManager().performUpdate();
	}

	/**
	 * Returns the event dispatcher
	 * 
	 * @deprecated This method should not be called by subclasses
	 * @return the event dispatcher
	 */
	protected DomainEventDispatcher getEventDispatcher() {
		return eventDispatcher;
	}

	/**
	 * Convenience method for finding the layer manager.
	 * 
	 * @return the LayerManager
	 */
	protected LayerManager getLayerManager() {
		return (LayerManager) getEditPartRegistry().get(LayerManager.ID);
	}

	/**
	 * Returns the lightweight system.
	 * 
	 * @return the system
	 */
	protected LightweightSystem getLightweightSystem() {
		return lws;
	}

	/**
	 * Returns the root figure
	 * 
	 * @deprecated There is no reason to call this method $TODO delete this
	 *             method
	 * @return the root figure
	 */
	protected IFigure getRootFigure() {
		return rootFigure;
	}

	/**
	 * Extended to flush paints during drop callbacks.
	 * 
	 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#hookDropTarget()
	 */
	protected void hookDropTarget() {
		// Allow the real drop targets to make their changes first.
		super.hookDropTarget();

		// Then force and update since async paints won't occurs during a Drag
		// operation
		getDropTarget().addDropListener(new DropTargetAdapter() {
			public void dragEnter(DropTargetEvent event) {
				flush();
			}

			public void dragLeave(DropTargetEvent event) {
				flush();
			}

			public void dragOver(DropTargetEvent event) {
				flush();
			}
		});
	}

	/**
	 * Extended to tell the lightweight system what its control is.
	 * 
	 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#hookControl()
	 */
	protected void hookControl() {
		super.hookControl();
		Control control = getControl();
		Object innerCanvas = control.getData(Canvas.class.getName());
		if (innerCanvas instanceof Canvas) {
			control = (Canvas) innerCanvas;
		}
		getLightweightSystem().setControl((Canvas) control);
		control.addFocusListener(lFocus = new FocusListener() {
			public void focusGained(FocusEvent e) {
				handleFocusGained(e);
			}

			public void focusLost(FocusEvent e) {
				handleFocusLost(e);
			}
		});
	}

	/**
	 * Registers the accessible editpart with the event dispatcher.
	 * 
	 * @param acc
	 *            the accessible
	 */
	public void registerAccessibleEditPart(AccessibleEditPart acc) {
		Assert.isNotNull(acc);
		DomainEventDispatcher domainEventDispatcher = getEventDispatcher();
		if (domainEventDispatcher != null) {
			domainEventDispatcher.putAccessible(acc);
		}
	}

	/**
	 * Reveals the specified editpart by using {@link ExposeHelper}s. A
	 * bottom-up scan through the parent-chain is performed, looking for expose
	 * helpers along the way, and asking them to expose the given editpart.
	 * 
	 * @see org.eclipse.gef.EditPartViewer#reveal(EditPart)
	 */
	public void reveal(EditPart part) {
		if (part == null)
			return;
		EditPart current = part.getParent();
		while (current != null) {
			ExposeHelper helper = (ExposeHelper) current
					.getAdapter(ExposeHelper.class);
			if (helper != null)
				helper.exposeDescendant(part);
			current = current.getParent();
		}
		AccessibleEditPart acc = (AccessibleEditPart) part
				.getAdapter(AccessibleEditPart.class);
		//RAP does not support accessibility
		// if (acc != null)
		// getControl().getAccessible().setFocus(acc.getAccessibleID());
	}

	/**
	 * Extended implementation to flush the viewer as the context menu is shown.
	 * 
	 * @see EditPartViewer#setContextMenu(org.eclipse.jface.action.MenuManager)
	 */
	public void setContextMenu(MenuManager contextMenu) {
		super.setContextMenu(contextMenu);
		if (contextMenu != null)
			contextMenu.addMenuListener(new IMenuListener() {
				public void menuAboutToShow(IMenuManager manager) {
					flush();
				}
			});
	}

	/**
	 * @see org.eclipse.gef.EditPartViewer#setCursor(org.eclipse.swt.graphics.Cursor)
	 */
	public void setCursor(Cursor newCursor) {
		if (getEventDispatcher() != null)
			getEventDispatcher().setOverrideCursor(newCursor);
	}

	/**
	 * Extends the drag source to handle figures which handle MouseDown events,
	 * thereby aborting any DragDetect callbacks.
	 * 
	 * @see AbstractEditPartViewer#setDragSource(org.eclipse.swt.dnd.DragSource)
	 */
	protected void setDragSource(DragSource source) {
		super.setDragSource(source);

		class TheLastListener extends DragSourceAdapter {
			public void dragStart(DragSourceEvent event) {
				// If the EventDispatcher has captured the mouse, don't perform
				// native drag.
				if (getEventDispatcher().isCaptured())
					event.doit = false;
				if (event.doit) {
					// A drag is going to occur, tell the EditDomain
					getEventDispatcher().dispatchNativeDragStarted(event,
							GraphicalViewerImpl.this);
					/*
					 * The mouse down that came before the dragstart, or the
					 * dragstart event itself, may have caused selection or
					 * something that needs to be painted. paints will not get
					 * processed during DND, so flush.
					 */
					flush();
				}
			}

			public void dragFinished(DragSourceEvent event) {
				getEventDispatcher().dispatchNativeDragFinished(event,
						GraphicalViewerImpl.this);
			}
		}

		/*
		 * The DragSource may be set to null if there are no listeners. If there
		 * are listeners, this should be *the* last listener because all other
		 * listeners are hooked in super().
		 */
		if (source != null)
			getDragSource().addDragListener(new TheLastListener());
	}

	/**
	 * @see org.eclipse.gef.EditPartViewer#setEditDomain(org.eclipse.gef.EditDomain)
	 */
	public void setEditDomain(EditDomain domain) {
		super.setEditDomain(domain);
		// Set the new event dispatcher, even if the new domain is null. This
		// will dispose
		// the old event dispatcher.
		getLightweightSystem().setEventDispatcher(
				eventDispatcher = new DomainEventDispatcher(domain, this));
	}

	/**
	 * @see org.eclipse.gef.EditPartViewer#setRootEditPart(org.eclipse.gef.RootEditPart)
	 */
	public void setRootEditPart(RootEditPart editpart) {
		super.setRootEditPart(editpart);
		setRootFigure(((GraphicalEditPart) editpart).getFigure());
	}

	/**
	 * Sets the lightweight system's root figure.
	 * 
	 * @param figure
	 *            the root figure
	 */
	protected void setRootFigure(IFigure figure) {
		rootFigure = figure;
		getLightweightSystem().setContents(rootFigure);
	}

	/**
	 * @see org.eclipse.gef.EditPartViewer#setRouteEventsToEditDomain(boolean)
	 */
	public void setRouteEventsToEditDomain(boolean value) {
		getEventDispatcher().setRouteEventsToEditor(value);
	}

	/**
	 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#unhookControl()
	 */
	protected void unhookControl() {
		super.unhookControl();
		if (lFocus != null) {
			getControl().removeFocusListener(lFocus);
			lFocus = null;
		}
	}

	/**
	 * @see EditPartViewer#unregisterAccessibleEditPart(org.eclipse.gef.AccessibleEditPart)
	 */
	public void unregisterAccessibleEditPart(AccessibleEditPart acc) {
		Assert.isNotNull(acc);
		DomainEventDispatcher domainEventDispatcher = getEventDispatcher();
		if (domainEventDispatcher != null) {
			domainEventDispatcher.removeAccessible(acc);
		}
	}

	private static class MouseWheelDelegateHandler implements MouseWheelHandler {
		private static final MouseWheelHandler SINGLETON = new MouseWheelDelegateHandler();

		private MouseWheelDelegateHandler() {
		}

		/**
		 * Delegates handling to the selected editpart's MouseWheelHelper.
		 * 
		 * @see org.eclipse.gef.MouseWheelHandler#handleMouseWheel(org.eclipse.swt.widgets.Event,
		 *      org.eclipse.gef.EditPartViewer)
		 */
		public void handleMouseWheel(Event event, EditPartViewer viewer) {
			EditPart part = viewer.getFocusEditPart();
			do {
				MouseWheelHelper helper = (MouseWheelHelper) part
						.getAdapter(MouseWheelHelper.class);
				if (helper != null)
					helper.handleMouseWheelScrolled(event);
				part = part.getParent();
			} while (event.doit && part != null);
		}
	}

}
