#include <glib.h>
#include "edv_types.h"
#include "edv_mime_type.h"


/* MIME Type Commands */
const gchar *EDVMimeTypeGetCommandValueByName(
	edv_mime_type_struct *m, const gchar *name
);
edv_mime_type_command_struct *EDVMimeTypeGetCommandByName(
	edv_mime_type_struct *m, const gchar *name
);

edv_mime_type_command_struct *EDVMimeTypeCommandNew(void);
void EDVMimeTypeCommandDelete(edv_mime_type_command_struct *cmd);

/* MIME Types */
edv_mime_type_struct *EDVMimeTypeNew(
	const edv_mime_type_class mt_class,
	const gchar *value,
	const gchar *type,              /* MIME Type name */
	const gchar *description	/* Short verbose description */
);
edv_mime_type_struct *EDVMimeTypeCopy(const edv_mime_type_struct *m);
void EDVMimeTypeDelete(edv_mime_type_struct *m);


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


/*
 *	Gets the command value of the MIME Type command that matches
 *	the specified command name.
 */
const gchar *EDVMimeTypeGetCommandValueByName(
	edv_mime_type_struct *m, const gchar *name
)
{
	GList *glist;
	edv_mime_type_command_struct *cmd;

	if((m == NULL) || STRISEMPTY(name))
	    return(NULL);

	for(glist = m->commands_list; glist != NULL; glist = g_list_next(glist))
	{
	    cmd = EDV_MIME_TYPE_COMMAND(glist->data);
	    if(cmd == NULL)
		continue;

	    if(cmd->name == NULL)
		continue;

	    if(!g_strcasecmp(cmd->name, name))
		return(cmd->command);
	}

	return(NULL);
}

/*
 *	Gets the MIME Type command that matches the specified command
 *	name.
 */
edv_mime_type_command_struct *EDVMimeTypeGetCommandByName(
	edv_mime_type_struct *m, const gchar *name
)
{
	GList *glist;
	edv_mime_type_command_struct *cmd;

	if((m == NULL) || STRISEMPTY(name))
	    return(NULL);

	for(glist = m->commands_list; glist != NULL; glist = g_list_next(glist))
	{
	    cmd = EDV_MIME_TYPE_COMMAND(glist->data);
	    if(cmd == NULL)
		continue;

	    if(cmd->name == NULL)
		continue;

	    if(!g_strcasecmp(cmd->name, name))
		return(cmd);
	}

	return(NULL);
}


/*
 *	Creates a new MIME Type command.
 */
edv_mime_type_command_struct *EDVMimeTypeCommandNew(void)
{
	return(EDV_MIME_TYPE_COMMAND(g_malloc0(
	    sizeof(edv_mime_type_command_struct)
	)));
}

/*
 *	Deletes the MIME Type command.
 */
void EDVMimeTypeCommandDelete(edv_mime_type_command_struct *cmd)
{
	if(cmd == NULL)
	    return;

	g_free(cmd->name);
	g_free(cmd->command);
	g_free(cmd);
}


/*
 *	Creates a new MIME Type.
 */
edv_mime_type_struct *EDVMimeTypeNew(
	const edv_mime_type_class mt_class,
	const gchar *value,
	const gchar *type,		/* MIME Type name */
	const gchar *description	/* Short verbose description */
)
{
	edv_mime_type_struct *m = EDV_MIME_TYPE(
	    g_malloc0(sizeof(edv_mime_type_struct))
	);
	if(m == NULL)
	    return(m);

	m->mt_class = mt_class;

	m->value = STRDUP(value);
	m->type = STRDUP(type);
	m->description = STRDUP(description);

	m->handler = EDV_MIME_TYPE_HANDLER_COMMAND;

	m->commands_list = NULL;

	m->access_time = 0l;
	m->modify_time = 0l;
	m->change_time = 0l;

	return(m);
}

/*
 *	Coppies the MIME Type.
 */
edv_mime_type_struct *EDVMimeTypeCopy(const edv_mime_type_struct *m)
{
	gint i, n;
	edv_mime_type_struct *tar;
	const edv_mime_type_struct *src = m;

	if(src == NULL)
	    return(NULL);

	tar = EDVMimeTypeNew(
	    src->mt_class,
	    src->value,
	    src->type,
	    src->description
	);
	if(tar == NULL)
	    return(NULL);

	n = EDV_MIME_TYPE_TOTAL_ICON_STATES;
	for(i = 0; i < n; i++)
	{
	    tar->small_icon_file[i] = STRDUP(src->small_icon_file[i]);
	    tar->medium_icon_file[i] = STRDUP(src->medium_icon_file[i]);
	    tar->large_icon_file[i] = STRDUP(src->large_icon_file[i]);
	}

	if(src->commands_list != NULL)
	{
	    GList *glist;
	    edv_mime_type_command_struct *src_cmd, *tar_cmd;

	    for(glist = src->commands_list;
		glist != NULL;
		glist = g_list_next(glist)
	    )
	    {
		src_cmd = EDV_MIME_TYPE_COMMAND(glist->data);
		if(src_cmd == NULL)
		    continue;

		tar_cmd = EDVMimeTypeCommandNew();
		if(tar_cmd == NULL)
		    break;

		tar_cmd->name = STRDUP(src_cmd->name);
		tar_cmd->command = STRDUP(src_cmd->command);

		tar->commands_list = g_list_append(
		    tar->commands_list, tar_cmd
		);
	    }
	}

	return(tar);
}

/*
 *	Deletes the MIME Type.
 */
void EDVMimeTypeDelete(edv_mime_type_struct *m)
{
	gint i, n;

	if(m == NULL)
	    return;

	/* Delete the icon file paths */
	n = EDV_MIME_TYPE_TOTAL_ICON_STATES;
	for(i = 0; i < n; i++)
	{
	    g_free(m->small_icon_file[i]);
	    g_free(m->medium_icon_file[i]);
	    g_free(m->large_icon_file[i]);
	}

	/* Delete the commands */
	if(m->commands_list != NULL)
	{
	    g_list_foreach(
		m->commands_list, (GFunc)EDVMimeTypeCommandDelete, NULL
	    );
	    g_list_free(m->commands_list);
	}                                 

	/* Delete the value, type, and description */
	g_free(m->value);
	g_free(m->type);
	g_free(m->description);

	g_free(m);
}
