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

import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleControlListener;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.accessibility.AccessibleListener;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ui.presentations.PresentationUtil;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;

/**
 * The LightweightSystem is the link between SWT and Draw2d. It is the component
 * that provides the ability for {@link Figure Figures} to be hosted on an SWT
 * Canvas.
 * <p>
 * Normal procedure for using a LightweightSystem:
 * <ol>
 * <li>Create an SWT Canvas.
 * <li>Create a LightweightSystem passing it that Canvas.
 * <li>Create a Draw2d Figure and call setContents(IFigure). This Figure will be
 * the top-level Figure of the Draw2d application.
 * </ol>
 */
public class LightweightSystem {

	private Canvas canvas;
	IFigure contents;
	private IFigure root;
	private EventDispatcher dispatcher;
	private UpdateManager manager = new DeferredUpdateManager();
	private int ignoreResize;
	private RAPDragTracker tracker;

	/**
	 * Constructs a LightweightSystem on Canvas <i>c</i>.
	 * 
	 * @param c
	 *            the canvas
	 * @since 2.0
	 */
	public LightweightSystem(Canvas c) {
		this();
		setControl(c);
	}

	/**
	 * Constructs a LightweightSystem <b>without</b> a Canvas.
	 */
	public LightweightSystem() {
		init();
	}

