#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>

#include "../include/disk.h"

#include "cdialog.h"

#include "cfg.h"
#include "edvtypes.h"
#include "edvobj.h"
#include "edvrecbin.h"
#include "edvrecbinfio.h"
#include "edvutils.h"
#include "endeavour.h"
#include "edvconfirm.h"
#include "edvutilsgtk.h"
#include "edvcfglist.h"
#include "config.h"


#include "images/icon_copy_file_32x32.xpm"
#include "images/icon_move_file_32x32.xpm"
#include "images/icon_link2_32x32.xpm"
#include "images/icon_trash_32x32.xpm"
#include "images/icon_archive_add_32x32.xpm"
#include "images/icon_archive_extract_32x32.xpm"
#include "images/icon_recover_32x32.xpm"
#include "images/icon_purge_32x32.xpm"


gint EDVConfirmLink(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
);
gint EDVConfirmMove(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
);
gint EDVConfirmCopy(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
);
gint EDVConfirmDelete(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects
);

gint EDVConfirmArchiveAdd(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *arch_path
);
gint EDVConfirmArchiveExtract(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
);
gint EDVConfirmArchiveDelete(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects
);

gint EDVConfirmRecover(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path,		/* String containing index number */
	gint total_objects,
	const gchar *tar_path
);
gint EDVConfirmPurge(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path,		/* String containing index number */
	gint total_objects
);

gint EDVConfirmDND(
	edv_core_struct *core_ptr,
	gint gdk_action, guint info,
	GtkWidget *toplevel,
	GList *url_list,
	const gchar *tar_path
);


#define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
#define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)       (((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define STRLEN(s)       (((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)   (((s) != NULL) ? (*(s) == '\0') : TRUE)


static gchar *G_STRCAT(gchar *s, const gchar *s2)
{ 
	if(s != NULL) {
	    if(s2 != NULL) {
		gchar *sr = g_strconcat(s, s2, NULL);
		g_free(s);
		s = sr;
	    }
	} else {
	    if(s2 != NULL)
		s = STRDUP(s2);
	    else
		s = STRDUP("");
	}
	return(s);
}


/*
 *	Confirm link.
 *
 *	Returns one of CDIALOG_RESPONSE_*.
 *	Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *	specifies no confirmation for this operation.
 */
gint EDVConfirmLink(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;

	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_LINK
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme El Eslabón"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Le Lien"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Kettenglied"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare La Maglia"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Schakel"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Elo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Link"
#else
"Confirm Link"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"El Eslabón:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Le Lien:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Kettenglied:\n\
\n\
    %s\n\
\n\
Zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Maglia:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schakel:\n\
\n\
    %s\n\
\n\
Te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Elo:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Ledd:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#else
"Link:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#endif
		, src_path, tar_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"El eslabón %i se opone a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Le lien %i s'oppose à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Verknüpfen sie %i objekte zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Concatenare %i oggetti a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Verbind %i voorwerpen te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Ligue %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Forbind %i objekt til:\n\
\n\
    %s\n"
#else
"Link %i objects to:\n\
\n\
    %s\n"
#endif
		, total_objects, tar_path
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_link2_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);	/* Delete message */

	return(response);
}

/*
 *      Confirm move.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmMove(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;

	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_MOVE
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Mueva"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Le Mouvement"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Bewegung"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare Il Movimento"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Beweging"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Move"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Move"
#else
"Confirm Move"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Mueva:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Le Mouvement:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bewegung:\n\
\n\
    %s\n\
\n\
Zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Movimento:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Beweging:\n\
\n\
    %s\n\
\n\
Te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Mova:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Trekk:\n\
\n\
    %s\n\
\n\
Til:\n\
\n\
    %s\n"
#else
"Move:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#endif
		, src_path, tar_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Mueva %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Le mouvement %i s'oppose à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bewegen Sie %i Objekte zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Muovere %i oggetti a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Beweeg %i voorwerpen te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Mova %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Flytt %i objekt til:\n\
\n\
    %s\n"
#else
"Move %i objects to:\n\
\n\
    %s\n"
#endif
		, total_objects, tar_path
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_move_file_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);    /* Delete message */

	return(response);
}

