/*******************************************************************************
 * 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.setSystem(true);
			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();
		}
	}

}
