/*******************************************************************************
 * Copyright (c) 2004, 2007 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
 *     Wind River - Bug 206407 AbstractMemoryRendering connect()s the wrong "this" 
 *******************************************************************************/
package org.eclipse.debug.ui.memory;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.views.memory.PropertyChangeNotifier;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchActionConstants;

/**
 * Abstract implementation of a memory rendering.
 * <p>
 * To contribute an action to a rendering, an <code>objectContribution</code> can
 * be used on a rendering implementation class itself using a 
 * <code>popupMenus</code> extension. Additionally, the context menu created
 * by <code>createPopupMenu()</code> is registered with an identifier of this
 * rendering's container identifier. Actions may also be contributed to the
 * container's context menu specifically by using a  <code>viewerContribution</code>
 * on a <code>popupMenus</code> extension that has a <code>targetID</code> referring
 * to this rendering container's identifier. 
 * </p>
 * <p>
 * Clients implementing memory renderings must subclass this class.
 * </p>
 * @since 3.1
 */
public abstract class AbstractMemoryRendering extends PlatformObject implements IMemoryRendering{

	private IMemoryBlock fMemoryBlock;
	private IMemoryRenderingContainer fContainer;
	private ListenerList fPropertyListeners;
	private boolean fVisible = true;
	private MenuManager fPopupMenuMgr;
	private String fRenderingId;
	
	private class ConnectionJob extends Job
	{
		Runnable fRunnable;
		ConnectionJob(Runnable runnable)
		{
			super("Connect/Disconnect MemoryBlock"); //$NON-NLS-1$
			fRunnable = runnable;
			setSystem(true);
		}

		protected IStatus run(IProgressMonitor monitor) {
			fRunnable.run();
			return Status.OK_STATUS;
		}
	}
	
	/**
	 * Client may provide a label decorator adapter from its memory block
	 * to decorate the label of a rendering.
	 * @since 3.2 
	 */
	private ILabelDecorator fLabelDecorator;
	private IMenuListener fMenuListener;
	
