package org.eclipse.swt.dnd;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.motif.*;

/**
 *
 * Class <code>DropTarget</code> defines the target object for a drag and drop transfer.
 *
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 *
 * <p>This class identifies the <code>Control</code> over which the user must position the cursor
 * in order to drop the data being transferred.  It also specifies what data types can be dropped on 
 * this control and what operations can be performed.  You may have several DropTragets in an 
 * application but there can only be a one to one mapping between a <code>Control</code> and a <code>DropTarget</code>.
 * The DropTarget can receive data from within the same application or from other applications 
 * (such as text dragged from a text editor like Word).</p>
 *
 * <code><pre>
 *	int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
 *	Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
 *	DropTarget target = new DropTarget(label, operations);
 *	target.setTransfer(types);
 * </code></pre>
 *
 * <p>The application is notified of data being dragged over this control and of when a drop occurs by 
 * implementing the interface <code>DropTargetListener</code> which uses the class 
 * <code>DropTargetEvent</code>.  The application can modify the type of drag being performed 
 * on this Control at any stage of the drag by modifying the <code>event.detail</code> field or the 
 * <code>event.currentDataType</code> field.  When the data is dropped, it is the responsibility of 
 * the application to copy this data for its own purposes.
 *
 * <code><pre>
 *	target.addDropListener (new DropTargetListener() {
 *		public void dragEnter(DropTargetEvent event) {};
 *		public void dragOver(DropTargetEvent event) {};
 *		public void dragLeave(DropTargetEvent event) {};
 *		public void dragOperationChanged(DropTargetEvent event) {};
 *		public void dropAccept(DropTargetEvent event) {}
 *		public void drop(DropTargetEvent event) {
 *			// A drop has occurred, copy over the data
 *			if (event.data == null) { // no data to copy, indicate failure in event.detail
 *				event.detail = DND.DROP_NONE;
 *				return;
 *			}
 *			label.setText ((String) event.data); // data copied to label text
 *		}
 * 	});
 * </pre></code>
 *
 * <dl>
 *	<dt><b>Styles</b> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK 
 *	<dt><b>Events</b> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged, 
 *                        DND.Drop, DND.DropAccept
 * </dl>
 */ 
public class DropTarget extends Widget {
	
	private Callback dropProc;
	private Callback transferProc;
	private Callback dragProc;
	
	// info for registering as a droptarget	
	private Control control;
	private Listener controlListener;
	private Transfer[] transferAgents = new Transfer[0];
	
	// info about data being dragged over site
	private TransferData selectedDataType;
	private TransferData[] dataTypes;
	private int dropTransferObject;
	private XmDropProcCallback droppedEventData;
	
	private DragUnderEffect effect;
	
