/*******************************************************************************
 * Copyright (c) 2000, 2016 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.swt.snippets;

/*
 * Drag and Drop example snippet: drag and drop an object with a
 * custom data transfer type from SWT to AWT/Swing
 *
 * Note that JRE 1.6 or newer is required on Linux.
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 */
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetListener;
import java.io.*;
import java.util.*;

import javax.swing.*;

import org.eclipse.swt.*;
import org.eclipse.swt.awt.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

public class Snippet319 {

	/* The data flavor must be MIME type-like */
	static final String MIME_TYPE = "custom/myType"; // $NON-NLS-1$

	/* The object being transferred is defined as: */
	static class MyType {
		String name;
		long time;
	}

public static void main(String[] args) {
	new Snippet319().go();
}

public void go() {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setBounds(10,10,600,200);

	/* Create SWT controls and add drag source */
	final Label swtLabel = new Label(shell, SWT.BORDER);
	swtLabel.setBounds(10,10,580,50);
	swtLabel.setText("SWT drag source");
	DragSource dragSource = new DragSource(swtLabel, DND.DROP_COPY);
	dragSource.setTransfer(new MyTypeTransfer());
	dragSource.addDragListener(new DragSourceAdapter() {
		@Override
		public void dragSetData(DragSourceEvent event) {
			MyType object = new MyType();
			object.name = "content dragged from SWT";
			object.time = System.currentTimeMillis();
			event.data = object;
		}
	});

	/* Create AWT/Swing controls */
	Composite embeddedComposite = new Composite(shell, SWT.EMBEDDED);
	embeddedComposite.setBounds(10, 100, 580, 50);
	embeddedComposite.setLayout(new FillLayout());
	Frame frame = SWT_AWT.new_Frame(embeddedComposite);
	final JLabel jLabel = new JLabel("AWT/Swing drop target");
	frame.add(jLabel);

	/* Register the custom data flavour */
	final DataFlavor flavor = new DataFlavor(MIME_TYPE, "MyType custom flavor");
	/*
	 * Note that according to jre/lib/flavormap.properties, the preferred way to
	 * augment the default system flavor map is to specify the AWT.DnD.flavorMapFileURL
	 * property in an awt.properties file.
	 *
	 * This snippet uses the alternate approach below in order to provide a simple
	 * stand-alone snippet that demonstrates the functionality.  This implementation
	 * works well, but if the instanceof check below fails for some reason when used
	 * in a different context then the drop will not be accepted.
	 */
	FlavorMap map = SystemFlavorMap.getDefaultFlavorMap();
	if (map instanceof SystemFlavorMap) {
		SystemFlavorMap systemMap = (SystemFlavorMap)map;
		systemMap.addFlavorForUnencodedNative(MIME_TYPE, flavor);
	}

	/* add drop target */
	DropTargetListener dropTargetListener = new DropTargetAdapter() {
		@Override
		public void drop(DropTargetDropEvent dropTargetDropEvent) {
			try {
				dropTargetDropEvent.acceptDrop(DnDConstants.ACTION_COPY);
				ByteArrayInputStream inStream = (ByteArrayInputStream)dropTargetDropEvent.getTransferable().getTransferData(flavor);
				int available = inStream.available();
				byte[] bytes = new byte[available];
				inStream.read(bytes);
				MyType object = restoreFromByteArray(bytes);
				String string = object.name + ": " + new Date(object.time).toString();
				jLabel.setText(string);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
	new DropTarget(jLabel, dropTargetListener);

	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
	display.dispose();
}


/* SWT custom data transfer implementation */

class MyTypeTransfer extends ByteArrayTransfer {

	final int MIME_TYPE_ID = registerType(MIME_TYPE);

	@Override
	protected int[] getTypeIds() {
		return new int[] {MIME_TYPE_ID};
	}

	@Override
	protected String[] getTypeNames() {
		return new String[] {MIME_TYPE};
	}

@Override
public void javaToNative(Object object, TransferData transferData) {
	if (!checkMyType(object) || !isSupportedType(transferData)) {
		DND.error(DND.ERROR_INVALID_DATA);
	}
	MyType myType = (MyType)object;
	byte[] bytes = convertToByteArray(myType);
	if (bytes != null) {
		super.javaToNative(bytes, transferData);
	}
}

@Override
public Object nativeToJava(TransferData transferData) {
	if (!isSupportedType(transferData)) return null;
	byte[] bytes = (byte[])super.nativeToJava(transferData);
	return bytes == null ? null : restoreFromByteArray(bytes);
}

boolean checkMyType(Object object) {
	if (object == null) return false;
	MyType myType = (MyType)object;
	return myType != null && myType.name != null && myType.name.length() > 0 && myType.time > 0;
}

@Override
protected boolean validate(Object object) {
	return checkMyType(object);
}
}


/* shared methods for converting instances of MyType <-> byte[] */

static byte[] convertToByteArray(MyType type) {
	DataOutputStream dataOutStream = null;
	try {
		ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
		dataOutStream = new DataOutputStream(byteOutStream);
		byte[] bytes = type.name.getBytes();
		dataOutStream.writeInt(bytes.length);
		dataOutStream.write(bytes);
		dataOutStream.writeLong(type.time);
		return byteOutStream.toByteArray();
	} catch (IOException e) {
		return null;
	} finally {
		if (dataOutStream != null) {
			try {
				dataOutStream.close();
			} catch (IOException e) {}
		}
	}
}

static MyType restoreFromByteArray(byte[] bytes) {
	DataInputStream dataInStream = null;
	try {
		ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
		dataInStream = new DataInputStream(byteInStream);
		int size = dataInStream.readInt();
		byte[] name = new byte[size];
		dataInStream.read(name);
		MyType result = new MyType();
		result.name = new String(name);
		result.time = dataInStream.readLong();
		return result;
	} catch (IOException ex) {
		return null;
	} finally {
		if (dataInStream != null) {
			try {
				dataInStream.close();
			} catch (IOException e) {}
		}
	}
}

}