	/**
	 * Constructs a new rendering of the given type.
	 * 
	 * @param renderingId memory rendering type identifier
	 */
	public AbstractMemoryRendering(String renderingId)
	{
		fRenderingId = renderingId;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#init(org.eclipse.debug.ui.memory.IMemoryRenderingSite, org.eclipse.debug.core.model.IMemoryBlock)
	 */
	public void init(IMemoryRenderingContainer container, IMemoryBlock block) {
		fContainer = container;
		fMemoryBlock = block;
		
		fLabelDecorator = (ILabelDecorator)fMemoryBlock.getAdapter(ILabelDecorator.class);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#dispose()
	 */
	public void dispose()
	{
		// disconnect from memory block when rendering is disposed
		if (fMemoryBlock instanceof IMemoryBlockExtension)
		{
			Runnable runnable = new Runnable(){
				public void run() {
						((IMemoryBlockExtension)fMemoryBlock).disconnect(AbstractMemoryRendering.this);		
				}};
			new ConnectionJob(runnable).schedule();
		}
		
		if (fPopupMenuMgr != null)
		{
			fPopupMenuMgr.removeMenuListener(fMenuListener);
			fPopupMenuMgr.removeAll();
			fPopupMenuMgr.dispose();
			fPopupMenuMgr = null;
		}
		
		if (fPropertyListeners != null)
			fPropertyListeners = null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#activated()
	 */
	public void activated() {
		if (fContainer.getMemoryRenderingSite().getSynchronizationService() != null)
			fContainer.getMemoryRenderingSite().getSynchronizationService().setSynchronizationProvider(this);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#deactivated()
	 */
	public void deactivated() {
		// do nothing when deactivated
		// we do not want to set the sync provider from rendering site
		// to null because Linux GTK unexpectedly fires deactivated event.
		// If we reset the sync provider upon a deactivated event, it screws
		// up synchronization on Linux GTK.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesVisible()
	 */
	public void becomesVisible() {
		fVisible = true;
		
		if (fMemoryBlock instanceof IMemoryBlockExtension)
		{
			Runnable runnable = new Runnable(){
				public void run() {
					((IMemoryBlockExtension)fMemoryBlock).connect(AbstractMemoryRendering.this);		
				}};
			new ConnectionJob(runnable).schedule();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesHidden()
	 */
	public void becomesHidden() {
		fVisible = false;
		if (fMemoryBlock instanceof IMemoryBlockExtension)
		{
			Runnable runnable = new Runnable(){
				public void run() {
						((IMemoryBlockExtension)fMemoryBlock).disconnect(AbstractMemoryRendering.this);		
				}};
			new ConnectionJob(runnable).schedule();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#getMemoryBlock()
	 */
	public IMemoryBlock getMemoryBlock() {
		return fMemoryBlock;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#getRenderingId()
	 */
	public String getRenderingId()
	{
		return fRenderingId;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
	 */
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
				
		if (fPropertyListeners == null)
			fPropertyListeners = new ListenerList();
		
		fPropertyListeners.add(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
	 */
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		
		if (fPropertyListeners == null)
			return;
		fPropertyListeners.remove(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#getImage()
	 */
	public Image getImage() {
		return decorateImage(null);
	}
	
	/**
	 * Decorates and returns this rendering's image.
	 * 
	 * @param image base image
	 * @return decorated image
	 * @since 3.2
	 */	
	protected Image decorateImage(Image image) {
		if (fLabelDecorator != null)
			return fLabelDecorator.decorateImage(image, this);
		return image;		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRendering#getLabel()
	 */
	public  String getLabel()
	{
		if (fMemoryBlock == null)
			return IInternalDebugCoreConstants.EMPTY_STRING;
		
		StringBuffer label = new StringBuffer(IInternalDebugCoreConstants.EMPTY_STRING);
		
		if (fMemoryBlock instanceof IMemoryBlockExtension)
		{
			String expression = ((IMemoryBlockExtension)fMemoryBlock).getExpression();
			
			if (expression == null)
				expression = IInternalDebugCoreConstants.EMPTY_STRING;
			
			label.append(expression);
			
			if (expression.startsWith("&")) //$NON-NLS-1$
				label.insert(0, "&"); //$NON-NLS-1$		
			
			// show full address if the rendering is visible
			// hide address if the rendering is invisible
			try {
				if (fVisible && ((IMemoryBlockExtension)fMemoryBlock).getBigBaseAddress() != null)
				{	
					label.append(" : 0x"); //$NON-NLS-1$
					label.append(((IMemoryBlockExtension)fMemoryBlock).getBigBaseAddress().toString(16).toUpperCase());
				}
			} catch (DebugException e) {
				// do nothing... the label will not show memory block's address
			}
		}
		else
		{
			long address = fMemoryBlock.getStartAddress();
			label.append(Long.toHexString(address).toUpperCase());
		}
		
		IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId());
		
		if (type != null)
		{
			String preName = type.getLabel();
			
			if (preName != null)
			{
				label.append(" <"); //$NON-NLS-1$
				label.append(preName);
				label.append(">");  //$NON-NLS-1$
			}
		}
		
		return decorateLabel(label.toString());
	}
	
	/**
	 * Decorates and returns this rendering's label.
	 * 
	 * @param label base label
	 * @return decorated label
	 * @since 3.2
	 */
	protected String decorateLabel(String label) {
		if (fLabelDecorator != null)
			return fLabelDecorator.decorateText(label.toString(), this);
		return label.toString();		
	}
	
	/**
	 * Helper method for creating a pop up menu in the rendering for a control.
	 * Call this method when a context menu is required for a control
	 * in a rendering.
	 * <p>
	 * To contribute an action to a rendering, an <code>objectContribution</code> can
	 * be used on a rendering implementation class itself using a 
	 * <code>popupMenus</code> extension. Additionally, the context menu created
	 * by this method is registered with an identifier of this rendering's container.
	 * Actions may also be contributed to the context menu specifically by using a 
	 * <code>viewerContribution</code> on a <code>popupMenus</code> extension
	 * that has a <code>targetID</code> referring to this rendering container's identifier. 
	 * </p>
	 * <p>
	 * Clients are expected to become a menu listener for their pop  up 
	 * menu if they require to fill the context menu for the rendering.
	 * </p>
	 * @param control - control to create the pop up menu for
	 */
	protected void createPopupMenu(Control control)
	{
		if (fPopupMenuMgr == null)
		{
			fPopupMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
			fPopupMenuMgr.setRemoveAllWhenShown(true);
			IMemoryRenderingSite site = fContainer.getMemoryRenderingSite();
			String menuId = fContainer.getId();
						
			ISelectionProvider selProvider = site.getSite().getSelectionProvider();
			
			fMenuListener = new IMenuListener() {
							public void menuAboutToShow(IMenuManager manager) {
								manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
							}};
			fPopupMenuMgr.addMenuListener(fMenuListener);
			
			site.getSite().registerContextMenu(menuId, fPopupMenuMgr, selProvider);
		}
		
		Menu popupMenu = fPopupMenuMgr.createContextMenu(control);
		control.setMenu(popupMenu);
	}
	
	/**
	 * Returns the pop up menu manager for this rendering, or <code>null</code>
	 * if none.
	 * 
	 * @return the pop up menu manager for this rendering, or <code>null</code>
	 */
	protected MenuManager getPopupMenuManager()
	{
		return fPopupMenuMgr;
	}
	
	/**
	 * Fires the given event to all registered listeners.
	 * 
	 * @param event the event to fire
	 */
	protected void firePropertyChangedEvent(PropertyChangeEvent event)
	{
		if (fPropertyListeners == null)
			return;
		
		Object[] listeners = fPropertyListeners.getListeners();
		
		for (int i=0; i<listeners.length; i++)
		{	
			PropertyChangeNotifier notifier = new PropertyChangeNotifier((IPropertyChangeListener)listeners[i], event);
			SafeRunner.run(notifier);
		}
	}
	
	/**
	 * Returns the container hosting this memory rendering.
	 * 
	 * @return the container hosting this memory rendering
	 */
	public IMemoryRenderingContainer getMemoryRenderingContainer()
	{
		return fContainer;
	}

	/**
	 * Returns whether this rendering is currently visible.
	 * 
	 * @return whether this rendering is currently visible
	 */
	public boolean isVisible() {
		return fVisible;
	}
}
