/*******************************************************************************
 * Copyright (c) 2000, 2006 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.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;

/**
 * A <code>DelegatingDragAdapter</code> is a <code>DragSourceListener</code> that  
 * maintains and delegates to a set of {@link TransferDragSourceListener}s. Each 
 * TransferDragSourceListener can then be implemented as if it were the 
 * <code>DragSource's</code> only DragSourceListener.
 * <p>
 * When a drag is started, a subset of all <code>TransferDragSourceListeners</code>
 * is generated and stored in a list of <i>active</i> listeners. This subset is
 * calculated by forwarding {@link DragSourceListener#dragStart(DragSourceEvent)} to 
 * every listener, and checking if the {@link DragSourceEvent#doit doit} field is left 
 * set to <code>true</code>.
 * </p> 
 * The <code>DragSource</code>'s set of supported Transfer types ({@link
 * DragSource#setTransfer(Transfer[])}) is updated to reflect the Transfer types
 * corresponding to the active listener subset.
 * <p>
 * If and when {@link #dragSetData(DragSourceEvent)} is called, a single
 * <code>TransferDragSourceListener</code> is chosen, and only it is allowed to set the
 * drag data. The chosen listener is the first listener in the subset of active listeners
 * whose Transfer supports ({@link Transfer#isSupportedType(TransferData)}) the 
 * <code>dataType</code> in the <code>DragSourceEvent</code>.
 * </p>
 * <p>
 * The following example snippet shows a <code>DelegatingDragAdapter</code> with two
 * <code>TransferDragSourceListeners</code>. One implements drag of text strings, 
 * the other supports file transfer and demonstrates how a listener can be disabled using
 * the dragStart method. 
 * </p>
 * <code><pre>
 *		final TreeViewer viewer = new TreeViewer(shell, SWT.NONE);
 *		
 *		DelegatingDragAdapter dragAdapter = new DelegatingDragAdapter();		
 *		dragAdapter.addDragSourceListener(new TransferDragSourceListener() {
 *			public Transfer getTransfer() {
 *				return TextTransfer.getInstance();
 *			}
 *			public void dragStart(DragSourceEvent event) {
 *				// always enabled, can control enablement based on selection etc.
 *			}
 *			public void dragSetData(DragSourceEvent event) {
 *				event.data = "Transfer data";
 *			}
 *			public void dragFinished(DragSourceEvent event) {
 *				// no clean-up required
 *			}
 *		});
 *		dragAdapter.addDragSourceListener(new TransferDragSourceListener() {
 *			public Transfer getTransfer() {
 *				return FileTransfer.getInstance();
 *			}
 *			public void dragStart(DragSourceEvent event) {
 *				// enable drag listener if there is a viewer selection
 *				event.doit = !viewer.getSelection().isEmpty();
 *			}
 *			public void dragSetData(DragSourceEvent event) {
 *				File file1 = new File("C:/temp/file1");
 *				File file2 = new File("C:/temp/file2");
 *				event.data = new String[] {file1.getAbsolutePath(), file2.getAbsolutePath()};
 *			}
 *			public void dragFinished(DragSourceEvent event) {
 *				// no clean-up required
 *			}
 *		});
 *		viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, dragAdapter.getTransfers(), dragAdapter);
 * </pre></code>
 * @since 3.0
 */
public class DelegatingDragAdapter implements DragSourceListener {
    private List listeners = new ArrayList();

    private List activeListeners = new ArrayList();

    private TransferDragSourceListener currentListener;

    /**
     * Adds the given <code>TransferDragSourceListener</code>.
     * 
     * @param listener the new listener
     */
    public void addDragSourceListener(TransferDragSourceListener listener) {
        listeners.add(listener);
    }

    /**
     * The drop has successfully completed. This event is forwarded to the current 
     * drag listener.
     * Doesn't update the current listener, since the current listener  is already the one
     * that completed the drag operation.
     * 
     * @param event the drag source event
     * @see DragSourceListener#dragFinished(DragSourceEvent)
     */
    public void dragFinished(final DragSourceEvent event) {
        //		if (Policy.DEBUG_DRAG_DROP)
        //			System.out.println("Drag Finished: " + toString()); //$NON-NLS-1$
        SafeRunnable.run(new SafeRunnable() {
            public void run() throws Exception {
                if (currentListener != null) {
                    // there is a listener that can handle the drop, delegate the event
                    currentListener.dragFinished(event);
                } else {
                    // The drag was canceled and currentListener was never set, so send the
                    // dragFinished event to all the active listeners. 
                    Iterator iterator = activeListeners.iterator();
                    while (iterator.hasNext()) {
						((TransferDragSourceListener) iterator.next())
                                .dragFinished(event);
					}
                }
            }
        });
        currentListener = null;
        activeListeners.clear();
    }

