/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jface.util;

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

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>
 * @since 3.0
 */
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) {
            SafeRunnable.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) {
        	SafeRunnable.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) {
        	SafeRunnable.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) {
        	SafeRunnable.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) {
        	SafeRunnable.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) {
        	SafeRunnable.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;
                }
				event.currentDataType = originalDataType;
            }
        }
        setCurrentListener(null, event);
        event.detail = DND.DROP_NONE;
    }
}