/*
 *      Confirm copy.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmCopy(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_COPY
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Copia"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer la Copie"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Kopie"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare La Copia"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Kopie"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Cópia"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Copy"
#else
"Confirm Copy"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"La Copia:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Copie:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Kopie:\n\
\n\
    %s\n\
\n\
Zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Copia:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Kopie:\n\
\n\
    %s\n\
\n\
Te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Cópia:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Kopi:\n\
\n\
    %s\n\
\n\
Til:\n\
\n\
    %s\n"
#else
"Copy:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#endif
		, src_path, tar_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"La copia %i se opone a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"La copie %i s'oppose à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Kopieren Sie %i Objekte zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Copiare %i oggetti a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Kopieer %i voorwerpen te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Copie %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Kopier %i objekt til:\n\
\n\
    %s\n"
#else
"Copy %i objects to:\n\
\n\
    %s\n"
#endif
		, total_objects, tar_path
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_copy_file_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);    /* Delete message */

	return(response);
}

/*
 *      Confirm delete or purge.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmDelete(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects
)
{
	gint response;
	const gchar *title;
	gchar *buf;
	gint delete_method;
	guint8 **icon_data = (guint8 **)icon_trash_32x32_xpm;
	const cfg_item_struct *cfg_list;

	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	cfg_list = core_ptr->cfg_list;

	if(!CFGItemListGetValueI(
	    cfg_list, EDV_CFG_PARM_CONFIRM_DELETE
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Get delete method */
	delete_method = CFGItemListGetValueI(
	    cfg_list, EDV_CFG_PARM_DELETE_METHOD
	);


	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Borre"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Effacer"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Löscht"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare Cancellare"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Schrappet"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Anula"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Delete"
#else
"Confirm Delete"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	{
	    const gchar *name = EDVGetPathName(src_path);
	    if(ISLPATHDIR(src_path))
		buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Borre Guía:\n\
\n\
    %s\n\
\n\
Inclusive cualquier contenido dentro de esa guía.\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Effacer L'Annuaire:\n\
\n\
    %s\n\
\n\
Y compris n'importe quels contenus dans cet annuaire.\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Löschen Sie Verzeichnis:\n\
\n\
    %s\n\
\n\
Irgendeines Inhalts innerhalb jenes Verzeichnisses.\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Cancellare L'Elenco:\n\
\n\
    %s\n\
\n\
Includere qualunque contenuto entro quell'elenco.\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schrap Gids:\n\
\n\
    %s\n\
\n\
Inclusief enig inhoud's binnen dat gids.\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Anule Guia:\n\
\n\
    %s\n\
\n\
Incluir qualquer conteúdo dentro daquele guia.\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stryk Directory:\n\
\n\
    %s\n\
\n\
Including noe innhold innenfor den katalogen.\n"
#else
"Delete directory \"%s\"?\n\
\n\
Including any contents within that directory.\n"
#endif
		    , name
		);
	    else
		buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Borre:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Effacer:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Löschen Sie:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Cancellare:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schrap:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Anule:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stryk:\n\
\n\
    %s\n"
#else
"Delete object \"%s\"?\n"
#endif
		    , name
		);
	}
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"¿Borra %i objetos escogidos?\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Efface %i des objets choisis?\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Löschen Sie %i ausgewählte Objekte?\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Cancella %i oggetti scelti?\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schrap %i geselecteerde voorwerpen?\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Anule %i objetos selecionados?\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stryk %i valgte ut objekt?\n"
#else
"Delete %i selected objects?\n"
#endif
		, total_objects
	    );

	/* If the delete method is EDV_DELETE_METHOD_PURGE then append
	 * message indicating that this is a permanent delete
	 */
	if(delete_method == EDV_DELETE_METHOD_PURGE)
	{
	    buf = G_STRCAT(
		buf,
#if defined(PROG_LANGUAGE_SPANISH)
"\n¡Usted no será capaz de recuperar el object(s)\n\
una vez ellos han sido borrados!\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"\nVous ne pourrez pas retrouver le object(s)\n\
une fois ils ont été effacés!\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"\nSie sind das objekt(s) einmal sie nicht gelöscht\n\
worden werden wiedererlangen können!\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"\nLei non sarà in grado di ricuperare l'oggetto(s)\n\
una volta sono stato cancellati!\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"\nU zijn het voorwerp(s) eenmaal zij niet\n\
geschrappet zult kunnen terugkrijgen!\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"\nVocê nao será capaz de recuperar o objeto(s) vez\n\
uma que eles foram anulados!\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"\nDe er ikke kyndig utvinne objektet(s) en gang\n\
de strøket!\n"
#else
"\nYou will not be able to recover the object(s)\n\
once they have been deleted!\n"
#endif
	    );
	    /* Use purge icon instead of delete icon since we are 
	     * permanently purging object(s)
	     */
	    icon_data = (guint8 **)icon_purge_32x32_xpm;
	}

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL, icon_data,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);    /* Delete message */

	return(response);
}

