/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;

/**
 * A <code>DelegatingDropAdapter</code> is a <code>DropTargetListener</code> that 
 * maintains and delegates to a set of {@link TransferDropTargetListener}s. Each 
 * <code>TransferDropTargetListener</code> can then be implemented as if it were 
 * the DropTarget's only <code>DropTargetListener</code>.
 * <p>
 * On <code>dragEnter</code>, <code>dragOperationChanged</code>, <code>dragOver</code>
 * and <code>drop</code>, a <i>current</i> listener is obtained from the set of all 
 * <code>TransferDropTargetListeners</code>. The current listener is the first listener 
 * to return <code>true</code> for 
 * {@link TransferDropTargetListener#isEnabled(DropTargetEvent)}.
 * The current listener is forwarded all <code>DropTargetEvents</code> until some other
 * listener becomes the current listener, or the drop terminates.
 * </p>
 * <p>
 * After adding all <code>TransferDropTargetListeners</code> to the 
 * <code>DelegatingDropAdapter</code> the combined set of <code>Transfers</code> should 
 * be set in the SWT <code>DropTarget</code>. <code>#getTransfers()</code> provides the 
 * set of <code>Transfer</code> types of all <code>TransferDropTargetListeners</code>. 
 * </p>
 * <p>
 * The following example snippet shows a <code>DelegatingDropAdapter</code> with two
 * <code>TransferDropTargetListeners</code>. One supports dropping resources and 
 * demonstrates how a listener can be disabled in the isEnabled method. 
 * The other listener supports text transfer. 
 * </p>
 * <code><pre>
 *		final TreeViewer viewer = new TreeViewer(shell, SWT.NONE);
 * 		DelegatingDropAdapter dropAdapter = new DelegatingDropAdapter();
 *		dropAdapter.addDropTargetListener(new TransferDropTargetListener() {
 *			public Transfer getTransfer() {
 *				return ResourceTransfer.getInstance();
 *			}
 *			public boolean isEnabled(DropTargetEvent event) {
 *				// disable drop listener if there is no viewer selection
 *				if (viewer.getSelection().isEmpty())
 *					return false;
 *				return true;
 *			}
 *			public void dragEnter(DropTargetEvent event) {}
 *			public void dragLeave(DropTargetEvent event) {}
 *			public void dragOperationChanged(DropTargetEvent event) {}
 *			public void dragOver(DropTargetEvent event) {}
 *			public void drop(DropTargetEvent event) {
 *				if (event.data == null)
 *					return;
 *				IResource[] resources = (IResource[]) event.data;
 *				if (event.detail == DND.DROP_COPY) {
 *					// copy resources
 *				} else {
 *					// move resources
 *				}
 *					
 *			}
 *			public void dropAccept(DropTargetEvent event) {}
 *		});
 *		dropAdapter.addDropTargetListener(new TransferDropTargetListener() {
 *			public Transfer getTransfer() {
 *				return TextTransfer.getInstance();
 *			}
 *			public boolean isEnabled(DropTargetEvent event) {
 *				return true;
 *			}
 *			public void dragEnter(DropTargetEvent event) {}
 *			public void dragLeave(DropTargetEvent event) {}
 *			public void dragOperationChanged(DropTargetEvent event) {}
 *			public void dragOver(DropTargetEvent event) {}
 *			public void drop(DropTargetEvent event) {
 *				if (event.data == null)
 *					return;
 *				System.out.println(event.data);
 *			}
 *			public void dropAccept(DropTargetEvent event) {}
 *		});		
 *		viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, dropAdapter.getTransfers(), dropAdapter);
 * </pre></code>
 * <p>
 * NOTE: This API is experimental and subject to change including removal.
 * </p>
 * @since 2.2
 */
public class DelegatingDropAdapter implements DropTargetListener {
	private List listeners = new ArrayList();
	private TransferDropTargetListener currentListener;
	private int originalDropType;

