/*
** 1998-09-12 -	A Move As command. Very useful.
** 1999-03-06 -	Adapted for the new selection/generic/dirrow representations.
*/

#include "gentoo.h"
#include "errors.h"
#include "fileutil.h"
#include "overwrite.h"
#include "progress.h"
#include "dirpane.h"
#include "strutil.h"
#include "cmd_move.h"
#include "cmd_generic.h"

#include "cmd_moveas.h"

#define	CMD_ID	"move as"

/* ----------------------------------------------------------------------------------------- */

typedef struct {
	GtkWidget	*vbox;
	GtkWidget	*label;
	GtkWidget	*entry;
	MainInfo	*min;
	gint		ovw_open;
} MvaInfo;

/* ----------------------------------------------------------------------------------------- */

/* 1998-09-12 -	Update body of copy as GUI. */
static void mva_body(MainInfo *min, DirPane *src, DirRow *row, GtkWindow *win, gpointer user)
{
	char	buf[FILENAME_MAX + 32];
	MvaInfo	*mva = (MvaInfo *) user;

	gtk_window_set_title(win, "Move As");
	sprintf(buf, "Enter name to move \"%s\" as:", DP_ROW_NAME(row));
	gtk_label_set_text(GTK_LABEL(mva->label), buf);
	gtk_entry_set_text(GTK_ENTRY(mva->entry), DP_ROW_NAME(row));
	gtk_entry_select_region(GTK_ENTRY(mva->entry), 0, -1);
	gtk_widget_grab_focus(mva->entry);

	if(mva->ovw_open == FALSE)
	{
		ovw_overwrite_begin(mva->min, "\"%s\" already exists - continue with move?", OVWF_HIDE);
		mva->ovw_open = TRUE;
	}
}

static int mva_action(MainInfo *min, DirPane *src, DirPane *dst, DirRow *row, gpointer user)
{
	char	dest[PATH_MAX], *text, *name;
	MvaInfo	*mva = (MvaInfo *) user;
	mode_t	mode;
	OvwRes	ores;

	if(!fut_cd(src->dir.path, NULL, 0))
		return 0;

	text = gtk_entry_get_text(GTK_ENTRY(mva->entry));
	if(text && *text)
	{
		if(strchr(text, '/') == NULL)
			g_snprintf(dest, sizeof dest, "%s/%s", dst->dir.path, text);
		else
			str_strncpy(dest, text, sizeof dest);
		ores = ovw_overwrite_file(mva->min, dest, dp_full_name(src, DP_ROW_INDEX(src, row)));
		if(ores == OVW_SKIP)
			return 1;
		else if(ores == OVW_CANCEL)
			return 0;
		pgs_progress_begin(min, "Move As", PFLG_COUNT_RECURSIVE | PFLG_ITEM_VISIBLE | PFLG_BYTE_VISIBLE);
		name = DP_ROW_NAME(row);
		if(rename(name, dest) == -1)	/* Rename failed? */
		{
			if(errno == EXDEV)		/* Rename across devices attempted? */
			{
				err_clear(min);
				mode = DP_ROW_LSTAT(row).st_mode;
				if(S_ISLNK(mode))
					move_link(min, name, dest);
				else if(S_ISDIR(mode))
					move_dir(min, name, dest);
				else if(S_ISREG(mode))
					move_file(min, name, dest, &DP_ROW_LSTAT(row));
				else if(S_ISCHR(mode) || S_ISBLK(mode))
					move_device(min, name, dest, &DP_ROW_LSTAT(row));
			}
		}
		pgs_progress_end(min);
	}
	dp_unselect(src, DP_ROW_INDEX(src, row));

	return errno == 0;
}

static void mva_free(gpointer user)
{
	MvaInfo	*mva = (MvaInfo *) user;

	if(mva->ovw_open)
		ovw_overwrite_end(mva->min);
}

/* 1998-09-12 -	The move as generic command function. */
int cmd_moveas(MainInfo *min, DirPane *src, DirPane *dst, CmdArg *ca)
{
	static MvaInfo	mva;

	mva.min	     = min;
	mva.ovw_open = FALSE;

	mva.vbox = gtk_vbox_new(FALSE, 0);
	mva.label = gtk_label_new("Move As");
	mva.entry = gtk_entry_new_with_max_length(FILENAME_MAX - 1);
	gtk_box_pack_start(GTK_BOX(mva.vbox), mva.label, FALSE, FALSE, 0);
	gtk_widget_show(mva.label);
	gtk_box_pack_start(GTK_BOX(mva.vbox), mva.entry, FALSE, FALSE, 0);
	gtk_widget_show(mva.entry);

	return cmd_generic(min, CGF_NOALL | CGF_SRC, mva_body, mva_action, mva_free, &mva);
}
