#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "cfg.h"


/* Item Types */
cfg_intlist_struct *CFGIntListNew(GList *glist);
void CFGIntListDelete(cfg_intlist_struct *intlist);

cfg_color_struct *CFGColorNew(
	gfloat r, gfloat g, gfloat b, gfloat a
);
void CFGColorDelete(cfg_color_struct *color);

cfg_accelkey_struct *CFGAccelkeyNew(
	gint opid, guint key, guint modifiers
);
void CFGAccelkeyDelete(cfg_accelkey_struct *accelkey);
cfg_accelkey_list_struct *CFGAccelkeyListNew(GList *glist);
void CFGAccelkeyListDelete(cfg_accelkey_list_struct *accelkey_list);

cfg_style_struct *CFGStyleNew(void);
void CFGStyleDelete(cfg_style_struct *style);


/* Cfg Item */
cfg_item_struct *CFGItemNew(
	cfg_type type, const gchar *parameter
);
gpointer CFGItemGetValue(
	const cfg_item_struct *ci, cfg_type *type_rtn
);
void CFGItemSetValue(cfg_item_struct *ci, gconstpointer value);
void CFGItemResetValue(cfg_item_struct *ci);
void CFGItemReset(cfg_item_struct *ci);
void CFGItemDelete(cfg_item_struct *ci);

/* Cfg List Utilities */
cfg_item_struct *CFGItemListCopyList(
	const cfg_item_struct *list
);
void CFGItemListDeleteList(cfg_item_struct *list);
gint CFGItemListMatchParameter(
	const cfg_item_struct *list, const gchar *parameter
);

/* Cfg Item Value Fetching */
gpointer CFGItemListMatchGetValue(
	const cfg_item_struct *list, const gchar *parameter,
	cfg_type *type_rtn
);
gint CFGItemListGetValueI(
	const cfg_item_struct *list, const gchar *parameter
);
glong CFGItemListGetValueL(
	const cfg_item_struct *list, const gchar *parameter
);
gulong CFGItemListGetValueUL(
	const cfg_item_struct *list, const gchar *parameter
);
gfloat CFGItemListGetValueF(
	const cfg_item_struct *list, const gchar *parameter
);
gdouble CFGItemListGetValueD(
	const cfg_item_struct *list, const gchar *parameter
);
gchar *CFGItemListGetValueS(
	const cfg_item_struct *list, const gchar *parameter
);
cfg_color_struct *CFGItemListGetValueColor(
	const cfg_item_struct *list, const gchar *parameter
);
cfg_intlist_struct *CFGItemListGetValueIntList(
	const cfg_item_struct *list, const gchar *parameter
);
cfg_accelkey_list_struct *CFGItemListGetValueAccelkeyList(
	const cfg_item_struct *list, const gchar *parameter
);
cfg_style_struct *CFGItemListGetValueStyle(
	const cfg_item_struct *list, const gchar *parameter
);

/* Cfg Item Value Setting */
void CFGItemListSetValue(
	cfg_item_struct *list, const gchar *parameter,
	gconstpointer value, gboolean create_as_needed
);
void CFGItemListSetValueI(
	cfg_item_struct *list, const gchar *parameter,
	gint value, gboolean create_as_needed
);
void CFGItemListSetValueL(
	cfg_item_struct *list, const gchar *parameter,
	glong value, gboolean create_as_needed
);
void CFGItemListSetValueUL(
	cfg_item_struct *list, const gchar *parameter,
	gulong value, gboolean create_as_needed
);
void CFGItemListSetValueF(
	cfg_item_struct *list, const gchar *parameter,
	gfloat value, gboolean create_as_needed
);
void CFGItemListSetValueD(
	cfg_item_struct *list, const gchar *parameter,
	gdouble value, gboolean create_as_needed
);
void CFGItemListSetValueS(
	cfg_item_struct *list, const gchar *parameter,
	const gchar *value, gboolean create_as_needed
);
void CFGItemListSetValueColor(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_color_struct *value, gboolean create_as_needed
);
void CFGItemListSetValueIntList(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_intlist_struct *value, gboolean create_as_needed
);
void CFGItemListSetValueAccelkeyList(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_accelkey_list_struct *value, gboolean create_as_needed
);
void CFGItemListSetValueStyle(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_style_struct *value, gboolean create_as_needed
);


#ifndef g_memcpy
# define g_memcpy	memcpy
#endif

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


/*
 *	Creates a new IntList.
 *
 *	The values from the specified GList will be coppied.
 */
cfg_intlist_struct *CFGIntListNew(GList *glist)
{
	cfg_intlist_struct *intlist = CFG_INTLIST(
	    g_malloc(sizeof(cfg_intlist_struct))
	);
	if(intlist == NULL)
	    return(NULL);

	intlist->list = NULL;
	while(glist != NULL)
	{
	    intlist->list = g_list_append(intlist->list, glist->data);
	    glist = g_list_next(glist);
	}

	return(intlist);
}

/*
 *	Deletes the IntList.
 */
void CFGIntListDelete(cfg_intlist_struct *intlist)
{
	if(intlist == NULL)
	    return;

	g_list_free(intlist->list);
	g_free(intlist);
}

/*
 *	Creates a new Color.
 */
cfg_color_struct *CFGColorNew(
	gfloat r, gfloat g, gfloat b, gfloat a
)
{
	cfg_color_struct *color = CFG_COLOR(
	    g_malloc(sizeof(cfg_color_struct))
	);
	if(color == NULL)
	    return(NULL);

	color->r = r;
	color->g = g;
	color->b = b;
	color->a = a;

	return(color);
}

/*
 *	Deletes the Color.
 */
void CFGColorDelete(cfg_color_struct *color)
{
	if(color == NULL)
	    return;

	g_free(color);
}

/*
 *	Creates a new Accelkey.
 */