	/**
	 * Adds the given <code>TransferDropTargetListener</code>.
	 * 
	 * @param listener the new listener
	 */
	public void addDropTargetListener(TransferDropTargetListener listener) {
		listeners.add(listener);
	}
	/**
	 * The cursor has entered the drop target boundaries. The current listener is 
	 * updated, and <code>#dragEnter()</code> is forwarded to the current listener.
	 * 
	 * @param event the drop target event 
	 * @see DropTargetListener#dragEnter(DropTargetEvent)
	 */
	public void dragEnter(DropTargetEvent event) {
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Drag Enter: " + toString()); //$NON-NLS-1$
		originalDropType = event.detail;
		updateCurrentListener(event);
	}
	/**
	 * The cursor has left the drop target boundaries. The event is forwarded to the 
	 * current listener.
	 * 
	 * @param event the drop target event
	 * @see DropTargetListener#dragLeave(DropTargetEvent)
	 */
	public void dragLeave(final DropTargetEvent event) {
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Drag Leave: " + toString()); //$NON-NLS-1$
		setCurrentListener(null, event);
	}
	/**
	 * The operation being performed has changed (usually due to the user changing 
	 * a drag modifier key while dragging). Updates the current listener and forwards 
	 * this event to that listener.
	 * 
	 * @param event the drop target event
	 * @see DropTargetListener#dragOperationChanged(DropTargetEvent)
	 */
	public void dragOperationChanged(final DropTargetEvent event) {
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Drag Operation Changed to: " + event.detail); //$NON-NLS-1$
		originalDropType = event.detail;
		TransferDropTargetListener oldListener = getCurrentListener();
		updateCurrentListener(event);
		final TransferDropTargetListener newListener = getCurrentListener();
		// only notify the current listener if it hasn't changed based on the 
		// operation change. otherwise the new listener would get a dragEnter 
		// followed by a dragOperationChanged with the exact same event. 
		if (newListener != null && newListener == oldListener) {
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {
					newListener.dragOperationChanged(event);
				}
			});
		}
	}
	/**
	 * The cursor is moving over the drop target. Updates the current listener and 
	 * forwards this event to that listener. If no listener can handle the drag 
	 * operation the <code>event.detail</code> field is set to <code>DND.DROP_NONE</code> 
	 * to indicate an invalid drop.
	 *   
	 * @param event the drop target event
	 * @see DropTargetListener#dragOver(DropTargetEvent)
	 */
	public void dragOver(final DropTargetEvent event) {
		TransferDropTargetListener oldListener = getCurrentListener();
		updateCurrentListener(event);
		final TransferDropTargetListener newListener = getCurrentListener();
	
		// only notify the current listener if it hasn't changed based on the 
		// drag over. otherwise the new listener would get a dragEnter 
		// followed by a dragOver with the exact same event. 
		if (newListener != null && newListener == oldListener) {
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {
					newListener.dragOver(event);
				}
			});
		}
	}
	/**
	 * Forwards this event to the current listener, if there is one. Sets the
	 * current listener to <code>null</code> afterwards.
	 * 
	 * @param event the drop target event
	 * @see DropTargetListener#drop(DropTargetEvent)
	 */
	public void drop(final DropTargetEvent event) {
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Drop: " + toString()); //$NON-NLS-1$
		updateCurrentListener(event);
		if (getCurrentListener() != null) { 
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {
					getCurrentListener().drop(event);
				}
			});
		}
		setCurrentListener(null, event);
	}
	/**
	 * Forwards this event to the current listener if there is one.
	 * 
	 * @param event the drop target event
	 * @see DropTargetListener#dropAccept(DropTargetEvent)
	 */
	public void dropAccept(final DropTargetEvent event) {
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Drop Accept: " + toString()); //$NON-NLS-1$
		if (getCurrentListener() != null) {
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {
					getCurrentListener().dropAccept(event);
				}
			});
		}
	}
	/**
	 * Returns the listener which currently handles drop events.
	 * 
	 * @return the <code>TransferDropTargetListener</code> which currently 
	 * 	handles drop events.
	 */
	private TransferDropTargetListener getCurrentListener() {
		return currentListener;
	}
	/**
	 * Returns the transfer data type supported by the given listener.
	 * Returns <code>null</code> if the listener does not support any of the   
	 * specified data types.
	 *  
	 * @param dataTypes available data types
	 * @param listener <code>TransferDropTargetListener</code> to use for testing 
	 * 	supported data types.
	 * @return the transfer data type supported by the given listener or 
	 * 	<code>null</code>.
	 */
	private TransferData getSupportedTransferType(TransferData[] dataTypes, TransferDropTargetListener listener) {
		for (int i = 0; i < dataTypes.length; i++) {
			if (listener.getTransfer().isSupportedType(dataTypes[i])) {
				return dataTypes[i];
			}
		}
		return null;
	}
	/**
	 * Returns the combined set of <code>Transfer</code> types of all 
	 * <code>TransferDropTargetListeners</code>.
	 * 
	 * @return the combined set of <code>Transfer</code> types
	 */
	public Transfer[] getTransfers() {
		Transfer[] types = new Transfer[listeners.size()];
		for (int i = 0; i < listeners.size(); i++) {
			TransferDropTargetListener listener = (TransferDropTargetListener)listeners.get(i);
			types[i] = listener.getTransfer();
		}
		return types;
	}
	/**
	 * Returns <code>true</code> if there are no listeners to delegate events to.
	 * 
	 * @return <code>true</code> if there are no <code>TransferDropTargetListeners</code>
	 *	<code>false</code> otherwise
	 */
	public boolean isEmpty() {
		return listeners.isEmpty();
	}
	/**
	 * Removes the given <code>TransferDropTargetListener</code>.
	 * Listeners should not be removed while a drag and drop operation is in progress.
	 * 
	 * @param listener the listener to remove
	 */
	public void removeDropTargetListener(TransferDropTargetListener listener) {
		if (currentListener == listener)
			currentListener = null;
		listeners.remove(listener);
	}
	/**
	 * Sets the current listener to <code>listener</code>. Sends the given 
	 * <code>DropTargetEvent</code> if the current listener changes.
	 * 
	 * @return <code>true</code> if the new listener is different than the previous
	 *	<code>false</code> otherwise
	 */
	private boolean setCurrentListener(TransferDropTargetListener listener, final DropTargetEvent event) {
		if (currentListener == listener) 
			return false;
		if (currentListener != null) {
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {			
					currentListener.dragLeave(event);
				}
			});
		}
		currentListener = listener;