    /**
     * The drop data is requested.
     * Updates the current listener and then forwards the event to it.
     * 
     * @param event the drag source event
     * @see DragSourceListener#dragSetData(DragSourceEvent)
     */
    public void dragSetData(final DragSourceEvent event) {
        //		if (Policy.DEBUG_DRAG_DROP)
        //			System.out.println("Drag Set Data: " + toString()); //$NON-NLS-1$

        updateCurrentListener(event); // find a listener that can provide the given data type
        if (currentListener != null) {
        	SafeRunnable.run(new SafeRunnable() {
                public void run() throws Exception {
                    currentListener.dragSetData(event);
                }
            });
        }
    }

    /**
     * A drag operation has started.
     * Forwards this event to each listener. A listener must set <code>event.doit</code> 
     * to <code>false</code> if it cannot handle the drag operation. If a listener can  
     * handle the drag, it is added to the list of active listeners.  
     * The drag is aborted if there are no listeners that can handle it.  
     * 
     * @param event the drag source event
     * @see DragSourceListener#dragStart(DragSourceEvent)
     */
    public void dragStart(final DragSourceEvent event) {
        //		if (Policy.DEBUG_DRAG_DROP)
        //			System.out.println("Drag Start: " + toString()); //$NON-NLS-1$
        boolean doit = false; // true if any one of the listeners can handle the drag
        List transfers = new ArrayList(listeners.size());

        activeListeners.clear();
        for (int i = 0; i < listeners.size(); i++) {
            final TransferDragSourceListener listener = (TransferDragSourceListener) listeners
                    .get(i);
            event.doit = true; // restore event.doit
            SafeRunnable.run(new SafeRunnable() {
                public void run() throws Exception {
                    listener.dragStart(event);
                }
            });
            if (event.doit) { // the listener can handle this drag
                transfers.add(listener.getTransfer());
                activeListeners.add(listener);
            }
            doit |= event.doit;
        }

        if (doit) {
			((DragSource) event.widget).setTransfer((Transfer[]) transfers
                    .toArray(new Transfer[transfers.size()]));
		}

        event.doit = doit;
    }

    /**
     * Returns the <code>Transfer<code>s from every <code>TransferDragSourceListener</code>.
     * 
     * @return the combined <code>Transfer</code>s
     */
    public Transfer[] getTransfers() {
        Transfer[] types = new Transfer[listeners.size()];
        for (int i = 0; i < listeners.size(); i++) {
            TransferDragSourceListener listener = (TransferDragSourceListener) listeners
                    .get(i);
            types[i] = listener.getTransfer();
        }
        return types;
    }

    /**
     * Returns <code>true</code> if there are no listeners to delegate drag events to.
     * 
     * @return <code>true</code> if there are no <code>TransferDragSourceListeners</code>
     * 	<code>false</code> otherwise.
     */
    public boolean isEmpty() {
        return listeners.isEmpty();
    }

    /**
     * Removes the given <code>TransferDragSourceListener</code>.
     * Listeners should not be removed while a drag and drop operation is in progress.
     *  
     * @param listener the <code>TransferDragSourceListener</code> to remove
     */
    public void removeDragSourceListener(TransferDragSourceListener listener) {
        listeners.remove(listener);
        if (currentListener == listener) {
			currentListener = null;
		}
        if (activeListeners.contains(listener)) {
			activeListeners.remove(listener);
		}
    }

    /**
     * Updates the current listener to one that can handle the drag. There can 
     * be many listeners and each listener may be able to handle many <code>TransferData</code> 
     * types.  The first listener found that supports one of the <code>TransferData</ode> 
     * types specified in the <code>DragSourceEvent</code> will be selected.
     * 
     * @param event the drag source event
     */
    private void updateCurrentListener(DragSourceEvent event) {
        currentListener = null;
        if (event.dataType == null) {
			return;
		}
        Iterator iterator = activeListeners.iterator();
        while (iterator.hasNext()) {
            TransferDragSourceListener listener = (TransferDragSourceListener) iterator
                    .next();

            if (listener.getTransfer().isSupportedType(event.dataType)) {
                //				if (Policy.DEBUG_DRAG_DROP)
                //					System.out.println("Current drag listener: " + listener); //$NON-NLS-1$			
                currentListener = listener;
                return;
            }
        }
    }

}
