#include "ftptool.h"

#ifdef XVIEW3

static int remote_drag;
static int local_drag;

#ifdef USE_PROTOTYPES
void remote_drop(Xv_Window window, Event *event, Selection_requestor sel)
#else
void remote_drop(window, event, sel)
Xv_Window	window;
Event 		*event;
Selection_requestor	sel;
#endif
{
	Xv_drop_site	ds;
	int		length, format;
	static int i;
	int		nitems;
	int		*string_length;
	char	*filename;
	char	*hostname;
	Xv_Server	server = XV_SERVER_FROM_WINDOW(event_window(event));
	
	if ((ds = dnd_decode_drop(sel, event)) == XV_ERROR) {
		footer_message("Decode drop failed.", (char *)NULL);
		return;
	}

	if (remote_drag) {
		footer_message("Ignoring drag & drop on same window",
			(char *)NULL);
	} else if (!connected) {
		footer_message("Not connected",
			(char *)NULL);
	} else if (dnd_is_local(event)){
		dowhat = DOPUT;
		notify_stop();
	} else {
		footer_message("Can only handle local drops",
			(char *)NULL);
	}

#ifdef notdef
	xv_set(sel, 
		SEL_TYPE_NAME, "_SUN_ENUMERATION_COUNT", 
		NULL);

	string_length = (int *)xv_get(sel, SEL_DATA, &length, &format);
	if (length != SEL_ERROR) {
		nitems = *string_length;
		free ((char *)string_length);
	}

	for (i = 0; i < nitems; i++) {
			
		xv_set(sel,
			SEL_TYPE, xv_get(server, SERVER_ATOM, "_SUN_ENUMERATION_ITEM"),
			SEL_TYPE_INDEX, 0,
			SEL_PROP_TYPE, XA_INTEGER,
			SEL_PROP_DATA, &i,
			SEL_PROP_FORMAT, 32,
			SEL_PROP_LENGTH, 1,
			NULL);

		(void)xv_get(sel, SEL_DATA, &length, &format);

		xv_set(sel, 
			SEL_TYPE, xv_get(server, SERVER_ATOM, "FILE_NAME"), 
			NULL);

		filename = (char *)xv_get(sel, SEL_DATA, &length, &format);
		if (length != SEL_ERROR) {
			free (filename);
		}

		/* XXX */
		/* Care about remote host drops? Probably. */
		xv_set(sel, 
			SEL_TYPE, xv_get(server, SERVER_ATOM, "HOST_NAME"), 
			NULL);

		hostname = (char *)xv_get(sel, SEL_DATA, &length, &format);
		if (length != SEL_ERROR) {
			free (hostname);
		}

	}
	xv_set(sel,
		SEL_TYPE_NAME, "_SUN_SELECTION_END",
		NULL);

	(void)xv_get(sel, SEL_DATA, &length, &format);
#endif

	dnd_done(sel);

}

static void (*remote_list_event_func)();

#ifdef USE_PROTOTYPES
void get_remote_list_event_proc(void)
#else
void get_remote_list_event_proc()
#endif
{
	remote_list_event_func = (void (*)())xv_get(base_window.list, 
		PANEL_EVENT_PROC);
	if (remote_list_event_func == (void (*)())NULL) {
		fprintf(stderr, "ftptool: could not get default list eventproc!\n");
		exit(1);
	}
}

#ifdef USE_PROTOTYPES
void remote_list_event(Panel_item item, Event *event)
#else
void remote_list_event(item, event)
Panel_item	item;
Event 		*event;
#endif
{
	short	mask;
	static int drag_pixels;

	switch(event_action(event)) {
	case ACTION_SELECT:
		if (!event_is_down(event)) {
			drag_pixels = 0;
		}
		break;
	case ACTION_ADJUST:
		/* XXX: translate ACTION_ADJUST to ACTION_SELECT, so they can still */
		/* use ADJUST to drag-select items on the list */
		event_set_action(event, ACTION_SELECT);
		break;
	case LOC_DRAG:
		/* XXX: translate ACTION_ADJUST to ACTION_SELECT, so they can still */
		/* use ADJUST to drag-select items on the list */
		if (action_adjust_is_down(event)) {
			mask = event_shiftmask(event);
			mask &= ~MS_MIDDLE_MASK;
			mask |= MS_LEFT_MASK;
			event_set_shiftmask(event, mask);
			drag_pixels = 0;
		} else if (action_select_is_down(event)) {
			if (connected 
				&& (remote_list_nfiles+remote_list_ndirs+remote_list_nothers)
				&& (drag_pixels++ >= drag_threshold)) {
				/* source the drag */
				remote_drag = 1;
				switch (dnd_send_drop(base_window.dnd)) {
				case XV_OK:
					break;
				case DND_TIMEOUT:
					footer_message("Drag and Drop: Timed out", 
						(char *)NULL);
					break;
				case DND_ILLEGAL_TARGET:
					footer_message("Drag and Drop: Illegal target", 
						(char *)NULL);
					break;
				case DND_SELECTION:
					footer_message("Drag and Drop: Bad selection", 
						(char *)NULL);
					break;
				case DND_ROOT:
					dowhat = DOREMOTEVIEW;
					notify_stop();
					break;
				case XV_ERROR:
					footer_message("Drag and Drop: Failed", 
						(char *)NULL);
					break;
				}
				remote_drag = 0;
				drag_pixels = 0;
				return;
			} 
		} else {
			drag_pixels = 0;
		}
		break;
	default:
		break;
	}
	(*remote_list_event_func)(item, event);
}

