/**
 * File:    WEMouseMoveTrackListener.java
 * Created: 17.06.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Christian Saad, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.editors.pages.activityEditor.internal;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jwt.meta.model.core.NamedElement;
import org.eclipse.jwt.we.editors.WEEditor;
import org.eclipse.jwt.we.misc.util.GeneralHelper;
import org.eclipse.jwt.we.parts.processes.policies.ScopeLayoutEditPolicy;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IViewSite;


/**
 * A singleton mouse listener for move and track events which can be attached to the
 * control of graphical viewers. It writes the mouse position into the status line.
 * 
 * @version $Id: WEMouseMoveTrackListener.java,v 1.3 2009-11-26 12:41:45 chsaad Exp $
 * @author Christian Saad (csaad@gmx.net), Programming distributed Systems Lab, University
 *         of Augsburg, Germany, www.ds-lab.org
 */
public class WEMouseMoveTrackListener
		implements MouseMoveListener, MouseTrackListener
{

	/**
	 * The singleton instance
	 */
	private static WEMouseMoveTrackListener myinstance = null;

	/**
	 * The status line manager.
	 */
	private IStatusLineManager statusLineManager;


	/**
	 * The constructor.
	 */
	private WEMouseMoveTrackListener()
	{
	}


	/**
	 * Returns the singleton instance
	 */
	public static WEMouseMoveTrackListener getInstance()
	{
		if (myinstance == null)
			myinstance = new WEMouseMoveTrackListener();
		return myinstance;
	}


	/**
	 * Acquires the status line manager.
	 */
	public void acquireStatusLineManager()
	{
		// get the current(!) status line manager
		WEEditor weEditor = GeneralHelper.getActiveInstance();

		if (weEditor != null)
		{
			IActionBars actionBars = null;
			if (weEditor.getSite() instanceof IViewSite)
			{
				actionBars = ((IViewSite) weEditor.getSite()).getActionBars();
			}
			else if (weEditor.getSite() instanceof IEditorSite)
			{
				actionBars = ((IEditorSite) weEditor.getSite()).getActionBars();
			}

			statusLineManager = actionBars.getStatusLineManager();
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseMove(MouseEvent e)
	{
		// try to acquire the current statusline manager
		acquireStatusLineManager();

		// set message
		if (statusLineManager != null)
		{
			String text = ""; //$NON-NLS-1$

			// the absolute mouse position
			Point absolutePosition = new Point(e.x, e.y);

			// get the layout edit policy
			if (GeneralHelper.getActiveInstance() == null
					|| GeneralHelper.getActiveInstance().getCurrentActivitySheet() == null)
			{
				// avoid npex when no active editor part (happens ex. when
				// switching between Eclipse and development JWT)
				return;
			}
			EditPartViewer editPartViewer = GeneralHelper.getActiveInstance()
					.getCurrentActivitySheet().getGraphicalViewer();
			EditPolicy layoutPolicy = editPartViewer.getContents().getEditPolicy(
					EditPolicy.LAYOUT_ROLE);

			if (layoutPolicy instanceof ScopeLayoutEditPolicy)
			{
				// get the relative mouse position
				CreateRequest request = new CreateRequest();
				request.setLocation(absolutePosition);
				Rectangle relativePos = (Rectangle) ((ScopeLayoutEditPolicy) layoutPolicy)
						.getConstraintFor(request);
				text += "(x:" + relativePos.x + " y:" + relativePos.y + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

				// get the object under the mouse
				Object mouseOverObject = null;
				EditPart editPart = editPartViewer.findObjectAt(absolutePosition);
				if (editPart != null)
				{
					mouseOverObject = editPart.getModel();
				}

				// generate a text for the element
				if (mouseOverObject instanceof NamedElement)
				{
					IItemLabelProvider lP = (IItemLabelProvider) GeneralHelper
							.getActiveInstance().getAdapterFactory().adapt(
									editPart.getModel(), IItemLabelProvider.class);

					text += " | " + lP.getText(mouseOverObject); //$NON-NLS-1$
				}

			}

			text = text.replaceAll("\\n", " "); //$NON-NLS-1$ //$NON-NLS-2$
			text = text.replaceAll("\\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
			statusLineManager.setMessage(text);
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseEnter(MouseEvent e)
	{
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseExit(MouseEvent e)
	{
		// try to acquire the current statusline manager
		if (statusLineManager == null)
		{
			acquireStatusLineManager();
		}

		// remove status line message on exit
		if (statusLineManager != null)
		{
			statusLineManager.setMessage(null);
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseHover(MouseEvent e)
	{
	}

}