cfg_accelkey_struct *CFGAccelkeyNew(
	gint opid, guint key, guint modifiers
)
{
	cfg_accelkey_struct *akey = CFG_ACCELKEY(
	    g_malloc(sizeof(cfg_accelkey_struct))
	);
	if(akey == NULL)
	    return(NULL);

	akey->opid = opid;
	akey->key = key;
	akey->modifiers = modifiers;

	return(akey);
}

/*
 *	Deletes the Accelkey.
 */
void CFGAccelkeyDelete(cfg_accelkey_struct *accelkey)
{
	if(accelkey == NULL)
	    return;

	g_free(accelkey);
}

/*
 *	Creates a new Accelkey List.
 *
 *	The values from the specified GList will be coppied.
 */
cfg_accelkey_list_struct *CFGAccelkeyListNew(GList *glist)
{
	cfg_accelkey_struct *akey;
	cfg_accelkey_list_struct *akey_list = CFG_ACCELKEY_LIST(
	    g_malloc(sizeof(cfg_accelkey_list_struct))
	);
	if(akey_list == NULL)
	    return(NULL);

	akey_list->list = NULL;
	while(glist != NULL)
	{
	    akey = CFG_ACCELKEY(glist->data);
	    if(akey == NULL)
		continue;

	    akey_list->list = g_list_append(
		akey_list->list,
		CFGAccelkeyNew(
		    akey->opid,
		    akey->key,
		    akey->modifiers
		)
	    );
	    glist = g_list_next(glist);
	}

	return(akey_list);
}

/*
 *	Deletes the Accelkey List.
 */
void CFGAccelkeyListDelete(cfg_accelkey_list_struct *accelkey_list)
{
	if(accelkey_list == NULL)
	    return;

	g_list_foreach(
	    accelkey_list->list,
	    (GFunc)CFGAccelkeyDelete,
	    NULL
	);
	g_list_free(accelkey_list->list);

	g_free(accelkey_list);
}

/*
 *	Creates a new Cfg Style.
 */
cfg_style_struct *CFGStyleNew(void)
{
	cfg_style_struct *style = CFG_STYLE(
	    g_malloc0(sizeof(cfg_style_struct))
	);
	if(style == NULL)
	    return(NULL);

	return(style);
}

/*
 *	Deletes the Cfg Style.
 */
void CFGStyleDelete(cfg_style_struct *style)
{
	gint i;

	if(style == NULL)
	    return;

	g_free(style->font_name);

	for(i = 0; i < CFG_STYLE_STATES; i++)
	    g_free(style->bg_pixmap_name[i]);

	g_free(style);
}


/*
 *	Creates a new Cfg Item.
 */
cfg_item_struct *CFGItemNew(
	cfg_type type, const gchar *parameter
)
{
	cfg_item_struct *ci = CFG_ITEM(
	    g_malloc0(sizeof(cfg_item_struct))
	);
	if(ci == NULL)
	    return(ci);

	ci->type = type;
	ci->parameter = STRDUP(parameter);
	ci->value = NULL;

	return(ci);
}

/*
 *	Returns the Cfg Item's value and type.
 */
gpointer CFGItemGetValue(
	const cfg_item_struct *ci, cfg_type *type_rtn
)
{
	if(ci != NULL)
	{
	    if(type_rtn != NULL)
		*type_rtn = ci->type;
	    return((gpointer)ci->value);
	}
	else
	{
	    if(type_rtn != NULL)
		*type_rtn = -1;
	    return(NULL);
	}
}

/*
 *	Sets the Cfg Item's value.
 *
 *	The type of data that value points to must match the same
 *	type of data of the ci's type.
 *
 *	Note that ci->value may be reallocated during this call.
 */