#ifdef USE_PROTOTYPES
void local_drop(Xv_Window window, Event *event, Selection_requestor sel)
#else
void local_drop(window, event, sel)
Xv_Window	window;
Event 		*event;
Selection_requestor	sel;
#endif
{
	Xv_drop_site	ds;
	int		length, format;
	static int i;
	int		nitems;
	int		*string_length;
	char	*filename;
	char	*hostname;
	Xv_Server	server = XV_SERVER_FROM_WINDOW(event_window(event));
	
	if ((ds = dnd_decode_drop(sel, event)) == XV_ERROR) {
		footer_message("Decode drop failed.", (char *)NULL);
		return;
	}

	if (local_drag) {
		local_footer_message("Ignoring drag & drop on same window",
			(char *)NULL);
	} else if (dnd_is_local(event)) {
		dowhat = DOGET;
		notify_stop();
	} else {
		local_footer_message("Can only handle local drops",
			(char *)NULL);
	}


#ifdef notdef
	xv_set(sel, 
		SEL_TYPE_NAME, "_SUN_ENUMERATION_COUNT", 
		NULL);

	string_length = (int *)xv_get(sel, SEL_DATA, &length, &format);
	if (length != SEL_ERROR) {
		nitems = *string_length;
		free ((char *)string_length);
	}

	for (i = 0; i < nitems; i++) {
			
		xv_set(sel,
			SEL_TYPE, xv_get(server, SERVER_ATOM, "_SUN_ENUMERATION_ITEM"),
			SEL_TYPE_INDEX, 0,
			SEL_PROP_TYPE, XA_INTEGER,
			SEL_PROP_DATA, &i,
			SEL_PROP_FORMAT, 32,
			SEL_PROP_LENGTH, 1,
			NULL);

		(void)xv_get(sel, SEL_DATA, &length, &format);

		xv_set(sel, 
			SEL_TYPE, xv_get(server, SERVER_ATOM, "FILE_NAME"), 
			NULL);

		filename = (char *)xv_get(sel, SEL_DATA, &length, &format);
		if (length != SEL_ERROR) {
			free (filename);
		}

		/* XXX */
		/* Care about remote host drops? Probably. */
		xv_set(sel, 
			SEL_TYPE, xv_get(server, SERVER_ATOM, "HOST_NAME"), 
			NULL);

		hostname = (char *)xv_get(sel, SEL_DATA, &length, &format);
		if (length != SEL_ERROR) {
			free (hostname);
		}

	}
	xv_set(sel,
		SEL_TYPE_NAME, "_SUN_SELECTION_END",
		NULL);

	(void)xv_get(sel, SEL_DATA, &length, &format);
#endif

	dnd_done(sel);

}

static void (*local_list_event_func)();

#ifdef USE_PROTOTYPES
void get_local_list_event_proc(void)
#else
void get_local_list_event_proc()
#endif
{
	local_list_event_func = (void (*)())xv_get(base_window.list, 
		PANEL_EVENT_PROC);
	if (local_list_event_func == (void (*)())NULL) {
		fprintf(stderr, "ftptool: could not get default list eventproc!\n");
		exit(1);
	}
}

#ifdef USE_PROTOTYPES
void local_list_event(Panel_item item, Event *event)
#else
void local_list_event(item, event)
Panel_item	item;
Event 		*event;
#endif
{
	short	mask;
	static int		drag_pixels;

	switch(event_action(event)) {
	case ACTION_SELECT:
		break;
	case ACTION_ADJUST:
		/* XXX: translate ACTION_ADJUST to ACTION_SELECT, so they can still */
		/* use ADJUST to drag-select items on the list */
		event_set_action(event, ACTION_SELECT);
		break;
	case LOC_DRAG:
		/* XXX: translate ACTION_ADJUST to ACTION_SELECT, so they can still */
		/* use ADJUST to drag-select items on the list */
		if (action_adjust_is_down(event)) {
			mask = event_shiftmask(event);
			mask &= ~MS_MIDDLE_MASK;
			mask |= MS_LEFT_MASK;
			event_set_shiftmask(event, mask);
			drag_pixels = 0;
		} else if (action_select_is_down(event)) {
			if ((local_list_nfiles+local_list_ndirs+local_list_nothers)
				&& (drag_pixels++ >= drag_threshold)) {
				/* source the drag */
				local_drag = 1;
				switch (dnd_send_drop(local_window.dnd)) {
				case XV_OK:
					break;
				case DND_TIMEOUT:
					local_footer_message("Drag and Drop: Timed out", 
						(char *)NULL);
					break;
				case DND_ILLEGAL_TARGET:
					local_footer_message("Drag and Drop: Illegal target", 
						(char *)NULL);
					break;
				case DND_SELECTION:
					local_footer_message("Drag and Drop: Bad selection", 
						(char *)NULL);
					break;
				case DND_ROOT:
					dowhat = DOLOCALVIEW;
					notify_stop();
					break;
				case XV_ERROR:
					footer_message("Drag and Drop: Failed", 
						(char *)NULL);
					break;
				}
				local_drag = 0;
				drag_pixels = 0;
				return;
			}
		} else {
			drag_pixels = 0;
		}
		break;
	default:
		break;
	}
	(*local_list_event_func)(item, event);
}

#endif
