/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>  
 *
 *
 * Authors:
 *		Srinivasa Ragavan <sragavan@novell.com>
 *
 * Copyright (C) 2009 Novell, Inc. (www.novell.com)
 *
 */

#ifndef _EM_TREE_STORE_H
#define _EM_TREE_STORE_H

#include <glib-object.h>
#include <libedataserver/e-msgport.h>

struct _GtkTreeIter;
struct _CamelFolder;

typedef struct _EMTreeLeaf EMTreeLeaf;
typedef struct _EMTreeNode EMTreeNode;

/* To save memory, nodes with no children are stored in leaf nodes */
/* TODO: Actuallyu implement this scheme, perhaps */
struct _EMTreeLeaf {
	struct _EMTreeNode *next;
	struct _EMTreeNode *prev;
	struct _EMTreeNode *parent;

	CamelMessageInfo *info;

	unsigned int flags:4;
};

struct _EMTreeNode {
	struct _EMTreeNode *next;
	struct _EMTreeNode *prev;
	struct _EMTreeNode *parent;

	CamelMessageInfo *info;

	unsigned int flags:4;
	/* uid of the latest message in the thread of this node */
	const char *latest_uid;
	gpointer msg_ref; 
	EDList children;
};

#define EM_TREE_NODE_LEAF (1<<0)

typedef struct _EMTreeStore       EMTreeStore;
typedef struct _EMTreeStoreClass  EMTreeStoreClass;

typedef enum {
	EMTS_COL_MESSAGEINFO,
	EMTS_COL_FROM,	
	EMTS_COL_SUBJECT,
	EMTS_COL_DATE,
	EMTS_COL_TO,
	EMTS_COL_FLAGS,
	EMTS_COL_THREADCOUNT,
	EMTS_COL_THREADPREVIEW,
	EMTS_COL_UNREAD,
	EMTS_COL_ATTACHMENT,
	EMTS_COL_NUMBER
} emts_col_t;

/* helper table with some column info */
struct _emts_column_info {
	GType type;
	const char *id;
	const char *title;
};

extern struct _emts_column_info emts_column_info[EMTS_COL_NUMBER];
typedef int (*sort_func) (gpointer *, gpointer *, EMTreeStore *);
struct _EMTreeStore
{
	GObject parent;

	EMTreeNode *root;
	guint32 stamp;
	 sort_func func;
	 gboolean sort_ascending;
};

struct _EMTreeStoreClass
{
	GObjectClass parent_class;
};

GType em_tree_store_get_type (void);

EMTreeStore * em_tree_store_new(gboolean show_children);
void em_tree_store_add_folder (EMTreeStore *emts, CamelFolder *folder, const char *expr, gboolean prune);
void em_tree_store_set_folders(EMTreeStore *emts, GPtrArray *folders, const char *expr);
void em_tree_store_resort (EMTreeStore *emts);
int em_tree_store_get_iter(EMTreeStore *store, struct _GtkTreeIter *iter, const char *uid);
time_t em_tree_store_thread_time (EMTreeStore *emts, const char *uid);
int em_tree_store_count_children (EMTreeStore *emts, GtkTreeIter *iter);
GPtrArray * em_tree_store_get_child_sorted_tree (EMTreeStore  *emts, GtkTreeIter *iter);
CamelMessageInfo * em_tree_store_get_info_from_path_string (EMTreeStore  *emts, const char *path);
const char * em_tree_store_get_uid_from_iter (EMTreeStore  *emts, GtkTreeIter *iter);
int em_tree_store_get_iter(EMTreeStore *emts, GtkTreeIter *iter, const char *uid);
const CamelMessageInfo * em_tree_store_get_info_from_iter (EMTreeStore  *emts, GtkTreeIter *iter);
GPtrArray * em_tree_store_get_child_infos (EMTreeStore  *emts, GtkTreeIter *iter);
void em_tree_store_search_folder (EMTreeStore *emts, CamelFolder *folder, const char *expr, gboolean prune);
void em_tree_insert_sorted_with_data (EDList *list, gpointer data, GFunc func,gpointer user_data);

#endif /* _EM_TREE_STORE_H */