void CFGItemSetValue(cfg_item_struct *ci, gconstpointer value)
{
	gint size;
	gint8 *ptr_8;
	guint8 *ptr_u8;
	gint16 *ptr_16;
	guint16 *ptr_u16;
	gint32 *ptr_32;
	guint32 *ptr_u32;
	gint64 *ptr_64;
	guint64 *ptr_u64;
	gfloat *ptr_float;
	gdouble *ptr_double;
	cfg_intlist_struct *ptr_intlist;
	cfg_color_struct *ptr_color;
	cfg_accelkey_list_struct *ptr_ak_list;
	cfg_style_struct *ptr_style;

	if(ci == NULL)
	    return;

	/* Delete existing value on the cfg item */
	CFGItemResetValue(ci);

	/* No value given? */
	if(value == NULL)
	    return;

	/* Set by type */
	switch(ci->type)
	{
	  case CFG_ITEM_TYPE_NONE:
	    break;

	  case CFG_ITEM_TYPE_INT8:
	    size = sizeof(gint8);
	    ptr_8 = (gint8 *)g_malloc(size);
	    if(ptr_8 != NULL)
		g_memcpy(ptr_8, value, size);
	    ci->value = ptr_8;
	    break;
	  case CFG_ITEM_TYPE_UINT8:
	    size = sizeof(guint8);
	    ptr_u8 = (guint8 *)g_malloc(size);
	    if(ptr_u8 != NULL)
		g_memcpy(ptr_u8, value, size);
	    ci->value = ptr_u8;
	    break;

	  case CFG_ITEM_TYPE_INT16:
	    size = sizeof(gint16);
	    ptr_16 = (gint16 *)g_malloc(size);
	    if(ptr_16 != NULL)
		g_memcpy(ptr_16, value, size);
	    ci->value = ptr_16;
	    break;
	  case CFG_ITEM_TYPE_UINT16:
	    size = sizeof(guint16);
	    ptr_u16 = (guint16 *)g_malloc(size);
	    if(ptr_u16 != NULL)
		g_memcpy(ptr_u16, value, size);
	    ci->value = ptr_u16;
	    break;

	  case CFG_ITEM_TYPE_INT32:
	    size = sizeof(gint32);
	    ptr_32 = (gint32 *)g_malloc(size);
	    if(ptr_32 != NULL)
		g_memcpy(ptr_32, value, size);
	    ci->value = ptr_32;
	    break;
	  case CFG_ITEM_TYPE_UINT32:
	    size = sizeof(guint32);
	    ptr_u32 = (guint32 *)g_malloc(size);
	    if(ptr_u32 != NULL)
		g_memcpy(ptr_u32, value, size);
	    ci->value = ptr_u32;
	    break;

	  case CFG_ITEM_TYPE_INT64:
	    size = sizeof(gint64);
	    ptr_64 = (gint64 *)g_malloc(size);
	    if(ptr_64 != NULL)
		g_memcpy(ptr_64, value, size);
	    ci->value = ptr_64;
	    break;
	  case CFG_ITEM_TYPE_UINT64:
	    size = sizeof(guint64);
	    ptr_u64 = (guint64 *)g_malloc(size);
	    if(ptr_u64 != NULL)
		g_memcpy(ptr_u64, value, size);
	    ci->value = ptr_u64;
	    break;

	  case CFG_ITEM_TYPE_FLOAT:
	    size = sizeof(gfloat);
	    ptr_float = (gfloat *)g_malloc(size);
	    if(ptr_float != NULL)
		g_memcpy(ptr_float, value, size);
	    ci->value = ptr_float;
	    break;
	  case CFG_ITEM_TYPE_DOUBLE:
	    size = sizeof(gdouble);
	    ptr_double = (gdouble *)g_malloc(size);
	    if(ptr_double != NULL)
		g_memcpy(ptr_double, value, size);
	    ci->value = ptr_double;
	    break;

	  case CFG_ITEM_TYPE_STRING:
	    ci->value = STRDUP((const gchar *)value);
	    break;

	  case CFG_ITEM_TYPE_INTLIST:
	    size = sizeof(cfg_intlist_struct);
	    if(size > 0)
	    {
		const cfg_intlist_struct *src_intlist = CFG_INTLIST(value);
		ptr_intlist = CFGIntListNew(src_intlist->list);
	    }
	    else
	    {
		ptr_intlist = NULL;
	    }
	    ci->value = ptr_intlist;
	    break;

	  case CFG_ITEM_TYPE_COLOR:
	    size = sizeof(cfg_color_struct);
	    if(size > 0)
	    {
		const cfg_color_struct *src_color = CFG_COLOR(value);
		ptr_color = CFGColorNew(
		    src_color->r,
		    src_color->g,
		    src_color->b,
		    src_color->a
		);
	    }
	    else
	    {
		ptr_color = NULL; 
	    }
	    ci->value = ptr_color;
	    break;

	  case CFG_ITEM_TYPE_ACCELKEY_LIST:
	    size = sizeof(cfg_accelkey_list_struct);
	    if(size > 0)
	    {
		const cfg_accelkey_list_struct *src_ak_list = CFG_ACCELKEY_LIST(value);
		ptr_ak_list = CFGAccelkeyListNew(
		    src_ak_list->list
		);
	    }
	    else
	    {
		ptr_ak_list = NULL;
	    }
	    ci->value = ptr_ak_list;
	    break;

	  case CFG_ITEM_TYPE_STYLE:
	    size = sizeof(cfg_style_struct);
	    ptr_style = CFGStyleNew();
	    if(ptr_style != NULL)
	    {
		gint state;
		const cfg_style_struct *src_style = CFG_STYLE(value);

		/* Copy values from source style to target style */
		ptr_style->font_name = STRDUP(src_style->font_name);
		g_memcpy(
		    ptr_style->color_flags, src_style->color_flags,
		    CFG_STYLE_STATES * sizeof(guint)
		);
		g_memcpy(
		    ptr_style->fg, src_style->fg,
		    CFG_STYLE_STATES * sizeof(cfg_color_struct)
		);
		g_memcpy(
		    ptr_style->bg, src_style->bg,
		    CFG_STYLE_STATES * sizeof(cfg_color_struct)
		);
		g_memcpy(
		    ptr_style->text, src_style->text,
		    CFG_STYLE_STATES * sizeof(cfg_color_struct)
		);
		g_memcpy(
		    ptr_style->base, src_style->base,
		    CFG_STYLE_STATES * sizeof(cfg_color_struct)
		);
		for(state = 0; state < CFG_STYLE_STATES; state++)
		    ptr_style->bg_pixmap_name[state] = STRDUP(
			src_style->bg_pixmap_name[state]
		    );
	    }
	    ci->value = ptr_style;
	    break;
	}
}

/*
 *	Deletes the Cfg Item's value and then resets it to NULL.
 */
void CFGItemResetValue(cfg_item_struct *ci)
{
	if((ci != NULL) ? (ci->value == NULL) : TRUE)
	    return;

	/* Delete value by type */
	switch(ci->type)
	{
	  case CFG_ITEM_TYPE_NONE:
	    break;
	  case CFG_ITEM_TYPE_INT8:
	    break;
	  case CFG_ITEM_TYPE_UINT8:
	    break;
	  case CFG_ITEM_TYPE_INT16:
	    break;
	  case CFG_ITEM_TYPE_UINT16:
	    break;
	  case CFG_ITEM_TYPE_INT32:
	    break;
	  case CFG_ITEM_TYPE_UINT32:
	    break;
	  case CFG_ITEM_TYPE_INT64:
	    break;
	  case CFG_ITEM_TYPE_UINT64:
	    break;
	  case CFG_ITEM_TYPE_FLOAT:
	    break;
	  case CFG_ITEM_TYPE_DOUBLE:
	    break;
	  case CFG_ITEM_TYPE_STRING:
	    break;
	  case CFG_ITEM_TYPE_INTLIST:
	    CFGIntListDelete(CFG_INTLIST(ci->value));
	    ci->value = NULL;
	    break;
	  case CFG_ITEM_TYPE_COLOR:
	    CFGColorDelete(CFG_COLOR(ci->value));
	    ci->value = NULL;
	    break;
	  case CFG_ITEM_TYPE_ACCELKEY_LIST:
	    CFGAccelkeyListDelete(CFG_ACCELKEY_LIST(ci->value));
	    ci->value = NULL;
	    break;
	  case CFG_ITEM_TYPE_STYLE:
	    CFGStyleDelete(CFG_STYLE(ci->value));
	    ci->value = NULL;
	    break;
	}

	/* Delete value in case it was not deleted above and reset it to
	 * NULL
	 */
	g_free(ci->value);
	ci->value = NULL;
}