/*
 *      Confirm adding of disk object(s) to an archive.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmArchiveAdd(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *arch_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_ARCHIVE_ADD
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Agregue"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Ajouter"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Hinzufügt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare Aggiungere"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Toevoegt"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Adiciona"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Add"
#else
"Confirm Add"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Agregue:\n\
\n\
    %s\n\
\n\
Al Archivo:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Ajouter:\n\
\n\
    %s\n\
\n\
A L'Archive:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Fügen Sie Hinzu:\n\
\n\
    %s\n\
\n\
Zu Archiv:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Aggiungere:\n\
\n\
    %s\n\
\n\
All'Archivio:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Toevoeg:\n\
\n\
    %s\n\
\n\
Aan Archief:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Adicione:\n\
\n\
    %s\n\
\n\
A Arquivo:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Tilføy:\n\
\n\
    %s\n\
\n\
Til Archive:\n\
\n\
    %s\n"
#else
"Add:\n\
\n\
    %s\n\
\n\
To Archive:\n\
\n\
    %s\n"
#endif
		, src_path, arch_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Agregue %i objetos al archivo:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Ajouter %i des objets à l'archive:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Fügen Sie Archiv %i Objekte hinzu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Aggiungere %i oggetti all'archivio:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Voeg aan archief %i voorwerpen toe:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Adicione %i objetos a arquivo:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Tilføy %i objekt til arkiv:\n\
\n\
    %s\n"
#else
"Add %i objects to archive:\n\
\n\
    %s\n"
#endif
		, total_objects, arch_path
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_archive_add_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);	/* Delete message */

	return(response);
}

/*
 *      Confirm extracting of archive object(s) to from an archive
 *	to the target disk object path.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmArchiveExtract(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects,
	const gchar *tar_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_ARCHIVE_EXTRACT
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme El Extracto"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer L'Extrait"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Extrakt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare L'Estratto"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Extract"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Extrai"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Extract"
#else
"Confirm Extract"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"El Extracto:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Extrait:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Extrakt:\n\
\n\
    %s\n\
\n\
Zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Estratto:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Extract:\n\
\n\
    %s\n\
\n\
Te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Extraia:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Extrakt:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#else
"Extract:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#endif
		, src_path, tar_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"El extracto %i los objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Extrait %i les objets à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Extrahieren Sie %i Objekte zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Estrarre %i oggetti a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Onttrek %i voorwerpen te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Extraia %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Trekk ut %i objekt til:\n\
\n\
    %s\n"
#else
"Extract %i objects to:\n\
\n\
    %s\n"
#endif
		, total_objects, tar_path
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_archive_extract_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);	/* Delete message */

	return(response);
}

