/*
                              Stack List

	Pair of lists with reorderable items
 */

#ifndef STACKLIST_H
#define STACKLIST_H

#include <gtk/gtk.h>


/*
 *	Stack List Flags:
 */
typedef enum {

	STACK_LIST_SHOW_DESCRIPTION_SOURCE	= (1 << 0),
	STACK_LIST_SHOW_DESCRIPTION_TARGET	= (1 << 1),
	STACK_LIST_MAINTAIN_SOURCE_ORDER	= (1 << 2)

} stack_list_flags;


typedef struct _stack_list_item_struct	stack_list_item_struct;
typedef struct _stack_list_struct	stack_list_struct;


/*
 *	Stack List Item:
 */
struct _stack_list_item_struct {

	gchar		*name;
	gchar		*description;
	GdkPixmap	*icon_pixmap;
	GdkBitmap	*icon_mask;

	gpointer	client_data;

	gint		id;		/* Arbitary number used to
					 * identify this item */ 

	gboolean	allow_multiple;	/* Multiple instances of this
					 * item on the target list
					 * allowed? */

	gboolean	stay_on_target;	/* This item may not be removed
					 * from the target list? */

};
#define STACK_LIST_ITEM(p)	((stack_list_item_struct *)(p))

/*
 *	Stack List:
 */
struct _stack_list_struct {

	GtkWidget	*toplevel;
	gboolean	map_state;
	gint		freeze_count,
			busy_count;

	stack_list_flags	flags;

	GtkWidget 	*src_clist,
			*tar_clist,
			*left_arrow_btn,
			*right_arrow_btn,
			*up_arrow_btn,
			*down_arrow_btn;

	gint		src_last_selected,	/* Last selected item indices */
			tar_last_selected;

	GtkWidget	*description_toplevel,
			*description_label;

	GtkWidget	*src_menu,
			*src_add_mi,
			*src_remove_mi;

	GtkWidget	*tar_menu,
			*tar_add_mi,
			*tar_remove_mi,
			*tar_up_mi,
			*tar_down_mi;

	/* Cache of Stack List Items */
	stack_list_item_struct	**item;
	gint			total_items;

	/* Last Stack List Item that was used for the description */
	stack_list_item_struct	*last_description_item;

	/* Changed Callback */
	void	(*changed_cb)(
		stack_list_struct *,		/* Stack List */
		gpointer			/* Data */
	);
	gpointer	changed_data;

        /* Added & Removed Callbacks */
        void	(*added_cb)(
		stack_list_struct *,		/* Stack List */
		stack_list_item_struct *,	/* Stack List Item */
                gpointer			/* Data */
        );
        gpointer	added_data;
        void	(*removed_cb)(
                stack_list_struct *,		/* Stack List */
                stack_list_item_struct *,	/* Stack List Item */
                gpointer			/* Data */
        );
        gpointer	removed_data;

};
#define STACK_LIST(p)	((stack_list_struct *)(p))


/* Stack List Item */
extern void StackListAppend(
	stack_list_struct *slist,
	const gchar *name,
	const gchar *description,
	guint8 **icon_data,
	gpointer client_data,
	gint id,
	gboolean allow_multiple, gboolean stay_on_target
);
extern void StackListClear(stack_list_struct *slist);

extern void StackListItemAppendSrc(stack_list_struct *slist, gint id);
extern void StackListItemAppendTar(stack_list_struct *slist, gint id);
extern void StackListItemSetAllFromCacheSrc(stack_list_struct *slist);

extern void StackListItemRemoveByIDSrc(
	stack_list_struct *slist, gint id,
	gboolean exclude_allowed_multiples
);
extern void StackListItemRemoveByIDTar(
	stack_list_struct *slist, gint id,
	gboolean exclude_allowed_multiples
);

extern void StackListItemClearSrc(stack_list_struct *slist);
extern void StackListItemClearTar(stack_list_struct *slist);

extern gint *StackListItemGetSrc(stack_list_struct *slist, gint *total);
extern gint *StackListItemGetTar(stack_list_struct *slist, gint *total);


/* Stack List */
extern stack_list_struct *StackListNew(
	GtkWidget *parent,
	const gchar *src_title, const gchar *tar_title
);
extern void StackListShowDescription(
        stack_list_struct *slist, 
        gboolean show_src_desc,
        gboolean show_tar_desc
);
extern void StackListSetMaintainSourceOrder(
	stack_list_struct *slist, gboolean maintain_source_order
);
extern void StackListSetChangedCB(
        stack_list_struct *slist, 
        void (*cb)(
                stack_list_struct *,		/* Stack List */
                gpointer			/* Data */
        ),
        gpointer data   
);
extern void StackListSetAddedCB(
        stack_list_struct *slist,
        void (*cb)(
                stack_list_struct *,		/* Stack List */
                stack_list_item_struct *,	/* Stack List Item */
                gpointer			/* Data */
        ),
        gpointer data
);
extern void StackListSetRemovedCB(
        stack_list_struct *slist,
        void (*cb)(
                stack_list_struct *,		/* Stack List */
                stack_list_item_struct *,	/* Stack List Item */
                gpointer			/* Data */
        ),                                                
        gpointer data
);
extern void StackListUpdateMenus(stack_list_struct *slist);
extern gboolean StackListMapped(stack_list_struct *slist);
extern void StackListMap(stack_list_struct *slist);
extern void StackListUnmap(stack_list_struct *slist);
extern void StackListDelete(stack_list_struct *slist);


#endif	/* STACKLIST_H */
