#include <gtk/gtk.h>

#include "cdialog.h"

#include "edvmimetypes.h"
#include "mimetypeswin.h"
#include "endeavour.h"
#include "edvcb.h"
#include "edvmimetypesinstall.h"
#include "edvutilsgtk.h"
#include "config.h"


gint EDVMimeTypeInstall(
	edv_core_struct *core_ptr, edv_mimetype_struct *m,
	gint pos,
	gboolean interactive,
	GtkWidget *toplevel
);


#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)


/*
 *	Installs the MIME Type specified by m to the core structure's
 *	list of MIME Types.
 *
 *	The given MIME Type m will be installed (transfered) and should
 *	not be referenced again after this call.
 *
 *	If pos is -1 then the MIME Type will be appended.
 *
 *	Returns the index of the installed MIME Type of -1 on error.
 */
gint EDVMimeTypeInstall(
	edv_core_struct *core_ptr, edv_mimetype_struct *m,
	gint pos,
	gboolean interactive,
	GtkWidget *toplevel
)
{
	gint mt_num;
	edv_mimetype_listwin_struct *lw;


	if((core_ptr == NULL) || (m == NULL))
	{
	    EDVMimeTypeDelete(m);
	    return(-1);
	}

	lw = core_ptr->mimetype_listwin;

	/* Check if another MIME Type exists with the same type */
	if(!STRISEMPTY(m->type))
	{
	    gint i;
	    const edv_mimetype_struct *m2;
	    for(i = 0; i < core_ptr->total_mimetypes; i++)
	    {
		m2 = core_ptr->mimetype[i];
		if(m2 == NULL)
		    continue;

		if(STRISEMPTY(m2->type))
		    continue;

		if(!g_strcasecmp(m2->type, m->type))
		    break;
	    }
	    /* Another MIME Type exists with the same type? */
	    if(i < core_ptr->total_mimetypes)
	    {
		if(!CDialogIsQuery())
		{
		    gchar *buf = g_strdup_printf(
"Another MIME Type exists with the same type:\n\
\n\
    %s\n\
\n\
%s\n",
			m->type, m->description
		    );
		    EDVPlaySoundError(core_ptr);
		    EDVMessageError(
"Install MIME Type Failed",
			buf,
			NULL,
			toplevel
		    );
		    g_free(buf);
		}
		EDVMimeTypeDelete(m);
		return(-1);
	    }
	}

	/* Confirm install? */
	if(interactive)
	{
	    gint response;
	    gchar *buf;

	    if(CDialogIsQuery())
	    {
		EDVMimeTypeDelete(m);
		return(-1);
	    }

	    buf = g_strdup_printf(
"Install MIME Type:\n\
\n\
    %s\n\
\n\
%s\n",
		m->type, m->description
	    );
	    EDVPlaySoundQuestion(core_ptr);
	    CDialogSetTransientFor(toplevel);
	    response = CDialogGetResponse(
"Install MIME Type",
		buf,
"You are being asked if you want to install a new MIME Type.\n\
MIME Types are used for recognizing and handling different kinds\n\
of file formats.\n\
\n\
For more information on MIME Types see Help->MIME Types\n",
		CDIALOG_ICON_INSTALL,
		CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_NO,
		CDIALOG_BTNFLAG_YES
	    );
	    CDialogSetTransientFor(NULL);
	    g_free(buf);
	    if(response != CDIALOG_RESPONSE_YES)
	    {
		EDVMimeTypeDelete(m);
		return(-1);
	    }
	}



	/* Append? */
	if((pos < 0) || (pos >= core_ptr->total_mimetypes))
	{
	    /* Allocate more pointers */
	    mt_num = MAX(core_ptr->total_mimetypes, 0);
	    core_ptr->total_mimetypes = mt_num + 1;
	    core_ptr->mimetype = (edv_mimetype_struct **)g_realloc(
		core_ptr->mimetype,
		core_ptr->total_mimetypes * sizeof(edv_mimetype_struct *)
	    );
	    if(core_ptr->mimetype == NULL)
	    {
		core_ptr->total_mimetypes = 0;
		EDVMimeTypeDelete(m);
		return(-1);
	    }

	    /* Set new MIME Type at appended position */
	    core_ptr->mimetype[mt_num] = m;
	}
	else
	{
	    gint i;

	    mt_num = pos;

	    /* Allocate more pointers */
	    core_ptr->total_mimetypes++;
	    core_ptr->mimetype = (edv_mimetype_struct **)g_realloc(
		core_ptr->mimetype,
		core_ptr->total_mimetypes * sizeof(edv_mimetype_struct *)
	    );
	    if(core_ptr->mimetype == NULL)
	    {
		core_ptr->total_mimetypes = 0;
		EDVMimeTypeDelete(m);
		return(-1);
	    }

	    /* Shift pointers */
	    for(i = core_ptr->total_mimetypes - 1; i > mt_num; i--)
		core_ptr->mimetype[i] = core_ptr->mimetype[i - 1];

	    /* Set new MIME Type at inserted position */
	    core_ptr->mimetype[mt_num] = m;
	}


	/* Send MIME Type added signal */
	EDVMimeTypeAddedEmit(core_ptr, mt_num, m);

	/* MIME Types List Window mapped? */
	if(EDVMimeTypesListWinIsMapped(lw))
	{
	    EDVMimeTypesListWinSetBusy(lw, TRUE);

	    /* Select newly installed MIME Type */
	    EDVMimeTypesListWinSelect(lw, mt_num);

	    EDVMimeTypesListWinSetBusy(lw, FALSE);
	}

	return(mt_num);
}