	private static final int DRAGOVER_HYSTERESIS = 50;
	private long dragOverStart;
	private Runnable dragOverHeartbeat;
	private DNDEvent dragOverEvent;
	
/**
 * Creates a new <code>DropTarget</code> to handle dropping on the specified <code>Control</code>.
 * 
 * @param control the <code>Control</code> over which the user positions the cursor to drop data
 *
 * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of 
 *					DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
 *
 */
public DropTarget(Control control, int style) {

	super (control, checkStyle(style));
	
	this.control = control;
	
	dropProc = new Callback(this, "dropProcCallback", 3);
	if (dropProc == null)
		DND.error(DND.ERROR_CANNOT_INIT_DROP);

	dragProc = new Callback(this, "dragProcCallback", 3);
	if (dragProc == null)
		DND.error(DND.ERROR_CANNOT_INIT_DROP);
		
	int[] args = new int[]{
		OS.XmNdropSiteOperations, opToOsOp(style),
		OS.XmNdropSiteActivity,   OS.XmDROP_SITE_ACTIVE,
		OS.XmNdropProc,           dropProc.getAddress(),
		OS.XmNdragProc,           dragProc.getAddress(),
		OS.XmNanimationStyle,     OS.XmDRAG_UNDER_NONE,
		OS.XmNdropSiteType,       OS.XmDROP_SITE_COMPOSITE,
	};

	// the OS may have registered this widget as a drop site on creation.
	// Remove the registered drop site because it has preconfigured values which we do not want.
	//OS.XmDropSiteUnregister(control.handle);
	// Register drop site with our own values
	OS.XmDropSiteRegister(control.handle, args, args.length / 2);

	controlListener = new Listener () {
		public void handleEvent (Event event) {
			if (!DropTarget.this.isDisposed()){
				DropTarget.this.dispose();
			}
		}
	};
	control.addListener (SWT.Dispose, controlListener);
	
	this.addListener (SWT.Dispose, new Listener () {
		public void handleEvent (Event event) {
			onDispose();
		}
	});
	
	if (control instanceof Tree) {
		effect = new TreeDragUnderEffect((Tree)control);
	} else if (control instanceof Table) {
		effect = new TableDragUnderEffect((Table)control);
	} else {
		effect = new NoDragUnderEffect(control);
	}
}
/**	 
 * Adds the listener to receive events.
 *
 * @param listener the listener
 *
 * @exception SWTError 
 *	<ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 * 		<li>ERROR_WIDGET_DISPOSED  when the widget has been disposed</li>
 * 		<li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void addDropListener(DropTargetListener listener) {	
	if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
	DNDListener typedListener = new DNDListener (listener);
	addListener (DND.DragEnter, typedListener);
	addListener (DND.DragLeave, typedListener);
	addListener (DND.DragOver, typedListener);
	addListener (DND.DragOperationChanged, typedListener);
	addListener (DND.Drop, typedListener);
	addListener (DND.DropAccept, typedListener);

}
static int checkStyle (int style) {
	if (style == SWT.NONE) return DND.DROP_MOVE;
	return style;
}
private void updateDragOverHover(long delay, DNDEvent event) {
	if (delay == 0) {
		dragOverStart = 0;
		dragOverEvent = null;
		dragOverHeartbeat = null;
		return;
	}
	dragOverStart = System.currentTimeMillis() + delay;
	if (dragOverEvent == null) dragOverEvent = new DNDEvent();
	dragOverEvent.x = event.x;
	dragOverEvent.y = event.y;
	dragOverEvent.dataTypes  = event.dataTypes;
	dragOverEvent.operations = event.operations;
	dragOverEvent.dataType  = event.dataType;
	dragOverEvent.detail  = event.detail;
}
private int dragProcCallback(int widget, int client_data, int call_data) {

	XmDragProcCallback callbackData = new XmDragProcCallback();
	OS.memmove(callbackData, call_data, XmDragProcCallback.sizeof);

	if (callbackData.reason == OS.XmCR_DROP_SITE_ENTER_MESSAGE){
		releaseDropInfo();
		
		// get the export targets
		int ppExportTargets = OS.XtMalloc(4);
		int pNumExportTargets = OS.XtMalloc(4);
		int[] args = new int[]{
			OS.XmNexportTargets,          ppExportTargets,
			OS.XmNnumExportTargets,       pNumExportTargets
		};

		OS.XtGetValues(callbackData.dragContext, args, args.length / 2);
		int[] numExportTargets = new int[1];
		OS.memmove(numExportTargets, pNumExportTargets, 4);
		OS.XtFree(pNumExportTargets);
		int[] pExportTargets = new int[1];
		OS.memmove(pExportTargets, ppExportTargets, 4);
		OS.XtFree(ppExportTargets);
		int[] exportTargets = new int[numExportTargets[0]];
		OS.memmove(exportTargets, pExportTargets[0], 4*numExportTargets[0]);
		//?OS.XtFree(pExportTargets[0]);

		for (int i = 0, length = exportTargets.length; i < length; i++){
			for (int j = 0, length2 = transferAgents.length; j < length2; j++){
				TransferData transferData = new TransferData();
				transferData.type = exportTargets[i];
				if (transferAgents[j].isSupportedType(transferData)) {
					TransferData[] newDataTypes = new TransferData[dataTypes.length + 1];
					System.arraycopy(dataTypes, 0, newDataTypes, 0, dataTypes.length);
					newDataTypes[dataTypes.length] = transferData;
					dataTypes = newDataTypes;
					break;
				}
			}
		}
	}

	DNDEvent event = new DNDEvent();
	event.widget     = this.control;
	event.time       = callbackData.timeStamp;
	short [] root_x = new short [1];
	short [] root_y = new short [1];
	OS.XtTranslateCoords (this.control.handle, (short) callbackData.x, (short) callbackData.y, root_x, root_y);
	event.x          = root_x[0];
	event.y          = root_y[0];
	event.dataTypes  = dataTypes;
	event.feedback = DND.FEEDBACK_SELECT;
	event.operations = osOpToOp(callbackData.operations);
	event.dataType  = selectedDataType;
	event.detail  = osOpToOp(callbackData.operation);

	try {
		switch (callbackData.reason) {
			case OS.XmCR_DROP_SITE_ENTER_MESSAGE :
				if (dataTypes.length > 0) {
					event.dataType = dataTypes[0];
				}
				dragOverHeartbeat = new Runnable() {
					public void run() {
						if (control.isDisposed() || dragOverStart == 0) return;
						long time = System.currentTimeMillis();
						int delay = DRAGOVER_HYSTERESIS;
						if (time >= dragOverStart) {
							DNDEvent event = new DNDEvent();
							event.widget = control;
							event.time = (int)time;
							event.x = dragOverEvent.x;
							event.y = dragOverEvent.y;
							event.dataTypes  = dragOverEvent.dataTypes;
							event.feedback = DND.FEEDBACK_SELECT;
							event.operations = dragOverEvent.operations;
							event.dataType  = dragOverEvent.dataType;
							event.detail  = dragOverEvent.detail;
							notifyListeners(DND.DragOver, event);
							effect.show(event.feedback, event.x, event.y);
						} else {
							delay = (int)(dragOverStart - time);
						}
						control.getDisplay().timerExec(delay, dragOverHeartbeat);
					}
				};
				updateDragOverHover(DRAGOVER_HYSTERESIS, event);
				
				notifyListeners(DND.DragEnter, event);
				effect.show(event.feedback, event.x, event.y);
				dragOverHeartbeat.run();
				break;
			
			case OS.XmCR_DROP_SITE_MOTION_MESSAGE :
				updateDragOverHover(DRAGOVER_HYSTERESIS, event);
				notifyListeners(DND.DragOver, event);
				effect.show(event.feedback, event.x, event.y);
				break;
			case OS.XmCR_OPERATION_CHANGED :
				updateDragOverHover(DRAGOVER_HYSTERESIS, event);
				notifyListeners(DND.DragOperationChanged, event);
				effect.show(event.feedback, event.x, event.y);
				break;
			case OS.XmCR_DROP_SITE_LEAVE_MESSAGE :
				event.detail  = DND.DROP_NONE;
				updateDragOverHover(0, null);
				notifyListeners(DND.DragLeave, event);
				effect.show(DND.FEEDBACK_NONE, 0, 0);
				return 0;
		}
	} catch (Throwable err) {
		callbackData.dropSiteStatus = OS.XmDROP_SITE_INVALID;
		callbackData.operation = opToOsOp(DND.DROP_NONE);
		OS.memmove(call_data, callbackData, XmDragProcCallback.sizeof);
		return 0;
	}
	
	selectedDataType = null;
	for (int i = 0; i < dataTypes.length; i++) {
		if (dataTypes[i].equals(event.dataType)) {
			selectedDataType = event.dataType;
			break;
		}
	}
	int lastOperation = DND.DROP_NONE;
	if (selectedDataType != null && ((event.detail & osOpToOp(callbackData.operations)) == event.detail)) {
		lastOperation = event.detail;
	}
	
	callbackData.dropSiteStatus = OS.XmDROP_SITE_VALID;
	callbackData.operation = opToOsOp(lastOperation);
	OS.memmove(call_data, callbackData, XmDragProcCallback.sizeof);

	return 0;
}
private int dropProcCallback(int widget, int client_data, int call_data) {
	updateDragOverHover(0, null);
	effect.show(DND.FEEDBACK_NONE, 0, 0);
	
	droppedEventData = new XmDropProcCallback();
	OS.memmove(droppedEventData, call_data, XmDropProcCallback.sizeof);	
	
	DNDEvent event = new DNDEvent();
	event.widget     = this.control;
	event.time       = droppedEventData.timeStamp;
	short [] root_x = new short [1];
	short [] root_y = new short [1];
	OS.XtTranslateCoords (this.control.handle, (short) droppedEventData.x, (short) droppedEventData.y, root_x, root_y);
	event.x          = root_x[0];
	event.y          = root_y[0];
	event.dataTypes  = dataTypes;
	event.operations = osOpToOp(droppedEventData.operations);
	event.dataType   = selectedDataType;
	event.detail     = osOpToOp(droppedEventData.operation);

	try {
		notifyListeners(DND.DropAccept,event);
	} catch (Throwable err) {
		event.detail = DND.DROP_NONE;
		event.dataType = null;
	}
	
	selectedDataType = null;
	for (int i = 0; i < dataTypes.length; i++) {
		if (dataTypes[i].equals(event.dataType)) {
			selectedDataType = event.dataType;
			break;
		}
	}
	int lastOperation = DND.DROP_NONE;
	if (selectedDataType != null && ((event.detail & osOpToOp(droppedEventData.operations)) == event.detail)) {
		lastOperation = event.detail;
	}
	
	if (lastOperation == DND.DROP_NONE) {
		// this was not a successful drop
		int[] args = new int[] {OS.XmNtransferStatus, OS.XmTRANSFER_FAILURE,
					OS.XmNnumDropTransfers, 0};
		dropTransferObject = OS.XmDropTransferStart(droppedEventData.dragContext, args, args.length / 2);
		return 0;
	}

	// ask drag source for dropped data
	int[] transferEntries = new int[2];
	transferEntries[0]  = 0;
	transferEntries[1] = selectedDataType.type;
		
	int pTransferEntries = OS.XtMalloc(transferEntries.length * 4);
	OS.memmove(pTransferEntries, transferEntries, transferEntries.length * 4);
	if (transferProc == null)
		transferProc = new Callback(this, "transferProcCallback", 7);

	if (transferProc != null){
		int[] args = new int[] {OS.XmNdropTransfers, pTransferEntries,
					OS.XmNnumDropTransfers, transferEntries.length / 2,
					OS.XmNtransferProc, transferProc.getAddress()};

		dropTransferObject = OS.XmDropTransferStart(droppedEventData.dragContext, args, args.length / 2);
		OS.XtFree(pTransferEntries);
	}

	return 0;
}
/**
 * Returns the Control which is registered for this DropTarget.  This is the control over which the 
 * user positions the cursor to drop the data.
 *
 * @return the Control which is registered for this DropTarget
 *
 */
public Control getControl () {
	return control;
}
public Display getDisplay () {

	if (control == null) DND.error(SWT.ERROR_WIDGET_DISPOSED);
	return control.getDisplay ();
}
/**
 * Returns the list of data types that can be transferred to this DropTarget.
 *
 * @return the list of data types that can be transferred to this DropTarget
 *
 */ 
public Transfer[] getTransfer(){
	return transferAgents;
}
public void notifyListeners (int eventType, Event event) {
	Point coordinates = new Point(event.x, event.y);
	coordinates = control.toControl(coordinates);
	if (this.control instanceof Tree) {
		event.item = ((Tree)control).getItem(coordinates);
	}
	if (this.control instanceof Table) {
		event.item = ((Table)control).getItem(coordinates);
	}
	super.notifyListeners(eventType, event);
}
private void onDispose() {
	
	if (dropProc != null)
		dropProc.dispose();
	dropProc = null;

	if (transferProc != null)
		transferProc.dispose();
	transferProc = null;

	if (dragProc != null)
		dragProc.dispose();
	dragProc = null;
	//if (control != null && !control.isDisposed()){
	//	OS.XmDropSiteUnregister(control.handle);
	//}
	if (controlListener != null) {
		control.removeListener(SWT.Dispose, controlListener);
	}
	controlListener = null;
	control = null;
	transferAgents = null;
}
private byte opToOsOp(int operation){
	byte osOperation = OS.XmDROP_NOOP;
	
	if ((operation & DND.DROP_COPY) == DND.DROP_COPY)
		osOperation |= OS.XmDROP_COPY;
	if ((operation & DND.DROP_MOVE) == DND.DROP_MOVE)
		osOperation |= OS.XmDROP_MOVE;
	if ((operation & DND.DROP_LINK) == DND.DROP_LINK)
		osOperation |= OS.XmDROP_LINK;
	
	return osOperation;
}
private int osOpToOp(byte osOperation){
	int operation = DND.DROP_NONE;
	
	if ((osOperation & OS.XmDROP_COPY) == OS.XmDROP_COPY)
		operation |= DND.DROP_COPY;
	if ((osOperation & OS.XmDROP_MOVE) == OS.XmDROP_MOVE)
		operation |= DND.DROP_MOVE;
	if ((osOperation & OS.XmDROP_LINK) == OS.XmDROP_LINK)
		operation |= DND.DROP_LINK;
	
	return operation;
}
private void releaseDropInfo(){
	selectedDataType = null;
	dataTypes = new TransferData[0];
	droppedEventData = null;
	dropTransferObject = 0;
}
/**	 
 * Removes the listener.
 *
 * @param listener the listener
 *
 * @exception SWTError
 *	<ul><li>ERROR_THREAD_INVALID_ACCESS	when called from the wrong thread</li>
 * 		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * 		<li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void removeDropListener(DropTargetListener listener) {	
	if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
	removeListener (DND.DragEnter, listener);
	removeListener (DND.DragLeave, listener);
	removeListener (DND.DragOver, listener);
	removeListener (DND.DragOperationChanged, listener);
	removeListener (DND.Drop, listener);
	removeListener (DND.DropAccept, listener);
}
/**
 * Specifies the list of data types that can be transferred to this DropTarget.
 *
 * @param transferAgents a list of Transfer objects which define the types of data that can be
 *						 dropped on this target
 */
public void setTransfer(Transfer[] transferAgents){
	this.transferAgents = transferAgents;
			
	// register data types
	TransferData[] transferData = new TransferData[0];
	for (int i = 0, length = transferAgents.length; i < length; i++){
		TransferData[] data = transferAgents[i].getSupportedTypes();
		TransferData[] newTransferData = new TransferData[transferData.length +  data.length];
		System.arraycopy(transferData, 0, newTransferData, 0, transferData.length);
		System.arraycopy(data, 0, newTransferData, transferData.length, data.length);
		transferData = newTransferData;
	}
	
	int[] atoms = new int[transferData.length];
	for (int i = 0, length = transferData.length; i < length; i++){
		atoms[i] = transferData[i].type;
	}

	// Copy import targets to global memory 
	int pImportTargets = OS.XtMalloc(atoms.length * 4);
	OS.memmove(pImportTargets, atoms, atoms.length * 4);

	int[] args = new int[]{
		OS.XmNimportTargets,      pImportTargets,
		OS.XmNnumImportTargets,   atoms.length
	};

	OS.XmDropSiteUpdate(control.handle, args, args.length / 2);
	
	OS.XtFree(pImportTargets);
	
}
private int transferProcCallback(int widget, int client_data, int pSelection, int pType, int pValue, int pLength, int pFormat) {
	
	int[] type = new int[1];
	OS.memmove(type, pType, 4);

	// get dropped data object
	Transfer transferAgent = null;
	TransferData transferData = new TransferData();
	transferData.type = type[0];
	for (int i = 0; i < transferAgents.length; i++){
		if (transferAgents[i].isSupportedType(transferData)){
			transferAgent = transferAgents[i];
			break;
		}
	}
	if (transferAgent != null) {
		transferData.pValue = pValue;
		int[] length = new int[1];
		OS.memmove(length, pLength, 4);
		transferData.length = length[0];
		int[] format = new int[1];
		OS.memmove(format, pFormat, 4);
		transferData.format = format[0];
		Object data = transferAgent.nativeToJava(transferData);
		
		OS.XtFree(transferData.pValue); //?? Should we be freeing this, and what about the other memory?
	
		// notify listeners of drop
		DNDEvent event = new DNDEvent();
		event.widget     = this.control;
		event.time       = droppedEventData.timeStamp;
		short [] root_x = new short [1];
		short [] root_y = new short [1];
		OS.XtTranslateCoords (this.control.handle, (short) droppedEventData.x, (short) droppedEventData.y, root_x, root_y);
		event.x          = root_x[0];
		event.y          = root_y[0];
		event.dataTypes  = dataTypes;
		event.operations = osOpToOp(droppedEventData.operations);
		event.dataType = transferData;
		event.detail     = osOpToOp(droppedEventData.operation);
		event.data       = data;

		try {
			notifyListeners(DND.Drop,event);
		} catch (Throwable err) {
			event.detail = DND.DROP_NONE;
		}

		if ((event.detail & DND.DROP_MOVE) == DND.DROP_MOVE) {
			OS.XmDropTransferAdd(dropTransferObject, new int[]{0, Transfer.registerType("DELETE\0")}, 1);
		}
	}

	return 0;
}

protected void checkSubclass () {
	String name = getClass().getName ();
	String validName = DropTarget.class.getName();
	if (!validName.equals(name)) {
		DND.error (SWT.ERROR_INVALID_SUBCLASS);
	}
}
}
