/*******************************************************************************
 * Copyright (c) 2000, 2013 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 leaf items in a tree
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 */
import org.eclipse.swt.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class Snippet91 {

public static void main (String [] args) {

	final Display display = new Display ();
	final Shell shell = new Shell (display);
	shell.setLayout(new FillLayout());
	final Tree tree = new Tree(shell, SWT.BORDER);
	for (int i = 0; i < 3; i++) {
		TreeItem item = new TreeItem(tree, SWT.NONE);
		item.setText("item "+i);
		for (int j = 0; j < 3; j++) {
			TreeItem subItem = new TreeItem(item, SWT.NONE);
			subItem.setText("item "+i+" "+j);
			for (int k = 0; k < 3; k++) {
				TreeItem subsubItem = new TreeItem(subItem, SWT.NONE);
				subsubItem.setText("item "+i+" "+j+" "+k);
			}
		}
	}

	Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
	int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;

	final DragSource source = new DragSource (tree, operations);
	source.setTransfer(types);
	final TreeItem[] dragSourceItem = new TreeItem[1];
	source.addDragListener (new DragSourceListener () {
		@Override
		public void dragStart(DragSourceEvent event) {
			TreeItem[] selection = tree.getSelection();
			if (selection.length > 0 && selection[0].getItemCount() == 0) {
				event.doit = true;
				dragSourceItem[0] = selection[0];
			} else {
				event.doit = false;
			}
		}
		@Override
		public void dragSetData (DragSourceEvent event) {
			event.data = dragSourceItem[0].getText();
		}
		@Override
		public void dragFinished(DragSourceEvent event) {
			if (event.detail == DND.DROP_MOVE)
				dragSourceItem[0].dispose();
				dragSourceItem[0] = null;
		}
	});

	DropTarget target = new DropTarget(tree, operations);
	target.setTransfer(types);
	target.addDropListener (new DropTargetAdapter() {
		@Override
		public void dragOver(DropTargetEvent event) {
			event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
			if (event.item != null) {
				TreeItem item = (TreeItem)event.item;
				Point pt = display.map(null, tree, event.x, event.y);
				Rectangle bounds = item.getBounds();
				if (pt.y < bounds.y + bounds.height/3) {
					event.feedback |= DND.FEEDBACK_INSERT_BEFORE;
				} else if (pt.y > bounds.y + 2*bounds.height/3) {
					event.feedback |= DND.FEEDBACK_INSERT_AFTER;
				} else {
					event.feedback |= DND.FEEDBACK_SELECT;
				}
			}
		}
		@Override
		public void drop(DropTargetEvent event) {
			if (event.data == null) {
				event.detail = DND.DROP_NONE;
				return;
			}
			String text = (String)event.data;
			if (event.item == null) {
				TreeItem item = new TreeItem(tree, SWT.NONE);
				item.setText(text);
			} else {
				TreeItem item = (TreeItem)event.item;
				Point pt = display.map(null, tree, event.x, event.y);
				Rectangle bounds = item.getBounds();
				TreeItem parent = item.getParentItem();
				if (parent != null) {
					TreeItem[] items = parent.getItems();
					int index = 0;
					for (int i = 0; i < items.length; i++) {
						if (items[i] == item) {
							index = i;
							break;
						}
					}
					if (pt.y < bounds.y + bounds.height/3) {
						TreeItem newItem = new TreeItem(parent, SWT.NONE, index);
						newItem.setText(text);
					} else if (pt.y > bounds.y + 2*bounds.height/3) {
						TreeItem newItem = new TreeItem(parent, SWT.NONE, index+1);
						newItem.setText(text);
					} else {
						TreeItem newItem = new TreeItem(item, SWT.NONE);
						newItem.setText(text);
					}

				} else {
					TreeItem[] items = tree.getItems();
					int index = 0;
					for (int i = 0; i < items.length; i++) {
						if (items[i] == item) {
							index = i;
							break;
						}
					}
					if (pt.y < bounds.y + bounds.height/3) {
						TreeItem newItem = new TreeItem(tree, SWT.NONE, index);
						newItem.setText(text);
					} else if (pt.y > bounds.y + 2*bounds.height/3) {
						TreeItem newItem = new TreeItem(tree, SWT.NONE, index+1);
						newItem.setText(text);
					} else {
						TreeItem newItem = new TreeItem(item, SWT.NONE);
						newItem.setText(text);
					}
				}


			}
		}
	});

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