/*
 *      Confirm delete archive object.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmArchiveDelete(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects
)
{
	gint response;
	const gchar *title;
	gchar *buf;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_ARCHIVE_DELETE
	))
	    return(CDIALOG_RESPONSE_YES);

	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Borre"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Effacer"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Löscht"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare Cancellare"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Schrappet"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Anula"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Delete"
#else
"Confirm Delete"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Borre:\n\
\n\
    %s\n\
\n\
¡Este objeto en el archivo no se puede recuperar una\n\
vez se ha borrado!\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Effacer:\n\
\n\
    %s\n\
\n\
Cet objet dans l'archive ne peut pas être retrouvé une\n\
fois il a été effacé!\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Löschen Sie:\n\
\n\
    %s\n\
\n\
Dieses Objekt im Archiv ist einmal es nicht gelöscht\n\
worden kann wiedererlangt werden!\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Cancellare:\n\
\n\
    %s\n\
\n\
Quest'oggetto nell'archivio non può essere ricuperato\n\
una volta è stato cancellato!\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schrap:\n\
\n\
    %s\n\
\n\
Deze voorwerp in het archief is niet eenmaal het\n\
geschrappet kan, is teruggekregen!\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Anule:\n\
\n\
    %s\n\
\n\
Este objeto no arquivo nao pode ser recuperado vez\n\
uma que foi anulado!\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stryk:\n\
\n\
    %s\n\
\n\
This objekt i arkivet utvunnet ikke en eneste gang\n\
som det stryker!\n"
#else
"Delete:\n\
\n\
    %s\n\
\n\
This object in the archive cannot be recovered once\n\
it has been deleted!\n"
#endif
		, src_path
	    );
	else
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"¿Borra %i objetos escogidos?\n\
\n\
¡Estos objetos en el archivo no se pueden recuperar una\n\
vez ellos han sido borrados!\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Efface %i objets choisis?\n\
\n\
Ces objets dans l'archive ne peuvent pas être retrouvés\n\
une fois ils ont été effacés!\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Löschen Sie %i ausgewählte objekte?\n\
\n\
Diese Objekte im Archiv sind einmal sie nicht gelöscht\n\
worden können wiedererlangt werden!\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Cancella %i oggetti scelti?\n\
\n\
Questi oggetti nell'archivio non possono essere\n\
ricuperati una volta sono stato cancellati!\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Schrap %i geselecteerde voorwerpen?\n\
\n\
Deze voorwerpen in het archief zijn niet eenmaal zij\n\
geschrappet kunnen, is teruggekregen!\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Anule %i objetos selecionados?\n\
\n\
Estes objetos no arquivo nao podem ser recuperados vez\n\
uma que eles foram anulados!\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stryk %i valgte ut objekt?\n\
\n\
Disse objektene i arkivet utvunnet ikke en eneste gang\n\
som de strøket!\n"
#else
"Delete %i selected objects?\n\
\n\
These objects in the archive cannot be recovered once\n\
they have been deleted!\n"
#endif
		, total_objects
	    );

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_purge_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);	/* Delete message */

	return(response);
}


/*
 *      Confirm recovering of a recycled object.
 *
 *	Note that src_path is actually a string containing the recycled
 *	object index number.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmRecover(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path,		/* String containing index number */
	gint total_objects,
	const gchar *tar_path
)
{
	gint response;
	const gchar *title;
	gchar *buf;
	const gchar *recycled_index_file;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_RECOVER
	))
	    return(CDIALOG_RESPONSE_YES);


	/* Get path to recycled objects index file */
	recycled_index_file = CFGItemListGetValueS(
	    core_ptr->cfg_list, EDV_CFG_PARM_FILE_RECYCLED_INDEX
	);


	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Recupere"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer Retrouver"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Wiedererlangt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare Ricuperare"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Terugkrijgt"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Recupera"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Recover"
#else
"Confirm Recover"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	{
	    edv_recbin_object_struct *rec_obj = EDVRecBinObjectStat(
		recycled_index_file, atoi(src_path)
	    );
	    if((rec_obj != NULL) ? (rec_obj->name != NULL) : FALSE)
		buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Recupere:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Retrouver:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Erlangen Sie Wieder:\n\
\n\
    %s\n\
\n\
Zu:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Ricuperare:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Krijg Terug:\n\
\n\
    %s\n\
\n\
Te:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Recupere:\n\
\n\
    %s\n\
\n\
A:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Utvinn:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#else
"Recover:\n\
\n\
    %s\n\
\n\
To:\n\
\n\
    %s\n"
#endif
		     , rec_obj->name, tar_path
		);
	    else
		buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Recupere 1 objeto a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Retrouver 1 objet à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Erlangen Sie 1 Objekt zu wieder:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Ricuperare 1 oggetto a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Krijg 1 voorwerp te terug:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Recupere 1 objeto a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Utvinn 1 objekt til:\n\
\n\
    %s\n"
#else
"Recover 1 object to:\n\
\n\
    %s\n"
#endif
		    , tar_path
		);

	    EDVRecBinObjectDelete(rec_obj);	/* Delete recycled object stats */
	}
	else
	{
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Recupere %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Etrouver %i des objets à:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Erlangen sie %i objekte zu wieder:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Ricuperare %i oggetti a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Krijg %i voorwerpen te terug:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Recupere %i objetos a:\n\
\n\
    %s\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Utvinn %i objekt til:\n\
\n\
    %s\n"
#else
"Recover %i objects to:\n\
\n\
    %s\n"
#endif
		, total_objects, tar_path
	    );
	}

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_recover_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);	/* Delete message */

	return(response);
}

