/*******************************************************************************
 * 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.swt.dnd;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.widgets.*;

class TreeDragAndDropEffect extends DragAndDropEffect {
	Tree tree;
	
	int scrollIndex = -1;
	long scrollBeginTime;

	int expandIndex = -1;
	long expandBeginTime;
	
	static final int SCROLL_HYSTERESIS = 150; // milli seconds
	static final int EXPAND_HYSTERESIS = 300; // milli seconds

TreeDragAndDropEffect(Tree tree) {
	this.tree = tree;
}

int checkEffect(int effect) {
	// Some effects are mutually exclusive.  Make sure that only one of the mutually exclusive effects has been specified.
	if ((effect & DND.FEEDBACK_SELECT) != 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER & ~DND.FEEDBACK_INSERT_BEFORE;
	if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER;
	return effect;
}

Widget getItem(int x, int y) {
	Point coordinates = new Point(x, y);
	coordinates = tree.toControl(coordinates);
	TreeItem item = tree.getItem(coordinates);
	if (item == null) {
		Rectangle area = tree.getClientArea();
		if (area.contains(coordinates)) {
			// Scan across the width of the tree.
			for (int x1 = area.x; x1 < area.x + area.width; x1++) {
				Point pt = new Point(x1, coordinates.y);
				item = tree.getItem(pt);
				if (item != null) {
					break;
				}
			}
		}
	}
	return item;
}

ImageData getDragSourceImage(int x, int y) {
	if (OS.GTK_VERSION < OS.VERSION (2, 2, 0)) return null;
	/*
	* Bug in GTK.  gtk_tree_selection_get_selected_rows() segmentation faults
	* in versions smaller than 2.2.4 if the model is NULL.  The fix is
	* to give a valid pointer instead.
	*/
	int /*long*/ handle = tree.handle;
	int /*long*/ selection = OS.gtk_tree_view_get_selection (handle);
	int /*long*/ [] model = OS.GTK_VERSION < OS.VERSION (2, 2, 4) ? new int /*long*/ [1] : null;
	int /*long*/ list = OS.gtk_tree_selection_get_selected_rows (selection, model);
	if (list == 0) return null;
	int count = Math.min(10, OS.g_list_length (list));
	Image image = null;
	Display display = tree.getDisplay();
	if (count == 1) {
			int /*long*/ path = OS.g_list_nth_data (list, 0);
			int /*long*/ pixmap = OS.gtk_tree_view_create_row_drag_icon(handle, path);
			image =  Image.gtk_new(display, SWT.ICON, pixmap, 0); 
	} else {
		int width = 0, height = 0;
		int[] w = new int[1], h = new int[1];
		int[] yy = new int[count], hh = new int[count];
		int /*long*/ [] pixmaps = new int /*long*/ [count];
		GdkRectangle rect = new GdkRectangle ();
		for (int i=0; i<count; i++) {
			int /*long*/ path = OS.g_list_nth_data (list, i);
			OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
			pixmaps[i] = OS.gtk_tree_view_create_row_drag_icon(handle, path);
			OS.gdk_drawable_get_size(pixmaps[i], w, h);
			width = Math.max(width, w[0]);
			height = rect.y + h[0] - yy[0];
			yy[i] = rect.y;
			hh[i] = h[0];
		}
		int /*long*/ source = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, -1);
		int /*long*/ gcSource = OS.gdk_gc_new(source);
		int /*long*/ mask = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, 1);
		int /*long*/ gcMask = OS.gdk_gc_new(mask);
		GdkColor color = new GdkColor();
		color.pixel = 0;
		OS.gdk_gc_set_foreground(gcMask, color);
		OS.gdk_draw_rectangle(mask, gcMask, 1, 0, 0, width, height);
		color.pixel = 1;
		OS.gdk_gc_set_foreground(gcMask, color);
		for (int i=0; i<count; i++) {
			OS.gdk_draw_drawable(source, gcSource, pixmaps[i], 0, 0, 0, yy[i] - yy[0], -1, -1);
			OS.gdk_draw_rectangle(mask, gcMask, 1, 0, yy[i] - yy[0], width, hh[i]);
			OS.g_object_unref(pixmaps[i]);
		}
		OS.g_object_unref(gcSource);
		OS.g_object_unref(gcMask);
		 image  = Image.gtk_new(display, SWT.ICON, source, mask);
	}
	OS.g_list_free (list);
	
	ImageData imageData = image.getImageData();
	image.dispose();
	return imageData;
}