	/**
	 * Adds SWT listeners to the LightWeightSystem's Canvas. This allows for SWT
	 * events to be dispatched and handled by its {@link EventDispatcher}.
	 * <P>
	 * <EM>WARNING:</EM> This method should not be overridden.
	 * 
	 * @since 2.0
	 */
	protected void addListeners() {
		final EventHandler handler = createEventHandler();
		canvas.getAccessible().addAccessibleListener(handler);
		canvas.getAccessible().addAccessibleControlListener(handler);
		canvas.addMouseListener(handler);
		// UNSUPPORTED - api not implemented in RAP
		// canvas.addMouseMoveListener(handler);
		// canvas.addMouseTrackListener(handler);
		canvas.addKeyListener(handler);
		canvas.addTraverseListener(handler);
		canvas.addFocusListener(handler);
		canvas.addDisposeListener(handler);
		// HACK: for DND in RAP
		PresentationUtil.addDragListener(canvas, handler);
		DragSource dragSource = new DragSource(canvas, DND.DROP_MOVE
				| DND.DROP_COPY | DND.DROP_LINK);
		final DragSourceListener listener = new DragSourceListener() {

			public void dragStart(DragSourceEvent event) {
				tracker = new RAPDragTracker(handler, canvas);
				tracker.open();
			}

			public void dragSetData(DragSourceEvent event) {
			}

			public void dragFinished(DragSourceEvent event) {
				if (tracker != null) {
					tracker.close();
					tracker = null;
				}
			}
		};

		dragSource.addDragListener(listener);

		canvas.addListener(org.eclipse.draw2d.rap.swt.SWT.MouseWheel, handler);

		canvas.addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent e) {
				LightweightSystem.this.controlResized();
			}
		});
		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				LightweightSystem.this.paint(event.gc);
			}
		});
	}

	/**
	 * Resizes and revalidates the root figure when the control is resized.
	 */
	protected void controlResized() {
		if (ignoreResize > 0)
			return;
		Rectangle r = new Rectangle(canvas.getClientArea());
		r.setLocation(0, 0);
		root.setBounds(r);
		root.revalidate();
		getUpdateManager().performUpdate();
	}

	/**
	 * Returns this LightwightSystem's EventDispatcher.
	 * 
	 * @return the event dispatcher
	 * @since 2.0
	 */
	protected EventDispatcher getEventDispatcher() {
		if (dispatcher == null)
			setEventDispatcher(new SWTEventDispatcher());
		return dispatcher;
	}

	/**
	 * Returns this LightweightSystem's root figure.
	 * 
	 * @return the root figure
	 * @since 2.0
	 */
	public IFigure getRootFigure() {
		return root;
	}

	/**
	 * Returns a new instance of this LightweightSystem's EventHandler.
	 * 
	 * @return the newly created event handler
	 * @since 2.0
	 */
	protected final EventHandler createEventHandler() {
		return internalCreateEventHandler();
	}

	/**
	 * Creates and returns the root figure.
	 * 
	 * @return the newly created root figure
	 */
	protected RootFigure createRootFigure() {
		RootFigure f = new RootFigure();
		f.addNotify();
		f.setOpaque(true);
		f.setLayoutManager(new StackLayout());
		return f;
	}

	/**
	 * Returns this LightweightSystem's UpdateManager.
	 * 
	 * @return the update manager
	 * @since 2.0
	 */
	public UpdateManager getUpdateManager() {
		return manager;
	}

	/**
	 * Initializes this LightweightSystem by setting the root figure.
	 */
	protected void init() {
		setRootPaneFigure(createRootFigure());
	}

	EventHandler internalCreateEventHandler() {
		return new EventHandler();
	}

	/**
	 * Invokes this LightweightSystem's {@link UpdateManager} to paint this
	 * LightweightSystem's Canvas and contents.
	 * 
	 * @param gc
	 *            the GC used for painting
	 * @since 2.0
	 */
	public void paint(GC gc) {
		getUpdateManager().paint(gc);
	}

	/**
	 * Sets the contents of the LightweightSystem to the passed figure. This
	 * figure should be the top-level Figure in a Draw2d application.
	 * 
	 * @param figure
	 *            the new root figure
	 * @since 2.0
	 */
	public void setContents(IFigure figure) {
		if (contents != null)
			root.remove(contents);
		contents = figure;
		root.add(contents);
	}

	/**
	 * Sets the LightweightSystem's control to the passed Canvas.
	 * 
	 * @param c
	 *            the canvas
	 * @since 2.0
	 */
	public void setControl(Canvas c) {
		if (canvas == c)
			return;
		canvas = c;
		if ((c.getStyle() & SWT.DOUBLE_BUFFERED) != 0)
			getUpdateManager().setGraphicsSource(
					new NativeGraphicsSource(canvas));
		else
			getUpdateManager().setGraphicsSource(
					new BufferedGraphicsSource(canvas));
		getEventDispatcher().setControl(c);
		addListeners();

		// Size the root figure and contents to the current control's size
		Rectangle r = new Rectangle(canvas.getClientArea());
		r.setLocation(0, 0);
		root.setBounds(r);
		root.revalidate();
	}

	/**
	 * Sets this LightweightSystem's EventDispatcher.
	 * 
	 * @param dispatcher
	 *            the new event dispatcher
	 * @since 2.0
	 */
	public void setEventDispatcher(EventDispatcher dispatcher) {
		this.dispatcher = dispatcher;
		dispatcher.setRoot(root);
		dispatcher.setControl(canvas);
	}

	void setIgnoreResize(boolean value) {
		if (value)
			ignoreResize++;
		else
			ignoreResize--;
	}

	/**
	 * Sets this LightweightSystem's root figure.
	 * 
	 * @param root
	 *            the new root figure
	 */
	protected void setRootPaneFigure(RootFigure root) {
		getUpdateManager().setRoot(root);
		this.root = root;
	}

	/**
	 * Sets this LightweightSystem's UpdateManager.
	 * 
	 * @param um
	 *            the new update manager
	 * @since 2.0
	 */
	public void setUpdateManager(UpdateManager um) {
		manager = um;
		manager.setRoot(root);
	}

	/**
	 * The figure at the root of the LightweightSystem. If certain properties
	 * (i.e. font, background/foreground color) are not set, the RootFigure will
	 * obtain these properties from LightweightSystem's Canvas.
	 */
	protected class RootFigure extends Figure {
		/** @see IFigure#getBackgroundColor() */
		public Color getBackgroundColor() {
			if (bgColor != null)
				return bgColor;
			if (canvas != null)
				return canvas.getBackground();
			return null;
		}

		/** @see IFigure#getFont() */
		public Font getFont() {
			if (font != null)
				return font;
			if (canvas != null)
				return canvas.getFont();
			return null;
		}

		/** @see IFigure#getForegroundColor() */
		public Color getForegroundColor() {
			if (fgColor != null)
				return fgColor;
			if (canvas != null)
				return canvas.getForeground();
			return null;
		}

		/** @see IFigure#getUpdateManager() */
		public UpdateManager getUpdateManager() {
			return LightweightSystem.this.getUpdateManager();
		}

		/** @see IFigure#internalGetEventDispatcher() */
		public EventDispatcher internalGetEventDispatcher() {
			return getEventDispatcher();
		}

		/**
		 * @see IFigure#isMirrored()
		 */
		public boolean isMirrored() {
			return (LightweightSystem.this.canvas.getStyle() & org.eclipse.draw2d.rap.swt.SWT.MIRRORED) != 0;
		}

		/** @see Figure#isShowing() */
		public boolean isShowing() {
			return true;
		}
	}

	protected class RAPDragTracker {
		public boolean cancelled;
		public boolean tracking;
		private final MouseMoveListener listener;
		private final Widget widget;

		public RAPDragTracker(final MouseMoveListener listener,
				final Widget widget) {
			this.listener = listener;
			this.widget = widget;
		}

		public void open() {
			Job dragJob = new Job("Drag-Job") {
				protected IStatus run(IProgressMonitor monitor) {
					// Run tracker until mouse up occurs or escape key pressed.
					final Display display = widget.getDisplay();
					cancelled = false;
					tracking = true;

					try {
						long timeout = 0;
						long refreshRate = 200;
						while (tracking && !cancelled) {
							if (display != null && !display.isDisposed()) {
								display.syncExec(new Runnable() {
									public void run() {
										if (canvas.isDisposed()) {
											tracking = false;
											cancelled = true;
											return;
										}
										Event ev = new Event();
										ev.display = display;
										Point loc = canvas.toControl(display
												.getCursorLocation());
										ev.type = SWT.DragDetect;
										ev.widget = widget;
										ev.button = 1;
										ev.x = loc.x;
										ev.y = loc.y;
										MouseEvent me = new MouseEvent(ev);
										me.stateMask = SWT.BUTTON1;
										listener.mouseMove(me);
									}
								});
								timeout += refreshRate;
								if (timeout >= 60000) {
									cancelled = true;
								}
								Thread.sleep(refreshRate);
							}

						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						display.syncExec(new Runnable() {
							public void run() {
								close();
							}
						});
					}
					return Status.OK_STATUS;
				}
			};
			dragJob.schedule();
		}

		public void close() {
			tracking = false;
		}
	}

	/**
	 * Listener used to get all necessary events from the Canvas and pass them
	 * on to the {@link EventDispatcher}.
	 */
	protected class EventHandler implements MouseMoveListener, MouseListener,
			AccessibleControlListener, KeyListener, TraverseListener,
			FocusListener, AccessibleListener, MouseTrackListener, Listener,
			DisposeListener {
		/** @see FocusListener#focusGained(FocusEvent) */
		public void focusGained(FocusEvent e) {
			getEventDispatcher().dispatchFocusGained(e);
		}

		/** @see FocusListener#focusLost(FocusEvent) */
		public void focusLost(FocusEvent e) {
			getEventDispatcher().dispatchFocusLost(e);
		}

		/** @see AccessibleControlListener#getChild(AccessibleControlEvent) */
		public void getChild(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getChild(e);
		}

		/** @see AccessibleControlListener#getChildAtPoint(AccessibleControlEvent) */
		public void getChildAtPoint(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getChildAtPoint(e);
		}

		/** @see AccessibleControlListener#getChildCount(AccessibleControlEvent) */
		public void getChildCount(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getChildCount(e);
		}

		/** @see AccessibleControlListener#getChildren(AccessibleControlEvent) */
		public void getChildren(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getChildren(e);
		}

		/** @see AccessibleControlListener#getDefaultAction(AccessibleControlEvent) */
		public void getDefaultAction(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getDefaultAction(e);
		}

		/** @see AccessibleListener#getDescription(AccessibleEvent) */
		public void getDescription(AccessibleEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getDescription(e);
		}

		/** @see AccessibleControlListener#getFocus(AccessibleControlEvent) */
		public void getFocus(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getFocus(e);
		}

		/** @see AccessibleListener#getHelp(AccessibleEvent) */
		public void getHelp(AccessibleEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getHelp(e);
		}

		/** @see AccessibleListener#getKeyboardShortcut(AccessibleEvent) */
		public void getKeyboardShortcut(AccessibleEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getKeyboardShortcut(e);
		}

		/** @see AccessibleControlListener#getLocation(AccessibleControlEvent) */
		public void getLocation(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getLocation(e);
		}

		/** @see AccessibleListener#getName(AccessibleEvent) */
		public void getName(AccessibleEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getName(e);
		}

		/** @see AccessibleControlListener#getRole(AccessibleControlEvent) */
		public void getRole(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getRole(e);
		}

		/** @see AccessibleControlListener#getSelection(AccessibleControlEvent) */
		public void getSelection(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getSelection(e);
		}

		/** @see AccessibleControlListener#getState(AccessibleControlEvent) */
		public void getState(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getState(e);
		}

		/** @see AccessibleControlListener#getValue(AccessibleControlEvent) */
		public void getValue(AccessibleControlEvent e) {
			EventDispatcher.AccessibilityDispatcher ad;
			ad = getEventDispatcher().getAccessibilityDispatcher();
			if (ad != null)
				ad.getValue(e);
		}

		/**
		 * @see Listener#handleEvent(org.eclipse.swt.widgets.Event)
		 * @since 3.1
		 */
		public void handleEvent(Event event) {
			// Mouse wheel events
			if (event.type == org.eclipse.draw2d.rap.swt.SWT.MouseWheel)
				getEventDispatcher().dispatchMouseWheelScrolled(event);
			// HACK: for DND in RAP
			else if (event.type == SWT.DragDetect) {
				MouseEvent me = new MouseEvent(event);
				me.stateMask = SWT.BUTTON1;
				getEventDispatcher().dispatchMouseMoved(me);
			}
		}

		/** @see KeyListener#keyPressed(KeyEvent) */
		public void keyPressed(KeyEvent e) {
			getEventDispatcher().dispatchKeyPressed(e);
		}

		/** @see KeyListener#keyReleased(KeyEvent) */
		public void keyReleased(KeyEvent e) {
			getEventDispatcher().dispatchKeyReleased(e);
		}

		/** @see TraverseListener#keyTraversed(TraverseEvent) */
		public void keyTraversed(TraverseEvent e) {
			/*
			 * Doit is almost always false by default for Canvases with
			 * KeyListeners. Set to true to allow normal behavior. For example,
			 * in Dialogs ESC should close.
			 */
			e.doit = true;
			getEventDispatcher().dispatchKeyTraversed(e);
		}

		/** @see MouseListener#mouseDoubleClick(MouseEvent) */
		public void mouseDoubleClick(MouseEvent e) {
			getEventDispatcher().dispatchMouseDoubleClicked(e);
		}

		/** @see MouseListener#mouseDown(MouseEvent) */
		public void mouseDown(MouseEvent e) {
			getEventDispatcher().dispatchMousePressed(e);
		}

		/** @see MouseTrackListener#mouseEnter(MouseEvent) */
		public void mouseEnter(MouseEvent e) {
			getEventDispatcher().dispatchMouseEntered(e);
		}

		/** @see MouseTrackListener#mouseExit(MouseEvent) */
		public void mouseExit(MouseEvent e) {
			getEventDispatcher().dispatchMouseExited(e);
		}

		/** @see MouseTrackListener#mouseHover(MouseEvent) */
		public void mouseHover(MouseEvent e) {
			getEventDispatcher().dispatchMouseHover(e);
		}

		/** @see MouseMoveListener#mouseMove(MouseEvent) */
		public void mouseMove(MouseEvent e) {
			getEventDispatcher().dispatchMouseMoved(e);
		}

		/** @see MouseListener#mouseUp(MouseEvent) */
		public void mouseUp(MouseEvent e) {
			getEventDispatcher().dispatchMouseReleased(e);
			if (tracker != null) {
				tracker.close();
				tracker = null;
			}
		}

		/** @see DisposeListener#widgetDisposed(DisposeEvent) */
		public void widgetDisposed(DisposeEvent e) {
			getUpdateManager().dispose();
		}
	}

}