/*
 *	Deletes the Cfg Item's value and parameter and resets its type
 *	to CFG_ITEM_TYPE_NONE.
 */
void CFGItemReset(cfg_item_struct *ci)
{
	if(ci == NULL)
	    return;

	/* Delete value */
	CFGItemResetValue(ci);

	/* Delete parameter */
	g_free(ci->parameter);
	ci->parameter = NULL;

	/* Reset type */
	ci->type = CFG_ITEM_TYPE_NONE;
}

/*
 *	Deletes the Cfg Item.
 */
void CFGItemDelete(cfg_item_struct *ci)
{
	if(ci == NULL)
	    return;

	/* Delete the Cfg Item's value and parameter */
	CFGItemReset(ci);

	/* Delete the Cfg Item */
	g_free(ci);
}


/*
 *	Coppies the list of Cfg Items.
 *
 *	Each member of each Cfg Item will also be coppied.
 */
cfg_item_struct *CFGItemListCopyList(
	const cfg_item_struct *list
)
{
	gint i;
	const cfg_item_struct	*src_list = list,
				*src_cfg_item;
	cfg_item_struct		*tar_list = NULL,
				*tar_cfg_item;

	if(src_list == NULL)
	    return(tar_list);


	/* Iterate through source list, copying each configuration
	 * item to the target list
	 */
	i = 0;
	src_cfg_item = &src_list[i];
	while((src_cfg_item->type != CFG_ITEM_TYPE_NONE) ||
	      (src_cfg_item->parameter != NULL) ||
	      (src_cfg_item->value != NULL)
	)
	{
	    /* Aappend a new cfg item on the target list */
	    tar_list = CFG_ITEM(g_realloc(
		tar_list,
		(i + 1) * sizeof(cfg_item_struct)
	    ));
	    if(tar_list == NULL)
	    {
		i = 0;
		break;
	    }

	    /* Get pointer to new target cfg item */
	    tar_cfg_item = &tar_list[i];

	    /* Reset target cfg item */
	    memset(tar_cfg_item, 0x00, sizeof(cfg_item_struct));


	    /* Begin copying values from source cfg item to the
	     * target cfg item
	     */

	    /* Type */
	    tar_cfg_item->type = src_cfg_item->type;

	    /* Parameter */
	    tar_cfg_item->parameter = STRDUP(src_cfg_item->parameter);

	    /* Value */
	    if(src_cfg_item->value != NULL)
	    {
		switch(tar_cfg_item->type)
		{
		  case CFG_ITEM_TYPE_NONE:
		  case CFG_ITEM_TYPE_INT8:
		  case CFG_ITEM_TYPE_UINT8:
		  case CFG_ITEM_TYPE_INT16:
		  case CFG_ITEM_TYPE_UINT16:
		  case CFG_ITEM_TYPE_INT32:
		  case CFG_ITEM_TYPE_UINT32:
		    CFGItemListSetValueI(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueI(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_INT64:
		    CFGItemListSetValueL(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueL(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_UINT64:
		    CFGItemListSetValueUL(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueUL(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_FLOAT:
		    CFGItemListSetValueF(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueF(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_DOUBLE:
		    CFGItemListSetValueD(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueD(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_STRING:
		    CFGItemListSetValueS(
			tar_cfg_item, tar_cfg_item->parameter,
	CFGItemListGetValueS(src_cfg_item, src_cfg_item->parameter),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_INTLIST:
		    CFGItemListSetValueIntList(
			tar_cfg_item, tar_cfg_item->parameter,
			CFG_INTLIST(src_cfg_item->value),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_COLOR:
		    CFGItemListSetValueColor(
			tar_cfg_item, tar_cfg_item->parameter,
			CFG_COLOR(src_cfg_item->value),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_ACCELKEY_LIST:
		    CFGItemListSetValueAccelkeyList(
			tar_cfg_item, tar_cfg_item->parameter,
			CFG_ACCELKEY_LIST(src_cfg_item->value),
			FALSE
		    );
		    break;
		  case CFG_ITEM_TYPE_STYLE:
		    CFGItemListSetValueStyle(
			tar_cfg_item, tar_cfg_item->parameter,
			CFG_STYLE(src_cfg_item->value),
			FALSE
		    );
		    break;
		}
	    }

	    /* Go on to the next source Cfg Item */
	    i++;
	    src_cfg_item = &src_list[i];
	}

	/* Create the last Cfg Item on the target list to be all 0's,
	 * thus marking the end of the list
	 */
	tar_list = CFG_ITEM(g_realloc(
	    tar_list,
	    (i + 1) * sizeof(cfg_item_struct)
	));
	if(tar_list != NULL)
	{
	    tar_cfg_item = &tar_list[i];
	    memset(tar_cfg_item, 0x00, sizeof(cfg_item_struct));
	}

	return(tar_list);
}

/*
 *	Deletes the list of Cfg Items.
 */
void CFGItemListDeleteList(cfg_item_struct *list)
{
	gint i;
	cfg_item_struct *ci;


	if(list == NULL)
	    return;

	/* Reset each Cfg Item in the List, thus deleting each Cfg
	 * Item's members
	 */
	i = 0;
	ci = &list[i];
	while((ci->type != CFG_ITEM_TYPE_NONE) ||
	      (ci->parameter != NULL) ||
	      (ci->value != NULL)
	)
	{
	    /* Delete cfg item's parameter and value */
	    CFGItemReset(ci);

	    /* Go on to the next cfg item */
	    i++;
	    ci = &list[i];
	}

	/* Delete the Cfg Items List */
	g_free(list);
}

/*
 *	Scans through the sequential list of configuration items and
 *	returns the index number of the one who's parameter matches the
 *	given parameter (case insensitive).
 *
 *	The last item in the sequential list needs to be all 0.
 *
 *	Returns -1 on failed match or error, otherwise returns
 *	the index of the valid item.
 */
gint CFGItemListMatchParameter(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint i;
	const cfg_item_struct *ci;


	if((list == NULL) || STRISEMPTY(parameter))
	    return(-1);

	i = 0;
	ci = &list[i];
	while((ci->type != CFG_ITEM_TYPE_NONE) &&
	      (ci->parameter != NULL)
	)
	{
	    if(!g_strcasecmp(ci->parameter, parameter))
		return(i);

	    i++;
	    ci = &list[i];
	}

	return(-1);
}

/*
 *	Returns the value pointer and type of the Cfg Item that matches
 *	the given parameter found in the given Cfg Items List..
 *
 *      Returns NULL on failed match or error.
 *
 *	The returned pointer must not be modified or deleted.
 */
gpointer CFGItemListMatchGetValue(
	const cfg_item_struct *list, const gchar *parameter,
	cfg_type *type_rtn
)
{
	gint i;

	if(type_rtn != NULL)
	    *type_rtn = -1;

	/* Check if given parameter matches the parameter of a cfg item
	 * in the list
	 */
	i = CFGItemListMatchParameter(list, parameter);
	return((i > -1) ?
	    CFGItemGetValue(&list[i], type_rtn) : NULL
	);
}

/*
 *	Returns the gint value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 */
gint CFGItemListGetValueI(
	const cfg_item_struct *list, const gchar *parameter
)
{
#define RTN_VAL_T	gint
	RTN_VAL_T rtn_val = (RTN_VAL_T)0;
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	gint8 *ptr_8;
	guint8 *ptr_u8;
	gint16 *ptr_16;
	guint16 *ptr_u16;
	gint32 *ptr_32;
	guint32 *ptr_u32;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(rtn_val);
	else
	    ci_ptr = &list[ci_num];

	/* No value? */
	if(ci_ptr->value == NULL)
	    return(rtn_val);

	/* Get return value by cfg item type */
	switch((gint)ci_ptr->type)
	{
	  case CFG_ITEM_TYPE_INT8: 
	    ptr_8 = (gint8 *)ci_ptr->value;  
	    rtn_val = (RTN_VAL_T)(*ptr_8); 
	    break;
	  case CFG_ITEM_TYPE_UINT8: 
	    ptr_u8 = (guint8 *)ci_ptr->value;  
	    rtn_val = (RTN_VAL_T)(*ptr_u8); 
	    break;

	  case CFG_ITEM_TYPE_INT16:
	    ptr_16 = (gint16 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_16);
	    break;
	  case CFG_ITEM_TYPE_UINT16:
	    ptr_u16 = (guint16 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_u16);
	    break;

	  case CFG_ITEM_TYPE_INT32:
	    ptr_32 = (gint32 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_32);
	    break;
	  case CFG_ITEM_TYPE_UINT32:
	    ptr_u32 = (guint32 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_u32);
	    break;
	}

	return(rtn_val);
#undef RTN_VAL_T
}

/*
 *	Returns the glong value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 *		CFG_ITEM_TYPE_INT64
 *		CFG_ITEM_TYPE_UINT64
 */
glong CFGItemListGetValueL(
	const cfg_item_struct *list, const gchar *parameter
)
{
#define RTN_VAL_T	glong
	RTN_VAL_T rtn_val = (RTN_VAL_T)0;
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	gint64 *ptr_64;
	guint64 *ptr_u64;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(rtn_val);
	else
	    ci_ptr = &list[ci_num];

	/* No value? */
	if(ci_ptr->value == NULL)
	    return(rtn_val);

	/* Get return value by cfg item type */
	switch((gint)ci_ptr->type)  
	{
	  case CFG_ITEM_TYPE_INT8:
	  case CFG_ITEM_TYPE_UINT8:
	  case CFG_ITEM_TYPE_INT16:
	  case CFG_ITEM_TYPE_UINT16:
	  case CFG_ITEM_TYPE_INT32:
	  case CFG_ITEM_TYPE_UINT32:
	    rtn_val = (RTN_VAL_T)CFGItemListGetValueI(
		list, parameter
	    );
	    break;

	  case CFG_ITEM_TYPE_INT64:
	    ptr_64 = (gint64 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_64);
	    break;
	  case CFG_ITEM_TYPE_UINT64:
	    ptr_u64 = (guint64 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_u64);
	    break;
	}

	return(rtn_val);
#undef RTN_VAL_T  
}           

/*
 *	Returns the gulong value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 *		CFG_ITEM_TYPE_INT64
 *		CFG_ITEM_TYPE_UINT64
 */
gulong CFGItemListGetValueUL(
	const cfg_item_struct *list, const gchar *parameter
)
{
#define RTN_VAL_T       gulong
	RTN_VAL_T rtn_val = (RTN_VAL_T)0;
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	gint64 *ptr_64;
	guint64 *ptr_u64;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(rtn_val);
	else
	    ci_ptr = &list[ci_num];

	/* No value? */
	if(ci_ptr->value == NULL)
	    return(rtn_val);

	/* Get return value by cfg item type */
	switch((gint)ci_ptr->type)
	{
	  case CFG_ITEM_TYPE_INT8:
	  case CFG_ITEM_TYPE_UINT8:
	  case CFG_ITEM_TYPE_INT16:
	  case CFG_ITEM_TYPE_UINT16:
	  case CFG_ITEM_TYPE_INT32:
	  case CFG_ITEM_TYPE_UINT32:
	    rtn_val = (RTN_VAL_T)CFGItemListGetValueI(
		list, parameter
	    );
	    break;

	  case CFG_ITEM_TYPE_INT64:
	    ptr_64 = (gint64 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_64);
	    break;
	  case CFG_ITEM_TYPE_UINT64:
	    ptr_u64 = (guint64 *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_u64);
	    break;
	}

	return(rtn_val);
#undef RTN_VAL_T
}

/*
 *	Returns the gfloat value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 *		CFG_ITEM_TYPE_INT64
 *		CFG_ITEM_TYPE_UINT64
 *		CFG_ITEM_TYPE_FLOAT
 */
gfloat CFGItemListGetValueF(
	const cfg_item_struct *list, const gchar *parameter
)
{
#define RTN_VAL_T	float
	RTN_VAL_T rtn_val = (float)0.0;
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	gfloat *ptr_f;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)  
	    return(rtn_val);
	else
	    ci_ptr = &list[ci_num];

	/* No value? */
	if(ci_ptr->value == NULL)
	    return(rtn_val);

	/* Get return value by cfg item type */
	switch((gint)ci_ptr->type)
	{
	  case CFG_ITEM_TYPE_INT8:
	  case CFG_ITEM_TYPE_UINT8:
	  case CFG_ITEM_TYPE_INT16:
	  case CFG_ITEM_TYPE_UINT16:
	  case CFG_ITEM_TYPE_INT32:
	  case CFG_ITEM_TYPE_UINT32:
	  case CFG_ITEM_TYPE_INT64:
	  case CFG_ITEM_TYPE_UINT64:
	    rtn_val = (RTN_VAL_T)CFGItemListGetValueL(
		list, parameter
	    );
	    break;

	  case CFG_ITEM_TYPE_FLOAT:
	    ptr_f = (float *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_f);
	    break;
	}

	return(rtn_val);
#undef RTN_VAL_T
}

/*
 *	Returns the gdouble value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8 
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16  
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 *		CFG_ITEM_TYPE_INT64
 *		CFG_ITEM_TYPE_UINT64
 *		CFG_ITEM_TYPE_FLOAT
 *		CFG_ITEM_TYPE_DOUBLE
 */
gdouble CFGItemListGetValueD(
	const cfg_item_struct *list, const gchar *parameter
)
{
#define RTN_VAL_T	gdouble
	RTN_VAL_T rtn_val = (RTN_VAL_T)0.0;
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	gdouble *ptr_d;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(rtn_val);
	else
	    ci_ptr = &list[ci_num];

	/* No value? */
	if(ci_ptr->value == NULL)
	    return(rtn_val);

	/* Get return value by cfg item type */
	switch((gint)ci_ptr->type)
	{
	  case CFG_ITEM_TYPE_INT8:
	  case CFG_ITEM_TYPE_UINT8:
	  case CFG_ITEM_TYPE_INT16:
	  case CFG_ITEM_TYPE_UINT16:
	  case CFG_ITEM_TYPE_INT32:
	  case CFG_ITEM_TYPE_UINT32:
	  case CFG_ITEM_TYPE_INT64:
	  case CFG_ITEM_TYPE_UINT64:
	  case CFG_ITEM_TYPE_FLOAT:
	    rtn_val = (RTN_VAL_T)CFGItemListGetValueF(
		list, parameter
	    );
	    break;

	  case CFG_ITEM_TYPE_DOUBLE:
	    ptr_d = (double *)ci_ptr->value;
	    rtn_val = (RTN_VAL_T)(*ptr_d);
	    break;
	}

	return(rtn_val);
#undef RTN_VAL_T
}

/*
 *	Returns the string value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_STRING
 */
gchar *CFGItemListGetValueS(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint ci_num;
	const cfg_item_struct *ci_ptr;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(NULL);
	else
	    ci_ptr = &list[ci_num];

	/* Not the correct type or no value? */
	if((ci_ptr->type != CFG_ITEM_TYPE_STRING) ||
	   (ci_ptr->value == NULL)
	)
	    return(NULL);
	else
	    return((gchar *)ci_ptr->value);
}

/*
 *	Returns the color value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_COLOR
 */
cfg_color_struct *CFGItemListGetValueColor(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint ci_num;
	const cfg_item_struct *ci_ptr;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(NULL);
	else
	    ci_ptr = &list[ci_num];

	/* Not the correct type or no value? */
	if((ci_ptr->type != CFG_ITEM_TYPE_COLOR) ||
	   (ci_ptr->value == NULL)
	)
	    return(NULL);
	else
	    return(CFG_COLOR(ci_ptr->value));
}

/*
 *	Returns the intlist value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_INTLIST
 */
cfg_intlist_struct *CFGItemListGetValueIntList(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint ci_num;
	const cfg_item_struct *ci_ptr;


	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(NULL);
	else
	    ci_ptr = &list[ci_num];

	/* Not the correct type or no value? */
	if((ci_ptr->type != CFG_ITEM_TYPE_INTLIST) ||
	   (ci_ptr->value == NULL)
	)
	    return(NULL);
	else
	    return(CFG_INTLIST(ci_ptr->value));
}

/*
 *	Returns the accelkey list value of the Cfg Item who matches
 *	the given parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_ACCELKEY_LIST
 */
cfg_accelkey_list_struct *CFGItemListGetValueAccelkeyList(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(NULL);
	else
	    ci_ptr = &list[ci_num];

	/* Not the correct type or no value? */
	if((ci_ptr->type != CFG_ITEM_TYPE_ACCELKEY_LIST) ||
	   (ci_ptr->value == NULL)
	)
	    return(NULL);
	else
	    return(CFG_ACCELKEY_LIST(ci_ptr->value));
}

/*
 *	Returns the style value of the Cfg Item who matches the given
 *	parameter found in the given Cfg Items List.
 *
 *	Only Cfg Items of the following types will be matched:
 *
 *		CFG_ITEM_TYPE_STYLE
 */
cfg_style_struct *CFGItemListGetValueStyle(
	const cfg_item_struct *list, const gchar *parameter
)
{
	gint ci_num;
	const cfg_item_struct *ci_ptr;

	/* Match by parameter */
	ci_num = CFGItemListMatchParameter(list, parameter);
	if(ci_num < 0)
	    return(NULL);
	else
	    ci_ptr = &list[ci_num];

	/* Not the correct type or no value? */
	if((ci_ptr->type != CFG_ITEM_TYPE_STYLE) ||
	   (ci_ptr->value == NULL)
	)
	    return(NULL);
	else
	    return(CFG_STYLE(ci_ptr->value));
}


/*
 *      Sets the given value to the sequential list item found match
 *	the given parameter.
 *
 *      The last item in the sequential list needs to be all 0.
 *
 *	Returns the pointer to the new sequential list, if
 *	create_as_needed is false then pointer will be exactly the same
 *	as the list pointer value. If create_as_needed is true then
 *	the returned pointer will be a new pointer to the new
 *	sequential list and the old list will be deallocated.
 *
 *	Can return NULL on error if create_as_needed is true.
 */
void CFGItemListSetValue(
	cfg_item_struct *list, const gchar *parameter,
	gconstpointer value, gboolean create_as_needed
)
{
	gint i;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of cfg items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    /* Matched existing configuration item */
	    CFGItemSetValue(&list[i], value);
	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *      Sets value as a gint, the parameter must match to an item
 *      who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_INT8
 *              CFG_ITEM_TYPE_UINT8
 *              CFG_ITEM_TYPE_INT16
 *              CFG_ITEM_TYPE_UINT16
 *              CFG_ITEM_TYPE_INT32
 *              CFG_ITEM_TYPE_UINT32
 *              CFG_ITEM_TYPE_INT64
 *              CFG_ITEM_TYPE_UINT64
 *              CFG_ITEM_TYPE_FLOAT
 *              CFG_ITEM_TYPE_DOUBLE
 */
void CFGItemListSetValueI(
	cfg_item_struct *list, const gchar *parameter,
	gint value, gboolean create_as_needed
)
{
	CFGItemListSetValueL(
	    list, parameter, value, create_as_needed
	);
}

/*
 *      Sets value as a gint, the parameter must match to an item
 *      who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_INT8
 *              CFG_ITEM_TYPE_UINT8
 *              CFG_ITEM_TYPE_INT16
 *              CFG_ITEM_TYPE_UINT16
 *              CFG_ITEM_TYPE_INT32
 *              CFG_ITEM_TYPE_UINT32
 *              CFG_ITEM_TYPE_INT64
 *              CFG_ITEM_TYPE_UINT64
 *              CFG_ITEM_TYPE_FLOAT
 *              CFG_ITEM_TYPE_DOUBLE
 */
void CFGItemListSetValueL(
	cfg_item_struct *list, const gchar *parameter,
	glong value, gboolean create_as_needed
)
{
	gint i;
	gpointer ptr;
	gint8 v_8;
	guint8 v_u8;
	gint16 v_16;
	guint16 v_u16;
	gint32 v_32;
	guint32 v_u32;
	gint64 v_64;
	guint64 v_u64;
	gfloat v_float;
	gdouble v_double;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of configuration items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    ptr = NULL;
	    switch((gint)(&list[i])->type)
	    {
	      case CFG_ITEM_TYPE_INT8:
		v_8 = (gint8)value;
		ptr = (gpointer)&v_8;
		break;
	      case CFG_ITEM_TYPE_UINT8:
		v_u8 = (guint8)value;
		ptr = (gpointer)&v_u8;
		break;

	      case CFG_ITEM_TYPE_INT16:
		v_16 = (gint16)value;
		ptr = (gpointer)&v_16;
		break;
	      case CFG_ITEM_TYPE_UINT16:
		v_u16 = (guint16)value;
		ptr = (gpointer)&v_u16;
		break;

	      case CFG_ITEM_TYPE_INT32:
		v_32 = (gint32)value;
		ptr = (gpointer)&v_32;
		break;
	      case CFG_ITEM_TYPE_UINT32:
		v_u32 = (guint32)value;
		ptr = (gpointer)&v_u32;
		break;

	      case CFG_ITEM_TYPE_INT64:
		v_64 = (gint64)value;
		ptr = (gpointer)&v_64;
		break;
	      case CFG_ITEM_TYPE_UINT64:
		v_u64 = (guint64)value;
		ptr = (gpointer)&v_u64;
		break;

	      case CFG_ITEM_TYPE_FLOAT:
		v_float = (gfloat)value;
		ptr = (gpointer)&v_float;
		break;
	      case CFG_ITEM_TYPE_DOUBLE:
		v_double = (gdouble)value;
		ptr = (gpointer)&v_double;
		break;
	    }
	    if(ptr == NULL)
		return;

	    CFGItemSetValue(&list[i], ptr);
	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *      Sets value as a gulong, the parameter must match to an item
 *      who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_INT8
 *              CFG_ITEM_TYPE_UINT8
 *              CFG_ITEM_TYPE_INT16
 *              CFG_ITEM_TYPE_UINT16
 *              CFG_ITEM_TYPE_INT32
 *              CFG_ITEM_TYPE_UINT32
 *              CFG_ITEM_TYPE_INT64
 *              CFG_ITEM_TYPE_UINT64
 *              CFG_ITEM_TYPE_FLOAT
 *              CFG_ITEM_TYPE_DOUBLE
 */
void CFGItemListSetValueUL(
	cfg_item_struct *list, const gchar *parameter,
	gulong value, gboolean create_as_needed
)
{
	CFGItemListSetValueL(
	    list, parameter, value, create_as_needed
	);
}

/*
 *	Sets value as a gfloat, the parameter must match to an item
 *	who's type matches any of the following:
 *
 *		CFG_ITEM_TYPE_INT8
 *		CFG_ITEM_TYPE_UINT8
 *		CFG_ITEM_TYPE_INT16
 *		CFG_ITEM_TYPE_UINT16
 *		CFG_ITEM_TYPE_INT32
 *		CFG_ITEM_TYPE_UINT32
 *		CFG_ITEM_TYPE_INT64
 *		CFG_ITEM_TYPE_UINT64
 *		CFG_ITEM_TYPE_FLOAT
 */
void CFGItemListSetValueF(
	cfg_item_struct *list, const gchar *parameter,
	gfloat value, gboolean create_as_needed
)
{
	CFGItemListSetValueD(
	    list, parameter,
	    (gdouble)value, create_as_needed
	);
}

/*
 *      Sets value as a gdouble, the parameter must match to an item
 *      who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_INT8
 *              CFG_ITEM_TYPE_UINT8
 *              CFG_ITEM_TYPE_INT16
 *              CFG_ITEM_TYPE_UINT16
 *              CFG_ITEM_TYPE_INT32
 *              CFG_ITEM_TYPE_UINT32
 *              CFG_ITEM_TYPE_INT64
 *              CFG_ITEM_TYPE_UINT64
 *              CFG_ITEM_TYPE_FLOAT
 *              CFG_ITEM_TYPE_DOUBLE
 */
void CFGItemListSetValueD(
	cfg_item_struct *list, const gchar *parameter,
	gdouble value, gboolean create_as_needed
)
{
	gint i;
	gpointer ptr;
	gint8 v_8;
	guint8 v_u8;
	gint16 v_16;
	guint16 v_u16;
	gint32 v_32;
	guint32 v_u32;
	gint64 v_64;
	guint64 v_u64;
	gfloat v_float;
	gdouble v_double;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of configuration items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    ptr = NULL;
	    switch((gint)(&list[i])->type)
	    {
	      case CFG_ITEM_TYPE_INT8:
		v_8 = (gint8)value;
		ptr = (gpointer)&v_8;
		break;
	      case CFG_ITEM_TYPE_UINT8:
		v_u8 = (guint8)value;
		ptr = (gpointer)&v_u8;
		break;

	      case CFG_ITEM_TYPE_INT16:
		v_16 = (gint16)value;
		ptr = (gpointer)&v_16;
		break;
	      case CFG_ITEM_TYPE_UINT16:
		v_u16 = (guint16)value;
		ptr = (gpointer)&v_u16;
		break;

	      case CFG_ITEM_TYPE_INT32:
		v_32 = (gint32)value;
		ptr = (gpointer)&v_32;
		break;
	      case CFG_ITEM_TYPE_UINT32:
		v_u32 = (guint32)value;
		ptr = (gpointer)&v_u32;
		break;

	      case CFG_ITEM_TYPE_INT64:
		v_64 = (gint64)value;
		ptr = (gpointer)&v_64;
		break;
	      case CFG_ITEM_TYPE_UINT64:
		v_u64 = (guint64)value;
		ptr = (gpointer)&v_u64;
		break;

	      case CFG_ITEM_TYPE_FLOAT:
		v_float = (gfloat)value;
		ptr = (gpointer)&v_float;
		break;
	      case CFG_ITEM_TYPE_DOUBLE:
		v_double = (gdouble)value;
		ptr = (gpointer)&v_double;
		break;
	    }
	    if(ptr == NULL)
		return;

	    CFGItemSetValue(&list[i], ptr);
	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *      Sets value as a string, the parameter must match to an item
 *      who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_STRING
 */
void CFGItemListSetValueS(
	cfg_item_struct *list, const gchar *parameter,
	const gchar *value, gboolean create_as_needed
)
{
	gint i;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of configuration items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    if((&list[i])->type == CFG_ITEM_TYPE_STRING)
		CFGItemSetValue(&list[i], (gconstpointer)value);

	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *	Sets value as a cfg_color_struct, the parameter must match to
 *	an item who's type matches any of the following:
 *
 *		CFG_ITEM_TYPE_COLOR
 */
void CFGItemListSetValueColor(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_color_struct *value, gboolean create_as_needed
)
{
	gint i;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of configuration items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    if((&list[i])->type == CFG_ITEM_TYPE_COLOR)
		CFGItemSetValue(&list[i], (gconstpointer)value);

	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *	Sets value as a cfg_intlist_struct, the parameter must match
 *	to an item who's type matches any of the following:
 *
 *		CFG_ITEM_TYPE_INTLIST
 */
void CFGItemListSetValueIntList(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_intlist_struct *value, gboolean create_as_needed
)
{
	gint i;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the given
	 * list of configuration items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    if((&list[i])->type == CFG_ITEM_TYPE_INTLIST)
		CFGItemSetValue(&list[i], (gconstpointer)value);

	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *	Sets value as a cfg_accelkey_list_struct, the parameter must
 *	match to an item who's type matches any of the following:
 *
 *		CFG_ITEM_TYPE_ACCELKEY_LIST
 */
void CFGItemListSetValueAccelkeyList(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_accelkey_list_struct *value, gboolean create_as_needed
)
{
	gint i;

	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of cfg items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    if((&list[i])->type == CFG_ITEM_TYPE_ACCELKEY_LIST)
		CFGItemSetValue(&list[i], (gconstpointer)value);

	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}

/*
 *      Sets value as a cfg_style_struct, the parameter must match to
 *	an item who's type matches any of the following:
 *
 *              CFG_ITEM_TYPE_STYLE
 */
void CFGItemListSetValueStyle(
	cfg_item_struct *list, const gchar *parameter,
	const cfg_style_struct *value, gboolean create_as_needed
)
{
	gint i;


	if(list == NULL)
	    return;

	/* First try to match an existing configuration item in the
	 * given list of cfg items
	 */
	i = CFGItemListMatchParameter(list, parameter);
	if(i > -1)
	{
	    if((&list[i])->type == CFG_ITEM_TYPE_STYLE)
		CFGItemSetValue(&list[i], (gconstpointer)value);

	    return;
	}
	else
	{
	    /* Does not exist, are we allowed to create one? */
/* TODO */
	}
}