void showDropTargetEffect(int effect, int x, int y) {
	effect = checkEffect(effect);
	int /*long*/ handle = tree.handle;
	Point coordinates = new Point(x, y);
	coordinates = tree.toControl(coordinates);
	int /*long*/ [] path = new int /*long*/ [1];
	OS.gtk_tree_view_get_path_at_pos (handle, coordinates.x, coordinates.y, path, null, null, null);
	int index = -1;
	if (path[0] != 0) {
		int /*long*/ indices = OS.gtk_tree_path_get_indices(path[0]);
		if (indices != 0) {	
			int depth = OS.gtk_tree_path_get_depth(path[0]);
			int[] temp = new int[depth];
			OS.memmove (temp, indices, temp.length * 4);
			index = temp[temp.length - 1];
		}
	}
	if ((effect & DND.FEEDBACK_SCROLL) == 0) {
		scrollBeginTime = 0;
		scrollIndex = -1;
	} else {
		if (index != -1 && scrollIndex == index && scrollBeginTime != 0) {
			if (System.currentTimeMillis() >= scrollBeginTime) {
				GdkRectangle cellRect = new GdkRectangle ();
				OS.gtk_tree_view_get_cell_area (handle, path[0], 0, cellRect);
				if (cellRect.y < cellRect.height) {
					int[] tx = new int[1], ty = new int[1];
					OS.gtk_tree_view_widget_to_tree_coords(handle, cellRect.x, cellRect.y - cellRect.height, tx, ty);
					OS.gtk_tree_view_scroll_to_point (handle, -1, ty[0]);
				} else {
					//scroll down
					OS.gtk_tree_view_get_path_at_pos (handle, coordinates.x, coordinates.y + cellRect.height, path, null, null, null);
					if (path[0] != 0) {
						OS.gtk_tree_view_scroll_to_cell(handle, path[0], 0, false, 0, 0);
						OS.gtk_tree_path_free(path[0]);
						path[0] = 0;
					}
					OS.gtk_tree_view_get_path_at_pos (handle, coordinates.x, coordinates.y, path, null, null, null);	
				}
				scrollBeginTime = 0;
				scrollIndex = -1;
			}
		} else {
			scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
			scrollIndex = index;
		}
	}
	if ((effect & DND.FEEDBACK_EXPAND) == 0) {
		expandBeginTime = 0;
		expandIndex = -1;
	} else {
		if (index != -1 && expandIndex == index && expandBeginTime != 0) {
			if (System.currentTimeMillis() >= expandBeginTime) {
				OS.gtk_tree_view_expand_row (handle, path[0], false);
				expandBeginTime = 0;
				expandIndex = -1;
			}
		} else {
			expandBeginTime = System.currentTimeMillis() + EXPAND_HYSTERESIS;
			expandIndex = index;
		}
	}
	if (path[0] != 0) {
		int position = -1;
		if ((effect & DND.FEEDBACK_SELECT) != 0) position = OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
		if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE;
		if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0) position = OS.GTK_TREE_VIEW_DROP_AFTER;		
		if (position != -1) {
			OS.gtk_tree_view_set_drag_dest_row(handle, path[0], position);
		} else {
			OS.gtk_tree_view_unset_rows_drag_dest(handle);
		}
	} else {
		OS.gtk_tree_view_unset_rows_drag_dest(handle);
	}
	
	if (path[0] != 0) OS.gtk_tree_path_free (path [0]);
}
}