/*
 *      Confirm purge of a recycled object.
 *
 *      Note that src_path is actually a string containing the recycled
 *      object index number.
 *
 *      Returns one of CDIALOG_RESPONSE_*.
 *      Confirmation will always be CDIALOG_RESPONSE_YES if configuration
 *      specifies no confirmation for this operation.
 */
gint EDVConfirmPurge(
	edv_core_struct *core_ptr, GtkWidget *toplevel,
	const gchar *src_path, gint total_objects
)
{
	gint response;
	const gchar *title;
	gchar *buf;
	const gchar *recycled_index_file;


	if(core_ptr == NULL)
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	if(!CFGItemListGetValueI(
	    core_ptr->cfg_list, EDV_CFG_PARM_CONFIRM_PURGE
	))
	    return(CDIALOG_RESPONSE_YES);


	/* Get path to recycled objects index file */
	recycled_index_file = CFGItemListGetValueS(
	    core_ptr->cfg_list, EDV_CFG_PARM_FILE_RECYCLED_INDEX
	);


	/* Format confirmation title and message */

	title =
#if defined(PROG_LANGUAGE_SPANISH)
"Confirme Purga"
#elif defined(PROG_LANGUAGE_FRENCH)
"Confirmer La Purge"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bestätigen Sie Reinigt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Confermare La Purga"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bevestiig Zuivering"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Confirme Purge"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bekreft Purge"
#else
"Confirm Purge"
#endif
	;

	if((total_objects == 1) && (src_path != NULL))
	{
	    edv_recbin_object_struct *rec_obj = EDVRecBinObjectStat(
		recycled_index_file, atoi(src_path)
	    );
	    if((rec_obj != NULL) ? (rec_obj->name != NULL) : FALSE)
		buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"¿Purga recycled \"%s\" objetivo?\n\
\n\
¡Usted no será capaz de recuperar este objeto una\n\
vez se ha purgado!\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Veuillez a recyclé \"%s\" d'objet?\n\
\n\
Vous ne pourrez pas retrouver cet objet une fois\n\
il a été purgé!\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Reinigen Sie wiederverwerteten Objekt \"%s\"?\n\
\n\
Sie ist dieses Objekt einmal es nicht gereinigt\n\
worden werden wiedererlangen können!\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La purga ha riciclato \"%s\" di oggetto?\n\
\n\
Lei non sarà in grado di ricuperare quest'oggetto\n\
una volta è stato prosciolto!\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Recyclde zuivering voorwerp \"%s\"?\n\
\n\
U is deze voorwerp eenmaal het niet gereinigd zult\n\
kunnen terugkrijgen!\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"\"%s\" de objeto de recycled de purge?\n\
\n\
Você nao será capaz de recuperar este objeto vez\n\
uma que foi purged!\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Rens resirkuleredd objekt \"%s\"?\n\
\n\
De er ikke kyndig utvinne dette objektet en gang\n\
det renser!\n"
#else
"Purge recycled object \"%s\"?\n\
\n\
You will not be able to recover this object\n\
once it has been purged!"
#endif
		    , rec_obj->name
		);
	    else
		buf = STRDUP(
"Purge 1 recycled object?\n\
\n\
You will not be able to recover this object\n\
once it has been purged!"
		);

	    EDVRecBinObjectDelete(rec_obj);     /* Delete recycled object stats */
	}
	else
	{
	    buf = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"¿Purga %i objetos de recycled?\n\
\n\
¡Usted no será capaz de recuperar estos objetos\n\
una vez ellos han sido purgados!\n"
#elif defined(PROG_LANGUAGE_FRENCH)
"Purge %i ont recyclé des objets?\n\
\n\
Vous ne pourrez pas retrouver ces objets une fois\n\
ils ont été purgés!\n"
#elif defined(PROG_LANGUAGE_GERMAN)
"Reinigen sie %i wiederverwertete objekte?\n\
\n\
Sie sind diese objekte einmal sie nicht gereinigt\n\
worden werden wiedererlangen können!\n"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Proscioglie %i oggetti riciclati?\n\
\n\
Lei non sarà in grado di ricuperare questi\n\
oggetti una volta sono stato prosciolto!\n"
#elif defined(PROG_LANGUAGE_DUTCH)
"Reiniig %i gerecyclde voorwerpen?\n\
\n\
U zijn deze voorwerpen eenmaal zij niet gereinigd\n\
zult kunnen terugkrijgen!\n"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Purge %i objetos de recycled?\n\
\n\
Você nao será capaz de recuperar estes objetos vez\n\
uma que eles foram purged!\n"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Rens %i resirkuleredde objekt?\n\
\n\
De er ikke kyndig utvinne disse objektene en gang\n\
de renset!\n"
#else
"Purge %i recycled objects?\n\
\n\
You will not be able to recover these objects\n\
once they have been purged!"
#endif
		, total_objects
	    );
	}

	EDVPlaySoundQuestion(core_ptr);
	CDialogSetTransientFor(toplevel);
	response = CDialogGetResponseIconData(
	    title, buf, NULL,
	    (guint8 **)icon_purge_32x32_xpm,
	    CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
	    CDIALOG_BTNFLAG_YES
	);
	CDialogSetTransientFor(NULL);

	g_free(buf);    /* Delete message */

	return(response);
}