//		if (Policy.DEBUG_DRAG_DROP)
//			System.out.println("Current drop listener: " + listener); //$NON-NLS-1$
		if (currentListener != null) {
			Platform.run(new SafeRunnable() {
				public void run() throws Exception {			
					currentListener.dragEnter(event);
				}
			});
		}
		return true;
	}
	/**
	 * Updates the current listener to one that can handle the drop. There can be many
	 * listeners and each listener may be able to handle many <code>TransferData</code> 
	 * types. The first listener found that can handle a drop of one of the given 
	 * <code>TransferData</code> types will be selected.
	 * If no listener can handle the drag operation the <code>event.detail</code> field
	 * is set to <code>DND.DROP_NONE</code> to indicate an invalid drop.
	 *
	 * @param event the drop target event
	 */
	private void updateCurrentListener(DropTargetEvent event) {
		int originalDetail = event.detail;
		// revert the detail to the "original" drop type that the User indicated.
		// this is necessary because the previous listener may have changed the detail 
		// to something other than what the user indicated.
		event.detail = originalDropType;
	
		Iterator iter = listeners.iterator();
		while (iter.hasNext()) {
			TransferDropTargetListener listener = (TransferDropTargetListener) iter.next();
			TransferData dataType = getSupportedTransferType(event.dataTypes, listener); 
			if (dataType != null) {
				TransferData originalDataType = event.currentDataType;
				// set the data type supported by the drop listener
				event.currentDataType = dataType;
				if (listener.isEnabled(event)) {
					// if the listener stays the same, set its previously determined  
					// event detail 
					if (!setCurrentListener(listener, event))
						event.detail = originalDetail;
					return;
				} else {
					event.currentDataType = originalDataType;
				}				
			}			
		}
		setCurrentListener(null, event);
		event.detail = DND.DROP_NONE;
	}
}