/*
** 1998-06-07 -	A command to set the owner and group information on a file
**		(or set of files). Might get GUI-ish.
** 1998-06-08 -	Fixed the userinfo module, which allowed this one to take another
**		step towards completetion; now it preselects the current user/group
**		names from the option menus. I still miss some form of higher-level
**		control widgetry, though. Later...
** 1998-10-16 -	The defaults now work (even if you don't operate the menus).
** 1999-03-06 -	Adapted for new selection/generic/dirrow representations.
*/

#include "gentoo.h"
#include "errors.h"
#include "dirpane.h"
#include "userinfo.h"

#include "cmd_generic.h"
#include "cmd_chown.h"

#define	CMD_ID	"chown"

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

typedef struct {
	GtkWidget	*label;
	GtkWidget	*menu;
	GtkWidget	*optmenu;
	gint		history;			/* The weirdly named thing (see gtk_option_menu widget). */
} URow;

typedef struct {
	GtkWidget	*vbox;
	GtkWidget	*label;
	GtkWidget	*rowtable;
	URow		row[2];
	int		user, group;			/* The currently selected IDs. */
	gint		user_index, group_index;	/* Indices to default to. */
} ChoInfo;

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

static void cho_body(MainInfo *min, DirPane *src, DirRow *row, GtkWindow *win, gpointer user)
{
	gchar	label[MAXNAMLEN + 64];
	ChoInfo	*cho = (ChoInfo *) user;

	gtk_window_set_title(win, "Change ownership");
	g_snprintf(label, sizeof label, "Set ownership for '%s':", DP_ROW_NAME(row));
	gtk_label_set_text(GTK_LABEL(cho->label), label);
}

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

static int cho_action(MainInfo *min, DirPane *src, DirPane *dst, DirRow *row, gpointer user)
{
	ChoInfo	*cho = (ChoInfo *) user;
	gchar	name[PATH_MAX];

	g_snprintf(name, sizeof name, "%s/%s", src->dir.path, DP_ROW_NAME(row));

	if(chown(name, (uid_t) cho->user, (gid_t) cho->group))
		err_set(min, errno, CMD_ID, DP_ROW_NAME(row));
	else
		dp_unselect(src, DP_ROW_INDEX(src, row));

	return errno == 0;
}

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

static gint evt_chown_user(GtkWidget *wid, gpointer user)
{
	ChoInfo	*cho = (ChoInfo *) user;

	cho->user = (int) gtk_object_get_user_data(GTK_OBJECT(wid));

	return TRUE;
}

static gint evt_chown_group(GtkWidget *wid, gpointer user)
{
	ChoInfo	*cho = (ChoInfo *) user;

	cho->group = (int) gtk_object_get_user_data(GTK_OBJECT(wid));

	return TRUE;
}

int cmd_chown(MainInfo *min, DirPane *src, DirPane *dst, CmdArg *ca)
{
	char		*label[] = { "User", "Group" };
	GtkWidget	*menu[2];
	int		i;
	static ChoInfo	cho;

	if((cho.vbox = gtk_vbox_new(FALSE, 0)) != NULL)
	{
		if((cho.label = gtk_label_new("")) != NULL)
		{
			gtk_box_pack_start(GTK_BOX(cho.vbox), cho.label, FALSE, FALSE, 0);
			if((cho.rowtable = gtk_table_new(2, 2, FALSE)) != NULL)
			{
				gtk_box_pack_start(GTK_BOX(cho.vbox), cho.rowtable, FALSE, FALSE, 5);
				gtk_widget_show(cho.label);
				gtk_widget_show(cho.rowtable);

				menu[0] = usr_build_menu(UIM_USER,  (GtkSignalFunc) evt_chown_user,  &cho, geteuid(), &cho.row[0].history);
				cho.user = (int) geteuid();
				menu[1] = usr_build_menu(UIM_GROUP, (GtkSignalFunc) evt_chown_group, &cho, getgid(), &cho.row[1].history);
				cho.group = (int) getgid();

				for(i = 0; i < 2; i++)
				{
					cho.row[i].label = gtk_label_new(label[i]);
					gtk_table_attach_defaults(GTK_TABLE(cho.rowtable), cho.row[i].label, 0, 1, i, i+1);
					gtk_widget_show(cho.row[i].label);
					cho.row[i].menu = menu[i];
					cho.row[i].optmenu = gtk_option_menu_new();
					gtk_option_menu_set_menu(GTK_OPTION_MENU(cho.row[i].optmenu), cho.row[i].menu);
					gtk_option_menu_set_history(GTK_OPTION_MENU(cho.row[i].optmenu), cho.row[i].history);
					gtk_table_attach_defaults(GTK_TABLE(cho.rowtable), cho.row[i].optmenu, 1, 2, i, i+1);
					gtk_widget_show(cho.row[i].optmenu);
				}
				return cmd_generic(min, CGF_NODST, cho_body, cho_action, NULL, &cho);
			}
		}
	}
	return 0;
}