/*
 *	Calls appropriate confirmation based on the given GTK DND 
 *	information regarding the target type and the drag action.
 */
gint EDVConfirmDND(
	edv_core_struct *core_ptr,
	gint gdk_action, guint info,
	GtkWidget *toplevel,
	GList *url_list,
	const gchar *tar_path
)
{
	const gint nurls = g_list_length(url_list);
	const gchar *src_path = NULL;


	/* Must have the DND target name, target path, and a positive
	 * number of DND objects
	 */
	if(STRISEMPTY(tar_path) || (nurls <= 0))
	    return(CDIALOG_RESPONSE_NOT_AVAILABLE);

	/* If there is exactly one URL then get the path of that URL,
	 * otherwise leave src_path as NULL
	 */
	if(nurls == 1)
	{
	    GList *glist = url_list;
	    const url_struct *url = (glist != NULL) ?
		URL(glist->data) : NULL;
	    if(url != NULL)
		src_path = url->path;
	}


	/* Handle by drag context target type */

	/* Disk object? */
	if((info == EDV_DND_TYPE_INFO_TEXT_PLAIN) ||
	   (info == EDV_DND_TYPE_INFO_TEXT_URI_LIST) ||
	   (info == EDV_DND_TYPE_INFO_STRING)
	)
	{
	    switch(gdk_action)
	    {
	      case GDK_ACTION_LINK:
		return(EDVConfirmLink(
		    core_ptr, toplevel,
		    src_path, nurls, tar_path
		));
		break;
	      case GDK_ACTION_MOVE:
		return(EDVConfirmMove(
		    core_ptr, toplevel,
		    src_path, nurls, tar_path
		));
		break;
	      case GDK_ACTION_COPY:
		return(EDVConfirmCopy(
		    core_ptr, toplevel,
		    src_path, nurls, tar_path
		));
		break;
	    }
	}
	/* Recycled object? */
	else if(info == EDV_DND_TYPE_INFO_RECYCLED_OBJECT)
	{
	    switch(gdk_action)
	    {
	      case GDK_ACTION_LINK:
	      case GDK_ACTION_MOVE:
	      case GDK_ACTION_COPY:
		return(EDVConfirmRecover(
		    core_ptr, toplevel,
		    src_path, nurls, tar_path
		));
		break;
	    }
	}
	/* Archive object? */
	else if(info == EDV_DND_TYPE_INFO_ARCHIVE_OBJECT)
	{
	    switch(gdk_action)
	    {
	      case GDK_ACTION_LINK:
	      case GDK_ACTION_MOVE:
	      case GDK_ACTION_COPY:
		/* The first object is considered the archive itself,
		 * and all subsequent objects are objects in the archive
		 */
		if(nurls == 2)
		{
		    GList *glist = g_list_next(url_list);
		    const url_struct *url = (glist != NULL) ?
			URL(glist->data) : NULL;
		    if(url != NULL)
			src_path = url->path;
		}
		return(EDVConfirmArchiveExtract(
		    core_ptr, toplevel,
		    src_path, nurls - 1, tar_path
		));
		break;
	    }
	}

	/* Unsupported DND target type or drag action, return response
	 * not available just to be on the safe side so that the
	 * operation does not continue
	 */
	return(CDIALOG_RESPONSE_NOT_AVAILABLE);
}
