/*
 * 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)
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include <glib/gi18n.h>
#include "mail-view.h"
#include "mail-folder-view.h"
#include "mail/em-folder-tree.h"
#include "mail/em-popup.h"
#include "mail/mail-mt.h"
#include "mail/mail-ops.h"
#include "mail/em-utils.h"
#include "mail/em-composer-utils.h"

#ifdef EVOLUTION_2_26
#include "mail/em-marshal.h"
#else
#include <e-util/e-marshal.h>
#endif
#include "misc/e-spinner.h"
#include "mail-sqlite-store.h"
#include "em-tree-store.h"
#include "custom-cell-renderer-hbox.h"
#include "custom-cell-renderer-vbox.h"
#include "custom-cell-renderer-toggle-pixbuf.h"
#include <e-util/e-util.h>
#include "mail-utils.h"
#include "mail-composer-view.h"
#include "mail-shell.h"

#include <gdk/gdkkeysyms.h>

struct  _MailFolderViewPrivate {
	guint light:1;
	guint show_thread:1;
	guint show_children:1;
	guint message_shown:1;
	guint show_preview:1;
	GtkWidget *box;
	GList *children;
	char *expr;
	GtkWidget *tab_str;
	GtkWidget *folder_pane;

	CamelFolder *folder;
	char *uid;
	
	int sort_selected;
	gboolean sort_ascending;
	GtkWidget *view_scroller;
	GtkWidget *info_bar;
	GtkWidget *info_spinner;
	CamelOperation *cancel;
	GtkCellRenderer *from_to;
	GtkTreeViewColumn *cols[3];

	GtkCellRenderer *unread_toggle;
	gpointer *last_active_cell;

	char *folder_name;
};

enum {
	MESSAGE_SHOWN,
	VIEW_CLOSE,
	MESSAGE_NEW,
	SEARCH_SET,
	VIEW_LOADED,
	LAST_SIGNAL
};

static const char * mfv_get_selected_uid (GtkTreeView *tree, MailFolderView *mfv);
static void mfv_message_activated (GtkTreeView       *tree_view,  GtkTreePath       *path, GtkTreeViewColumn *column,  MailFolderView *shell);
static void mfv_delete (MailFolderView *mfv, gboolean del);
static void mfv_read (MailFolderView *mfv, gboolean del);
static void mfv_junk  (MailFolderView *mfv, gboolean junk);
static void mfv_folder_renamed (CamelStore *store, void *event, void *data);
static gboolean mfv_msg_unread  (GtkCellRenderer *cell, GdkEvent *event,GtkWidget *widget,const gchar *path,const GdkRectangle *background_area,const GdkRectangle *cell_area,GtkCellRendererState flags);


static guint signals[LAST_SIGNAL] = { 0 };

G_DEFINE_TYPE (MailFolderView, mail_folder_view, GTK_TYPE_VBOX)

static char * empty_xpm[] = {
"16 16 2 1",
" 	c None",
".	c #FFFFFF",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                ",
"                "};


static int
sort_dsent (EMTreeNode **n1, EMTreeNode **n2, EMTreeStore *emts)
{
	time_t t1, t2;

	t1 = em_tree_store_thread_time (emts, camel_message_info_uid ((*n1)->info));
	t2 = em_tree_store_thread_time (emts, camel_message_info_uid ((*n2)->info));
	if (emts->sort_ascending)
		return t1-t2;
	else
		return t2-t1;
}

static int
sort_subject (EMTreeNode **n1, EMTreeNode **n2, EMTreeStore *emts)
{
	if (emts->sort_ascending)
		return strcmp (camel_message_info_subject ((*n1)->info), camel_message_info_subject ((*n2)->info)) ;
	else
		return strcmp (camel_message_info_subject ((*n2)->info), camel_message_info_subject ((*n1)->info)) ;
}

static int
sort_from (EMTreeNode **n1, EMTreeNode **n2, EMTreeStore *emts)
{
	if (emts->sort_ascending)
		return strcmp (camel_message_info_from ((*n1)->info), camel_message_info_from ((*n2)->info)) ;
	else
		return strcmp (camel_message_info_from ((*n2)->info), camel_message_info_from ((*n1)->info)) ;
}


/* Sorting */

struct _sort_data {
	char *label;
	sort_func func;
	int value;
} sorting[] = {
	{ N_("_Date"), (sort_func)sort_dsent, 1 },
	{ N_("_Subject"), (sort_func)sort_subject, 2 },
	{ N_("_From"), (sort_func)sort_from, 3 },
};

static gboolean
mfv_btn_expose (GtkWidget *w, GdkEventExpose *event, MailFolderView *mfv)
{
	GdkPixbuf *img = g_object_get_data ((GObject *)w, "pbuf");
	cairo_t *cr = gdk_cairo_create (w->window);
	cairo_save (cr);
	gdk_cairo_set_source_pixbuf (cr, img, event->area.x-5, event->area.y-4);
	cairo_paint(cr);
	cairo_restore(cr);
	cairo_destroy (cr);

	return TRUE;
}

static void
mfv_save (MailFolderView *mfv)
{
	const char *uid = mfv_get_selected_uid (mfv->tree, mfv);
	double pos;
	char *state;
	
	if (!mfv->priv->folder)
		return;

	if (uid && *uid) 
		 camel_object_meta_set (mfv->priv->folder, "anjal:selected_uid", uid);

	pos = gtk_adjustment_get_value(gtk_scrolled_window_get_vadjustment ((GtkScrolledWindow *)mfv->priv->view_scroller));
	state = g_strdup_printf ("%lf", pos);
	camel_object_meta_set (mfv->priv->folder, "anjal:scroll_position", state);
	camel_object_meta_set (mfv->priv->folder, "anjal:search_state", mfv->search_state);
	camel_object_meta_set (mfv->priv->folder, "anjal:search", mfv->search);
	camel_object_meta_set (mfv->priv->folder, "anjal:search_str", mfv->search_str);

	camel_object_state_write(mfv->priv->folder);
	g_free(state);
}

static void
mfv_close (GtkButton *w, MailFolderView *mfv)
{
	mfv_save(mfv);
	g_signal_emit (mfv, signals[VIEW_CLOSE], 0);			
}

static char *
mfv_folder_name (char *name)
{
	if (strcmp(name, CAMEL_VTRASH_NAME) == 0)
		return _("Trash");
	else if (strcmp (name, CAMEL_VJUNK_NAME) == 0)
		return _("Junk");

	return name;
}

static void
mail_folder_view_init (MailFolderView  *shell)
{
	GdkPixbuf *pbuf = gtk_widget_render_icon ((GtkWidget *)shell, "gtk-close", GTK_ICON_SIZE_MENU, NULL);
	GtkWidget *tool, *box, *img;
	int w=-1, h=-1;

	shell->type = MAIL_VIEW_FOLDER;
	shell->search_state = NULL;
	shell->search_str = NULL;
	img = gtk_image_new_from_pixbuf (pbuf);
	g_object_set_data ((GObject *)img, "pbuf", pbuf);
	g_signal_connect (img, "expose-event", G_CALLBACK(mfv_btn_expose), shell);
	shell->uri = g_strdup("folder://");
	tool = gtk_button_new ();
	gtk_button_set_relief((GtkButton *)tool, GTK_RELIEF_NONE);
	gtk_button_set_focus_on_click ((GtkButton *)tool, FALSE);
	gtk_widget_set_tooltip_text (tool, _("Close Tab"));
	g_signal_connect (tool, "clicked", G_CALLBACK(mfv_close), shell);
	
	box = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start ((GtkBox *)box, img, FALSE, FALSE, 0);
	gtk_container_add ((GtkContainer *)tool, box);
	gtk_widget_show_all (tool);
	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings(tool) , GTK_ICON_SIZE_MENU, &w, &h);
	gtk_widget_set_size_request (tool, w+2, h+2);
	
	shell->priv = g_new0(MailFolderViewPrivate, 1);
	shell->priv->message_shown = 0;
	shell->priv->light = g_getenv("ANJAL_LITE") != NULL; /*Very light mode, to be used in mobile phone and not netbooks. This need good implementation also. */
	shell->priv->show_preview = 1;
	shell->priv->show_thread = g_getenv("ANJAL_THREAD") != NULL; 
	shell->priv->show_children = g_getenv("ANJAL_CHILDREN") != NULL;
	shell->priv->folder = NULL;
	shell->search = NULL;
	shell->priv->cancel = NULL;
	if (shell->priv->light) 
		shell->model = mail_sqlite_store_new ();
	else {
		shell->model = (GtkTreeModel *)em_tree_store_new (shell->priv->show_children);
		((EMTreeStore *)shell->model)->func = (sort_func)sort_dsent;
		((EMTreeStore *)shell->model)->sort_ascending = FALSE;
	}
	shell->priv->expr = g_strdup ("(match-all (not (system-flag \"junk\")))");
	shell->tab_label  = gtk_hbox_new (FALSE, 0);
	shell->menu_label  = gtk_label_new (NULL);
	shell->priv->tab_str = gtk_label_new (_("Select Folder"));
	gtk_box_pack_start ((GtkBox *)shell->tab_label, shell->priv->tab_str, FALSE, FALSE, 0);
	gtk_box_pack_start ((GtkBox *)shell->tab_label, tool, FALSE, FALSE, 0);
	gtk_widget_show_all (shell->tab_label);
	g_object_unref (pbuf);
	shell->priv->uid  = NULL;
	shell->priv->folder = NULL;
	shell->priv->sort_selected = 1;
	shell->priv->sort_ascending = FALSE;
}

static void 
mfv_row_del (GtkTreeModel *model, GtkTreePath *path, MailFolderView *mfv)
{
	GtkTreeSelection *sel = gtk_tree_view_get_selection(mfv->tree);
	/* are we on last row now? */
	GtkTreeIter iter;
	gtk_tree_model_get_iter(model, &iter, path);
	if (!gtk_tree_model_iter_next(model, &iter))
	{
		/* last row is selected and being deleted, move to prev row */
		gtk_tree_path_prev(path);
	}
	gtk_tree_selection_select_path (sel, path);
}

static void
mail_folder_view_finalize (GObject *object)
{
	 MailFolderView *mfv = (MailFolderView  *)object;

	 if (mfv->priv->folder_name)
		 g_free (mfv->priv->folder_name);

	 if (mfv->priv->cancel) {
		camel_operation_cancel(mfv->priv->cancel);
	 }
	 if (mfv->search_state) {
		 g_free(mfv->search_state);
		 mfv->search_state = NULL;
	 }
	 if (mfv->search_str) {
		 g_free(mfv->search_str);
		 mfv->search_str = NULL;
	 }

	 if (mfv->priv->folder->parent_store)
		 camel_object_unhook_event (mfv->priv->folder->parent_store, "folder_renamed", (CamelObjectEventHookFunc)mfv_folder_renamed, mfv);

	 if (mfv->priv->folder) {
		  camel_object_unref (mfv->priv->folder);
	 }
	 g_signal_handlers_disconnect_by_func (mfv->model, mfv_row_del, mfv);
	 g_object_unref (mfv->model);

	 g_free (mfv->uri);
	 g_free (mfv->priv);
	G_OBJECT_CLASS (mail_folder_view_parent_class)->finalize (object);
}

void
mail_folder_view_set_message (MailFolderView *mfv, const char *uid, int nomarkseen)
{
}


struct _db_read_msg {
	MailMsg base;

	MailFolderView *mfv;
	CamelFolder *folder;
	const char *uri;
	gboolean load;

	void (*done) (MailFolderView *, CamelFolder *folder, const char *uri);
};

static void
db_read_exec (struct _db_read_msg *m)
{
	MailFolderView *mfv  = m->mfv;
	CamelFolder *folder = m->folder;
	

	if (folder) {
		/* Load cursor based or folder based */

		if (mfv->priv->light)
			mail_sqlite_store_set_folder ((MailSqliteStore *)mfv->model, folder, NULL);
		else {
			char *str;

			if (!mfv->search && m->load)
				em_tree_store_add_folder ((EMTreeStore *)mfv->model, folder, mfv->priv->expr, TRUE);
			else {

				str = g_strdup_printf("(and %s %s)", mfv->priv->expr, mfv->search);
				if (m->load)
					em_tree_store_add_folder ((EMTreeStore *)mfv->model, folder, str, TRUE);
				else
					em_tree_store_search_folder ((EMTreeStore *)mfv->model, folder, mfv->search ? str : mfv->priv->expr, TRUE);

				g_free(str);
			}
		}

		/* FIXME: Set a signal emit and listen for it at note book and set the title appropriately */
	}
}

static void
db_read_done (struct _db_read_msg *m)
{
	if (m->done)
		m->done (m->mfv, m->folder, m->uri);
	
}

static void
db_read_free (struct _db_read_msg *m)
{
	 g_free((char *)m->uri);
}

static MailMsgInfo db_read_info = {
	sizeof (struct _db_read_msg),
	(MailMsgDescFunc) NULL,
	(MailMsgExecFunc) db_read_exec,
	(MailMsgDoneFunc) db_read_done,
	(MailMsgFreeFunc) db_read_free
};

static void
mfv_db_load (MailFolderView *mfv, const char *uri, CamelFolder *folder)
{
	struct _db_read_msg *m;

	m = mail_msg_new (&db_read_info);
	m->mfv = mfv;
	m->load = TRUE;
	m->uri = g_strdup(uri);
	m->folder = folder;
	m->done = mail_folder_view_set_folder;
	mail_msg_unordered_push (m);
}

static void
mfv_got_folder(char *uri, CamelFolder *folder, void *data)
{
	MailFolderView *mfv = data;

	if (mfv->priv->folder) {
		mfv_save(mfv);
		g_signal_handlers_disconnect_by_func (mfv->model, mfv_row_del, mfv);
		gtk_tree_view_set_model (GTK_TREE_VIEW (mfv->tree), NULL);
		camel_object_unref (mfv->priv->folder);
		mfv->priv->folder= NULL;
		g_object_unref (mfv->model);

		if (mfv->priv->light) 
			mfv->model = mail_sqlite_store_new ();
		else {
			mfv->model = (GtkTreeModel *)em_tree_store_new (mfv->priv->show_children);
			((EMTreeStore *)mfv->model)->func = sorting[mfv->priv->sort_selected-1].func;;
			((EMTreeStore *)mfv->model)->sort_ascending = mfv->priv->sort_ascending;
		}
	}
	
	camel_object_ref(folder);

	mfv->search = camel_object_meta_get (folder, "anjal:search");
	mfv->search_state = camel_object_meta_get (folder, "anjal:search_state");
	mfv->search_str = camel_object_meta_get (folder, "anjal:search_str");
	mfv_db_load (mfv, uri, folder);
}

void
mail_folder_view_set_folder_uri (MailFolderView *mfv, const char *uri)
{
	char *str=NULL;

	if (uri && mfv->uri && !strcmp(uri, mfv->uri))
		 return;

	if (mfv->uri)
		 g_free(mfv->uri);
	mfv->uri = g_strdup(uri);
	gtk_widget_show (mfv->priv->info_spinner);
	gtk_widget_hide ((GtkWidget *)mfv->mail);
	gtk_widget_show ((GtkWidget *)mfv->priv->info_bar);
	gtk_widget_hide (mfv->priv->view_scroller);

	if (uri) {
		str = g_strdup_printf("%s %s", _("Loading folder"), uri);
		gtk_label_set_text (g_object_get_data((GObject *)mfv->priv->info_bar, "label"), str);
		g_free(str);
		mail_get_folder(uri, 0, mfv_got_folder, mfv, mail_msg_fast_ordered_push);
	}
}

static void
mfv_folder_renamed (CamelStore *store, void *event, void *data)
{
	MailFolderView *mfv = (MailFolderView *)data;
	CamelRenameInfo *info = (CamelRenameInfo *)event;
	if (g_strcmp0(info->old_base, mfv->priv->folder_name) == 0){
		/* Folder renamed. Revamp the uri.*/
		g_free(mfv->uri);
		g_free(mfv->priv->folder_name);
		mfv->uri = g_strdup(info->new->uri);
		mfv->priv->folder_name = g_strdup (info->new->full_name);
		gtk_label_set_text ((GtkLabel *)mfv->priv->tab_str, mfv_folder_name(info->new->full_name));
	}
}

void
mail_folder_view_set_folder (MailFolderView *mfv, CamelFolder *folder, const char *uri)
{
	
	if (mfv->priv->folder && 0) {
		gtk_tree_view_set_model (GTK_TREE_VIEW (mfv->tree), NULL);
		camel_object_unref (mfv->priv->folder);
		g_object_unref (mfv->model);
		if (mfv->priv->light) 
			mfv->model = mail_sqlite_store_new ();
		else {
			mfv->model = (GtkTreeModel *)em_tree_store_new (mfv->priv->show_children);
			((EMTreeStore *)mfv->model)->func = sorting[mfv->priv->sort_selected-1].func;;
			((EMTreeStore *)mfv->model)->sort_ascending = mfv->priv->sort_ascending;
		}
	}
	if (folder) {
		/* Load cursor based or folder based */
		char *last_sel_uid, *spos;
		double pos = 0;
		GtkTreeIter iter;
		gboolean outgoing = FALSE;
		
	        if (em_utils_folder_is_drafts(folder, uri)
			|| em_utils_folder_is_sent(folder, uri)
			|| em_utils_folder_is_outbox(folder, uri))
			outgoing = TRUE;
		if (mfv->priv->folder_name)
			g_free (mfv->priv->folder_name);
		mfv->priv->folder_name = g_strdup(folder->full_name);
		if (folder->parent_store)
			camel_object_hook_event (folder->parent_store, "folder_renamed", (CamelObjectEventHookFunc)mfv_folder_renamed, mfv);
		if (outgoing) {
			if (mfv->priv->light)
				g_object_set_data ((GObject *)mfv->priv->from_to, "data", GINT_TO_POINTER (COL_FROM)); /* Implement TO */
			else 
				g_object_set_data ((GObject *)mfv->priv->from_to, "data", GINT_TO_POINTER (EMTS_COL_TO));
		}
		gtk_tree_view_set_model (GTK_TREE_VIEW (mfv->tree), mfv->model);
		g_signal_connect (mfv->model, "row-deleted", G_CALLBACK(mfv_row_del), mfv);
		mfv->priv->folder = folder;
		gtk_widget_hide ((GtkWidget *)mfv->mail);
		gtk_widget_hide (mfv->priv->info_spinner);
		gtk_widget_hide (mfv->priv->info_bar);
		gtk_widget_show (mfv->priv->view_scroller);
		gtk_widget_show ((GtkWidget *)mfv->tree);		
		last_sel_uid = camel_object_meta_get (folder, "anjal:selected_uid");
		spos = camel_object_meta_get (folder, "anjal:scroll_position");
		if (spos && *spos) {
			pos = strtod(spos, NULL);
		}
		gtk_label_set_text ((GtkLabel *)mfv->priv->tab_str, mfv_folder_name(folder->full_name));
		gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment ((GtkScrolledWindow *)mfv->priv->view_scroller), pos);
		if (last_sel_uid && *last_sel_uid) {
			 GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
			 GtkTreePath *path;
			 if (em_tree_store_get_iter ((EMTreeStore *)mfv->model, &iter, last_sel_uid)) {
				  
				  gtk_tree_selection_select_iter (sel, &iter);
				  path = gtk_tree_model_get_path (mfv->model, &iter);
				  
				  gtk_tree_view_scroll_to_cell (mfv->tree, path, NULL, FALSE, 0, 0);
				  gtk_tree_path_free (path);
			 }
		}
		gtk_widget_grab_focus ((GtkWidget *)mfv->tree);
		if (mfv->search_str && *mfv->search_str)
			g_signal_emit (mfv, signals[SEARCH_SET], 0);			

		/* FIXME: Set a signal emit and listen for it at note book and set the title appropriately */
		g_signal_emit (mfv, signals[VIEW_LOADED], 0);
		mail_refresh_folder(folder, NULL, NULL);
	}
}

static void
mail_folder_view_class_init (MailFolderViewClass *klass)
{
	GObjectClass * object_class = G_OBJECT_CLASS (klass);

	signals[MESSAGE_SHOWN] =
		g_signal_new ("message-shown",
			      G_OBJECT_CLASS_TYPE (object_class),
			      G_SIGNAL_RUN_FIRST,
			      G_STRUCT_OFFSET (MailFolderViewClass , message_shown),
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);
	signals[VIEW_CLOSE] =
		g_signal_new ("view-close",
			      G_OBJECT_CLASS_TYPE (object_class),
			      G_SIGNAL_RUN_FIRST,
			      G_STRUCT_OFFSET (MailFolderViewClass , view_close),
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);
	signals[MESSAGE_NEW] =
		g_signal_new ("message-new",
			      G_OBJECT_CLASS_TYPE (object_class),
			      G_SIGNAL_RUN_FIRST,
			      G_STRUCT_OFFSET (MailFolderViewClass , message_new),
			      NULL, NULL,
#ifdef EVOLUTION_2_26			      
			      em_marshal_VOID__POINTER_POINTER,
#else
			      e_marshal_VOID__POINTER_POINTER,
#endif			      
			      G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
	signals[SEARCH_SET] =
		g_signal_new ("search-set",
			      G_OBJECT_CLASS_TYPE (object_class),
			      G_SIGNAL_RUN_FIRST,
			      G_STRUCT_OFFSET (MailFolderViewClass , search_set),
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);
	signals[VIEW_LOADED] =
		g_signal_new ("view-loaded",
			      G_OBJECT_CLASS_TYPE (object_class),
			      G_SIGNAL_RUN_FIRST,
			      G_STRUCT_OFFSET (MailFolderViewClass , view_loaded),
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);	
	mail_folder_view_parent_class = g_type_class_peek_parent (klass);
	object_class->finalize = mail_folder_view_finalize;	

};


static char *
filter_date (time_t date)
{
	time_t nowdate = time(NULL);
	time_t yesdate;
	struct tm then, now, yesterday;
	char buf[26];
	gboolean done = FALSE;

	if (date == 0)
		return g_strdup (_("?"));

	localtime_r (&date, &then);
	localtime_r (&nowdate, &now);
	if (then.tm_mday == now.tm_mday &&
	    then.tm_mon == now.tm_mon &&
	    then.tm_year == now.tm_year) {
		e_utf8_strftime_fix_am_pm (buf, 26, _("Today %l:%M %p"), &then);
		done = TRUE;
	}
	if (!done) {
		yesdate = nowdate - 60 * 60 * 24;
		localtime_r (&yesdate, &yesterday);
		if (then.tm_mday == yesterday.tm_mday &&
		    then.tm_mon == yesterday.tm_mon &&
		    then.tm_year == yesterday.tm_year) {
			e_utf8_strftime_fix_am_pm (buf, 26, _("Yesterday %l:%M %p"), &then);
			done = TRUE;
		}
	}
	if (!done) {
		int i;
		for (i = 2; i < 7; i++) {
			yesdate = nowdate - 60 * 60 * 24 * i;
			localtime_r (&yesdate, &yesterday);
			if (then.tm_mday == yesterday.tm_mday &&
			    then.tm_mon == yesterday.tm_mon &&
			    then.tm_year == yesterday.tm_year) {
				e_utf8_strftime_fix_am_pm (buf, 26, _("%a %l:%M %p"), &then);
				done = TRUE;
				break;
			}
		}
	}
	if (!done) {
		if (then.tm_year == now.tm_year) {
			e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %l:%M %p"), &then);
		} else {
			e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %Y"), &then);
		}
	}
#if 0
#ifdef CTIME_R_THREE_ARGS
	ctime_r (&date, buf, 26);
#else
	ctime_r (&date, buf);
#endif
#endif

	return g_strdup (buf);
}

static void
draw_img (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
{
  	CustomCellRendererVBox *cellprogress = CUSTOM_CELL_RENDERER_VBOX (cell);
	GList *tmp = cellprogress->children;
	GtkWidget *wid = g_object_get_data ((GObject *)tree_column, "widget");

	while (tmp) {
		  GtkCellRenderer *child = (GtkCellRenderer *)tmp->data;
		  char *data = g_object_get_data ((GObject *)child, "data");
		  GdkPixbuf *img;

		  if (!GTK_IS_CELL_RENDERER_PIXBUF(child)) {
			   tmp = tmp->next;
			   continue;
		  }
		  if (data) {
			  img = gtk_widget_render_icon (wid, data, GTK_ICON_SIZE_MENU, NULL);
			  g_object_set ((GObject *)child, "pixbuf", img, NULL);
		  } else {
			  g_object_set ((GObject *)child, "pixbuf", gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm), NULL);
		  }
		  tmp = tmp->next;
	}
}
static void
draw_text (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, MailFolderView *mfv)
{
  	CustomCellRendererVBox *cellprogress = CUSTOM_CELL_RENDERER_VBOX (cell);
  	GValue value = { 0, }, value1 = {0,};
	int i=0;
	gboolean bold, ellipsize, strike, markup;
	gboolean unread = FALSE;
	guint32 flags;
	GtkTreeIter sel_iter;
	GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
	gtk_tree_selection_get_selected (sel, NULL, &sel_iter);
	gboolean selected = iter->user_data == sel_iter.user_data;
	/*
	gtk_tree_model_get (tree_model, iter, 27, &rec, -1);

	text = g_strdup_printf("%s - %s  %s", rec->from,  rec->subject, rec->date ? rec->date : "");
	g_object_set (cell, "text", text,
		      "weight", rec->flags & CAMEL_MESSAGE_SEEN ? PANGO_WEIGHT_NORMAL : PANGO_WEIGHT_BOLD,
		      NULL);
      */
	
	g_value_init (&value,  G_TYPE_STRING);
	g_value_init (&value1,  G_TYPE_UINT);	
	GList *tmp = cellprogress->children;
	while (tmp) {
		  GtkCellRenderer *child = (GtkCellRenderer *)tmp->data;
		  if (i!=-1) {
			  g_value_unset (&value);
			  g_value_unset (&value1);
		  }

		  if (GTK_IS_CELL_RENDERER_TEXT (child) || CUSTOM_IS_CELL_RENDERER_HBOX(child)) {
			  i = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "data"));
			  ellipsize = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-ellipsize")) ? TRUE : FALSE;
			  bold = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-bold")) ? TRUE : FALSE;
			  strike = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-strike")) ? TRUE : FALSE;
			  markup = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-markup")) ? TRUE : FALSE;		  
			  if (i !=-1) {
				   GValue v = {0,}, v1 = {0};
				  g_value_init (&v,  G_TYPE_UINT);
				  g_value_unset (&v);
				  g_value_init (&v1,  G_TYPE_BOOLEAN);
				  g_value_unset (&v1);
				  if (i == EMTS_COL_THREADPREVIEW) /* Hack to set the selected color a bit different */
					  g_object_set_data ((GObject *)tree_model, "sel", GINT_TO_POINTER(selected));
				  gtk_tree_model_get_value (tree_model, iter, i, &value);
				  if (i == EMTS_COL_THREADPREVIEW)
					  g_object_set_data ((GObject *)tree_model, "sel", GINT_TO_POINTER(0));
			  
				  g_object_set_property ((GObject *)child, (gchar *) markup ? "markup" : "text", &value);
				  if (mfv->priv->light) {
					  gtk_tree_model_get_value (tree_model, iter, COL_FLAGS, &v);
				  } else {
					  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_FLAGS, &v);
					  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_UNREAD, &v1);
				  }
				  if(!mfv->priv->light)
					   unread = g_value_get_boolean (&v1);
				  flags = g_value_get_uint (&v);
				  g_object_set ((GObject *)child,"strikethrough", (strike &&  (flags &CAMEL_MESSAGE_DELETED)),
								"ellipsize", ellipsize ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_NONE, NULL);
				  if (bold) {
					   if ( mfv->priv->light)
							g_object_set ((GObject *)child, "weight", ((!(flags &CAMEL_MESSAGE_SEEN))) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL);
					   else
							g_object_set ((GObject *)child, "weight", (unread ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL), NULL);
				  }
				  g_value_unset (&value);
				  i=-1;
			  }
			  else { /* if -1, then it must be a hbox*/
				  CustomCellRendererHBox *hb = (CustomCellRendererHBox *)child;
				  GList *t = hb->start_children;
				  while (t) {
					  GtkCellRenderer *c = (GtkCellRenderer *)t->data;
					  if (GTK_IS_CELL_RENDERER_TEXT (c)) {
						   GValue v = {0,},  v1 = {0};
						  g_value_init (&v,  G_TYPE_UINT);
						  g_value_unset (&v);
						  g_value_init (&v1,  G_TYPE_BOOLEAN);
						  g_value_unset (&v1);
						  i = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "data"));
						  ellipsize = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-ellipsize")) ? TRUE : FALSE;
						  bold = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-bold")) ? TRUE : FALSE;
						  strike = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-strike")) ? TRUE : FALSE;
						  markup = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-markup")) ? TRUE : FALSE;		  
						  gtk_tree_model_get_value (tree_model, iter, i, &value);
						  if (!mfv->priv->light && i == EMTS_COL_DATE) {
							  char *str = filter_date (g_value_get_uint(&value));
							  g_object_set ((GObject *)c, "text", str, NULL);
							  g_free(str);
						  } else {
							  g_object_set_property ((GObject *)c, (gchar *) markup ? "markup" : "text", &value);
						  }
						  if (mfv->priv->light) {
							  gtk_tree_model_get_value (tree_model, iter, COL_FLAGS, &v);
						  } else {
							  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_FLAGS, &v);
							  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_UNREAD, &v1);
						  }
						  
						  flags = g_value_get_uint (&v);
						  if(!mfv->priv->light)
							   unread = g_value_get_boolean (&v1);
						  g_object_set ((GObject *)c,"strikethrough", (strike &&  (flags &CAMEL_MESSAGE_DELETED)),
										"ellipsize", ellipsize ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_NONE, NULL);
						  if (bold) {
							   if ( mfv->priv->light)
									g_object_set ((GObject *)c, "weight", ((!(flags &CAMEL_MESSAGE_SEEN))) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL);
							   else
									g_object_set ((GObject *)c, "weight", (unread ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL), NULL);
						  }
						  g_value_unset (&value);
						 
					  } else if (GTK_IS_CELL_RENDERER_TOGGLE(c)) {
						   GValue v = {0,},  v1 = {0};
						   g_value_init (&v,  G_TYPE_UINT);
						   g_value_unset (&v);
						   g_value_init (&v1,  G_TYPE_BOOLEAN);
						   g_value_unset (&v1);

						   /* Assume for now its only flags */
						  if (mfv->priv->light) {
							  gtk_tree_model_get_value (tree_model, iter, COL_FLAGS, &v);
							  flags = g_value_get_uint (&v);
							  gtk_cell_renderer_toggle_set_active ((GtkCellRendererToggle *)c, (flags & CAMEL_MESSAGE_SEEN) != 0);
						  } else {
							  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_UNREAD, &v1);
							  unread = g_value_get_boolean (&v1);
							  gtk_cell_renderer_toggle_set_active ((GtkCellRendererToggle *)c, unread);
						  }
						   
					  }

					  i=-1;
					  t = t->next;
				  }
				  t = hb->end_children;
				  while (t) {
					GtkCellRenderer *c = (GtkCellRenderer *)t->data;
					guint32 flags;
					if (GTK_IS_CELL_RENDERER_TEXT (c)) {
						 GValue v1 = {0};
						 g_value_init (&v1,  G_TYPE_BOOLEAN);
						 g_value_unset (&v1);

						i = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "data"));
						ellipsize = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-ellipsize")) ? TRUE : FALSE;
						bold = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-bold")) ? TRUE : FALSE;
						strike = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-strike")) ? TRUE : FALSE;
						markup = GPOINTER_TO_INT(g_object_get_data((GObject *)c, "p-markup")) ? TRUE : FALSE;		  
						  if (!mfv->priv->light && i == EMTS_COL_DATE) {
							  
							  char *str =NULL;
							  GValue v = {0,};
							  g_value_init (&v,  G_TYPE_ULONG);
							  g_value_unset (&v);
							  gtk_tree_model_get_value (tree_model, iter, i, &v);
							  str = filter_date (g_value_get_ulong(&v));
							  g_object_set ((GObject *)c, "text", str, NULL);
							  g_free(str);

						  } else {
							  gtk_tree_model_get_value (tree_model, iter, i, &value);
							  g_object_set_property ((GObject *)c, (gchar *) markup ? "markup" : "text", &value);
							  g_value_unset (&value);
						  }
						  if (mfv->priv->light)
							  gtk_tree_model_get_value (tree_model, iter, COL_FLAGS, &value1);
						  else {
							  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_FLAGS, &value1);
							  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_UNREAD, &v1);
						  }
						flags = g_value_get_uint (&value1);
						  if(!mfv->priv->light)
							   unread = g_value_get_boolean (&v1);						  
						  if (bold) {
							   if ( mfv->priv->light)
									g_object_set ((GObject *)c, "weight", ((!(flags &CAMEL_MESSAGE_SEEN))) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL);
							   else
									g_object_set ((GObject *)c, "weight", (unread ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL), NULL);
						  }						
						g_object_set ((GObject *)c,"strikethrough", (strike &&  (flags &CAMEL_MESSAGE_DELETED)),
									  "ellipsize", ellipsize ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_NONE, NULL);
						
						g_value_unset (&value1);
					} else {
						/* We render attachment icon here */
						 GValue v1 = {0};
						 g_value_init (&v1,  G_TYPE_BOOLEAN);
						 g_value_unset (&v1);
						 
						 gtk_tree_model_get_value (tree_model, iter, EMTS_COL_ATTACHMENT, &v1);
						 if (g_value_get_boolean (&v1)) {
			 				g_object_set ((GObject *)c, "pixbuf", mail_utils_get_icon("mail-attachment", GTK_ICON_SIZE_MENU), NULL);
		  				 } else {
			  				g_object_set ((GObject *)c, "pixbuf", gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm), NULL);
		  				 }
					}
					i=-1;
					t = t->next;
				  }

			  }
			  if (i!= -1) {
				  g_value_unset (&value);
				  g_value_unset (&value1);
			  }
		  } else {
			  
			  i = -1;
		  }
		  tmp = tmp->next;
	}
}

static void
draw_flags (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, MailFolderView *mfv)
{
  	CustomCellRendererVBox *cellprogress = CUSTOM_CELL_RENDERER_VBOX (cell);
	int i=0;
	gboolean bold, ellipsize, strike, markup;
	gboolean unread = FALSE;

	GList *tmp = cellprogress->children;
	while (tmp) {
		  GtkCellRenderer *child = (GtkCellRenderer *)tmp->data;

		  if (CUSTOM_IS_CELL_RENDERER_TOGGLE_PIXBUF (child)) {
			  i = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "data"));
			  ellipsize = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-ellipsize")) ? TRUE : FALSE;
			  bold = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-bold")) ? TRUE : FALSE;
			  strike = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-strike")) ? TRUE : FALSE;
			  markup = GPOINTER_TO_INT(g_object_get_data((GObject *)child, "p-markup")) ? TRUE : FALSE;		  
			  if (i !=-1) {
				   GValue v1 = {0};
				  g_value_init (&v1,  G_TYPE_BOOLEAN);
				  g_value_unset (&v1);

				  if (mfv->priv->light) {
//					  gtk_tree_model_get_value (tree_model, iter, COL_FLAGS, &v);
					   /* unread for light tbd */
				  } else {
					  gtk_tree_model_get_value (tree_model, iter, EMTS_COL_UNREAD, &v1);
				  }
				  
				  if(!mfv->priv->light)
					   unread = g_value_get_boolean (&v1);
				  g_object_set ((GObject *)child, "active", unread, NULL);
			  }
		  }
		  
		  tmp = tmp->next;
	}
}

void
mail_folder_view_show_list (MailFolderView *mfv)
{
	 mfv->priv->message_shown = 0;
	gtk_widget_show ((GtkWidget *)mfv->tree);
	gtk_widget_show (mfv->priv->view_scroller);
	gtk_widget_hide ((GtkWidget *)mfv->mail);
	gtk_widget_grab_focus ((GtkWidget *)mfv->tree);
	
}

static const char *
mfv_get_selected_uid (GtkTreeView *tree, MailFolderView *mfv)
{
	 GtkTreeSelection *sel = gtk_tree_view_get_selection (tree);
	 GtkTreeIter iter;
	 gboolean selected;
	 
	 selected = gtk_tree_selection_get_selected (sel, NULL, &iter);
	 if(!selected)
		  return NULL;
	 
	 return em_tree_store_get_uid_from_iter ((EMTreeStore *)mfv->model, &iter);
}

static const CamelMessageInfo *
mfv_get_selected_info (GtkTreeView *tree, MailFolderView *mfv)
{
	 GtkTreeSelection *sel = gtk_tree_view_get_selection (tree);
	 GtkTreeIter iter;
	 gboolean selected;
	 
	 selected = gtk_tree_selection_get_selected (sel, NULL, &iter);
	 if(!selected)
		  return NULL;
	 
	 return em_tree_store_get_info_from_iter((EMTreeStore *)mfv->model, &iter);
}

static GPtrArray *
mfv_get_selected_threads (MailFolderView *mfv)
{
	GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
	GList *slist = gtk_tree_selection_get_selected_rows (sel, NULL);
	GList *tmp;
	GPtrArray *uids = g_ptr_array_new ();
	GtkTreeIter iter;
	
	tmp = slist;
	while (tmp) {
		 GtkTreePath *path = (GtkTreePath *)tmp->data;
		 gtk_tree_model_get_iter (mfv->model, &iter, path);
		 g_ptr_array_add (uids, g_strdup(em_tree_store_get_uid_from_iter ((EMTreeStore *)mfv->model, &iter)));
		 tmp = tmp->next;
	}
	g_list_foreach (slist, (GFunc)gtk_tree_path_free, NULL);
	g_list_free (slist);

	return uids;
}

static void
mfv_popup_open_new_tab (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 MailConvView *mcv = NULL;
	 GtkTreeIter iter;
	 GPtrArray *uids;	 
	 GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
	 char *umid;

	 gtk_tree_selection_get_selected (sel, NULL, &iter);
	 uids = em_tree_store_get_child_sorted_tree ((EMTreeStore *)mfv->model, &iter);
	
	 if (!uids || uids->len <= 0)
		 return;

	 umid = g_strdup_printf("message://%s/%s", mfv->priv->folder->full_name, (char *)uids->pdata[0]);

	 g_signal_emit (mfv, signals[MESSAGE_NEW], 0, &mcv, umid);
	 if (!mcv)
		  return;

	 mail_conv_view_set_thread (mcv, mfv->priv->folder, mfv->uri, uids);
}

static void
mfv_popup_open_current_tab (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 GtkTreeIter iter;
	 GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
	 GtkTreePath *path;
	 
	 gtk_tree_selection_get_selected (sel, NULL, &iter);
	 path = gtk_tree_model_get_path (mfv->model, &iter);
	 mfv_message_activated (mfv->tree,  path, NULL,  mfv);
	 gtk_tree_path_free (path);
}

static void
mfv_popup_read (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_read (mfv, TRUE);
}

static void
mfv_popup_unread (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_read (mfv, FALSE);
}

static void
mfv_popup_junk (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_junk (mfv, TRUE);
}

static void
mfv_popup_nojunk (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_junk (mfv, FALSE);
}


static void
mfv_popup_delete (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_delete (mfv, TRUE);
}

static void
mfv_popup_undelete (EPopup *ep, EPopupItem *pitem, void *data)
{
	 MailFolderView *mfv = (MailFolderView *)data;
	 mfv_delete (mfv, FALSE);
}

static void
mfv_message_got(CamelFolder *folder, const char *uid, CamelMimeMessage *msg, void *data, CamelException *ex)
{
	EMsgComposer *composer;
	MailFolderView *mfv = (MailFolderView *)data;
	MailComposerView *mcv;

	mfv->priv->cancel = NULL;
	composer = (EMsgComposer *)em_utils_edit_message (msg, folder);
	mcv = (MailComposerView *)mail_shell_create_composer ();
	mail_composer_view_replace_composer ((struct _MailComposerView *)mcv, (GtkWidget *)composer);
}

static void
mfv_open_composer (MailFolderView *mfv, char *uid)
{
	e_msg_composer_set_lite();
	mfv->priv->cancel = mail_get_messagex (mfv->priv->folder, uid, mfv_message_got, mfv, mail_msg_fast_ordered_push);
}

static EPopupItem mfv_popup_items[] = {
//	{ E_POPUP_ITEM, "10.emfv.00", N_("_Reply to Sender"), emfv_popup_reply_sender, NULL, "mail-reply-sender", EM_POPUP_SELECT_ONE },
//	{ E_POPUP_ITEM, "10.emfv.01", N_("Reply to _All"), emfv_popup_reply_all, NULL, "mail-reply-all", EM_POPUP_SELECT_ONE },
//	{ E_POPUP_ITEM, "10.emfv.02", N_("_Forward"), emfv_popup_forward, NULL, "mail-forward", EM_POPUP_SELECT_MANY },
	{ E_POPUP_ITEM, "10.mfv.00", N_("_Open in New Tab"), mfv_popup_open_new_tab, NULL, "stock_mail-open", EM_POPUP_SELECT_ONE },
	{ E_POPUP_ITEM, "10.mfv.01", N_("_Open in This Tab"), mfv_popup_open_current_tab, NULL, "stock_mail-open", EM_POPUP_SELECT_ONE },
	{ E_POPUP_BAR, "40.mfv", NULL, NULL, NULL, NULL },
	{ E_POPUP_ITEM, "40.mfv.00", N_("_Delete"), mfv_popup_delete, NULL, "edit-delete", EM_POPUP_SELECT_DELETE },
	{ E_POPUP_ITEM, "40.mfv.01", N_("U_ndelete"), mfv_popup_undelete, NULL, NULL, EM_POPUP_SELECT_UNDELETE },
	{ E_POPUP_BAR, "50.mfv", NULL, NULL, NULL, NULL },
	{ E_POPUP_ITEM, "50.mfv.00", N_("Mar_k as Read"), mfv_popup_read, NULL, "mail-mark-read", EM_POPUP_SELECT_MARK_READ },
	{ E_POPUP_ITEM, "50.mfv.01", N_("Mark as _Unread"), mfv_popup_unread, NULL, "mail-mark-unread", EM_POPUP_SELECT_MARK_UNREAD },
//	{ E_POPUP_ITEM, "50.mfv.02", N_("Mark as _Important"), emfv_popup_mark_important, NULL, "mail-mark-important", EM_POPUP_SELECT_MARK_IMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
//	{ E_POPUP_ITEM, "50.mfv.03", N_("Mark as Un_important"), emfv_popup_mark_unimportant, NULL, NULL, EM_POPUP_SELECT_MARK_UNIMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
	{ E_POPUP_ITEM, "50.mfv.04", N_("Mark as _Junk"), mfv_popup_junk, NULL, "mail-mark-junk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_JUNK },
	{ E_POPUP_ITEM, "50.mfv.05", N_("Mark as _Not Junk"), mfv_popup_nojunk, NULL, "mail-mark-notjunk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_NOT_JUNK },

};

static void
mfv_popup_items_free(EPopup *ep, GSList *items, void *data)
{
	g_slist_free(items);
}

static void
mfv_popup (MailFolderView *mfv, GdkEvent *event)
{
	GSList *menus = NULL;
	GtkMenu *menu;
	EMPopup *emp;
	EMPopupTargetSelect *t;
	int i;
	GtkTreePath *path = NULL;

	if (gtk_tree_view_get_path_at_pos (mfv->tree, event->button.x, event->button.y, &path, NULL, NULL, NULL)) {
		 GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
		 gtk_tree_selection_select_path (sel, path);
		 gtk_tree_path_free (path);
	} else {
		return;
	}
	
	/** @HookPoint-EMPopup: Message List Context Menu
	 * @Id: org.gnome.evolution.anjal.mail.folderview.popup.select
	 * @Type: EMPopup
	 * @Target: EMPopupTargetSelect
	 *
	 * This is the context menu shown on the message list.
	 */
	emp = em_popup_new("org.gnome.evolution.anjal.mail.folderview.popup");
	t = em_popup_target_new_select(emp, mfv->priv->folder, mfv->uri, mfv_get_selected_threads(mfv));
	t->target.widget = (GtkWidget *)mfv;

	for (i=0;i<G_N_ELEMENTS(mfv_popup_items); i++)
		 menus = g_slist_prepend(menus, &mfv_popup_items[i]);

	e_popup_add_items((EPopup *)emp, menus, NULL, mfv_popup_items_free, mfv);
	menu = e_popup_create_menu_once((EPopup *)emp, (EPopupTarget *)t, 0);

	gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
	
}

static gboolean
mfv_button_clicked (GtkWidget *w, GdkEventButton *event, MailFolderView *mfv)
{
	gboolean outgoing = FALSE;
	int x, y;
	GtkTreePath *path = NULL;
	GtkTreeViewColumn *column = NULL;


	x = (int) event->x;
	y = (int) event->y;

	if (gtk_tree_view_get_path_at_pos (mfv->tree, x, y, &path, &column, NULL, NULL) && column == mfv->priv->cols[0]) {
		char *str = gtk_tree_path_to_string (path);

		mfv_msg_unread (mfv->priv->unread_toggle, NULL, w, str, NULL, NULL, 0);
		g_free (str);
		gtk_tree_path_free (path);

		return TRUE;
	}
	if (path)
		gtk_tree_path_free (path);

	if (em_utils_folder_is_drafts(mfv->priv->folder, mfv->uri)
		|| em_utils_folder_is_outbox(mfv->priv->folder, mfv->uri))
		outgoing = TRUE;

	if (event->button == 2 || event->type == GDK_2BUTTON_PRESS) {
		MailConvView *mcv = NULL;
		GtkTreePath *path=NULL;
		GtkTreeIter iter;
		GPtrArray *uids;

		if (gtk_tree_view_get_path_at_pos (mfv->tree, event->x, event->y, &path, NULL, NULL, NULL)) {
			if (gtk_tree_model_get_iter (mfv->model, &iter, path)) {
				char *umid = NULL;

				uids = em_tree_store_get_child_sorted_tree ((EMTreeStore *)mfv->model, &iter);
				if (!outgoing && uids && uids->len >0) {
					umid = g_strdup_printf("message://%s/%s\n", mfv->priv->folder->full_name, (char *)uids->pdata[0]);
					g_signal_emit (mfv, signals[MESSAGE_NEW], 0, &mcv, umid);
					g_free(umid);

					if (!mcv)
						return TRUE;
				}
				if (outgoing)
					mfv_open_composer (mfv, (char *)uids->pdata[0]);
				else
					mail_conv_view_set_thread (mcv, mfv->priv->folder, mfv->uri, uids);
			}
			gtk_tree_path_free(path);
		} 
		return TRUE;
	} else if (event->button == 3) {
			 /* Right click */
			 mfv_popup (mfv, (GdkEvent *)event);
			 return TRUE;
	}
	return FALSE;
}

static void
mfv_message_activated (GtkTreeView       *tree_view,  GtkTreePath       *path, GtkTreeViewColumn *column,  MailFolderView *shell)
{
	GtkTreeIter iter;
	CamelMessageInfo *info = NULL;
	gboolean outgoing = FALSE;

	
	if (em_utils_folder_is_drafts(shell->priv->folder, shell->uri)
		|| em_utils_folder_is_outbox(shell->priv->folder, shell->uri))
		outgoing = TRUE;

	if (!outgoing) {
		shell->priv->message_shown = 1;
		gtk_widget_hide ((GtkWidget *)shell->tree);
		gtk_widget_hide (shell->priv->view_scroller);
		gtk_widget_show ((GtkWidget *)shell->mail);
	}

	if (!gtk_tree_model_get_iter (shell->model, &iter, path)) {
		g_warning ("Unable to open message\n");
		return;
	}
	gtk_tree_model_get (shell->model, &iter, EMTS_COL_MESSAGEINFO, &info, -1);
	if (!outgoing)
		shell->priv->uid = g_strdup (info->uid);
	
	if (shell->priv->light) {
		/* Implement plain message view */
	} else {
		/* Threaded message view */
		GPtrArray *msgs = em_tree_store_get_child_sorted_tree ((EMTreeStore *)shell->model, &iter);
		
		/* FIXME: Handle 'Sent' messages */
		if (!outgoing)
			mail_conv_view_set_thread (shell->mail, shell->priv->folder, shell->uri, msgs);
		else
			mfv_open_composer(shell, msgs->pdata[0]);
	}
	if (!outgoing)
		g_signal_emit (shell, signals[MESSAGE_SHOWN], 0);			
}

static void
mfv_tree_resize (GtkWidget *w, GtkAllocation *req, GtkTreeViewColumn *col)
{
	MailFolderView *shell = g_object_get_data((GObject *)w, "shell");

	gtk_tree_view_column_set_fixed_width (shell->priv->cols[2], 24);
	/* gtk_tree_view_column_set_sizing (shell->priv->cols[2], GTK_TREE_VIEW_COLUMN_AUTOSIZE); */

	if ((req->width - (gtk_tree_view_column_get_fixed_width(col)+56) > 1) && GTK_WIDGET_VISIBLE(shell->priv->folder_pane)) 
		gtk_tree_view_column_set_fixed_width (shell->priv->cols[1], req->width - 80);
	gtk_tree_view_column_set_fixed_width (shell->priv->cols[2], 16);

	g_signal_handlers_disconnect_by_func (w, mfv_tree_resize, col);
}


static void
mfv_selection_mark (MailFolderView *mfv, guint32 mask, guint32 set)
{
	 GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);
	 GtkTreeIter iter;
	 gboolean selected;
	 CamelMessageInfo *info = (CamelMessageInfo *) mfv_get_selected_info (mfv->tree, mfv);
	 GPtrArray *msgs = NULL;
	 int i;
	 
	 selected = gtk_tree_selection_get_selected (sel, NULL, &iter);
	 if(!selected)
		  return;

	 camel_message_info_set_flags (info, mask, set);
	 msgs = em_tree_store_get_child_infos ((EMTreeStore *)mfv->model, &iter);
	 for (i=0; i<msgs->len; i++)
		  camel_message_info_set_flags ((CamelMessageInfo *)msgs->pdata[i], mask, set);
}

static void
mfv_delete (MailFolderView *mfv, gboolean del)
{
	 if (del)
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED );
	 else
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_DELETED, 0 );
}

static void
mfv_junk  (MailFolderView *mfv, gboolean junk)
{
	 if (junk)
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);	 
	 else
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN, CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN);
}

static void
mfv_read (MailFolderView *mfv, gboolean read)
{
	 if (read)
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
	 else
		  mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, 0);
}
#ifdef NOT_USED
static CamelMessageInfo *
mfv_get_info (GObject *obj, char *path)
{
	 MailFolderView *mfv = g_object_get_data((GObject *)obj, "mfv");
	 return em_tree_store_get_info_from_path_string ((EMTreeStore *)mfv->model, path);
	 
}
#endif

static void
mfv_selection_mark_signal (MailFolderView *mfv, guint32 mask, guint32 set)
{
	 GtkTreeIter iter;
	 CamelMessageInfo *info;
	 GPtrArray *msgs = NULL;
	 int i;
	 GtkTreePath *path = NULL;

	 if (!gtk_tree_view_get_path_at_pos (mfv->tree, mfv->x_pos, mfv->y_pos, &path, NULL, NULL, NULL))
		 return;

	 gtk_tree_model_get_iter (mfv->model, &iter, path);
	 gtk_tree_path_free (path);

	 info = (CamelMessageInfo *)em_tree_store_get_info_from_iter((EMTreeStore *)mfv->model, &iter);
	 camel_message_info_set_flags (info, mask, set);
	 msgs = em_tree_store_get_child_infos ((EMTreeStore *)mfv->model, &iter);
	 for (i=0; i<msgs->len; i++)
		  camel_message_info_set_flags ((CamelMessageInfo *)msgs->pdata[i], mask, set);
}

static gboolean
mfv_msg_delete  (GtkCellRenderer *cell, GdkEvent *event,GtkWidget *widget,const gchar *path,const GdkRectangle *background_area,const GdkRectangle *cell_area,GtkCellRendererState flags)
{
	 MailFolderView *mfv = g_object_get_data((GObject *)cell, "mfv");
	 
	 mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED );
	 return TRUE;
}

static gboolean
mfv_msg_unread  (GtkCellRenderer *cell, GdkEvent *event,GtkWidget *widget,const gchar *path,const GdkRectangle *background_area,const GdkRectangle *cell_area,GtkCellRendererState flags)
{
	 MailFolderView *mfv = g_object_get_data((GObject *)cell, "mfv");
	 GtkTreeIter iter;
	 CamelMessageInfo *info;
	 GtkTreePath *tpath = NULL;

	 if (!gtk_tree_view_get_path_at_pos (mfv->tree, mfv->x_pos, mfv->y_pos, &tpath, NULL, NULL, NULL))
		 return TRUE;

	 gtk_tree_model_get_iter (mfv->model, &iter, tpath);
	 gtk_tree_path_free (tpath);
	 info = (CamelMessageInfo *)em_tree_store_get_info_from_iter((EMTreeStore *)mfv->model, &iter);

	 if ((camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN) == 0)
		  mfv_selection_mark_signal (mfv, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
	 else
		  mfv_selection_mark_signal (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, 0);
	 /*
	if (camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN)
		 camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, 0);
	else
		 camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);	  
	 */
	 return TRUE;
}

static gboolean
mfv_msg_junk (GtkCellRenderer *cell, GdkEvent *event,GtkWidget *widget,const gchar *path,const GdkRectangle *background_area,const GdkRectangle *cell_area,GtkCellRendererState flags)
{
	 MailFolderView *mfv = g_object_get_data((GObject *)cell, "mfv");
	 
	  mfv_selection_mark (mfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);	 
          // camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);	 

	 return TRUE;
}


static gboolean
mfv_key_pressed (GtkWidget *w, GdkEventKey *event, MailFolderView *mfv)
{
	 gboolean shift = event->state & GDK_SHIFT_MASK ? TRUE : FALSE;
	 
	 switch (event->keyval) {
	 case GDK_D:
	 case GDK_d:		  
		  if (!(event->state & GDK_CONTROL_MASK))
			   return FALSE;
	 case GDK_Delete:
		  mfv_delete (mfv, !shift);
		  break;
	 case GDK_J:
	 case GDK_j:
		  mfv_junk (mfv, !shift);
		  break;
	 case GDK_M:
	 case GDK_m:
		  mfv_read(mfv, !shift);
		  break;
	 default:
		  return FALSE;
	 }
	 
	 return TRUE;
}

enum {
	DND_X_UID_LIST,		/* x-uid-list */
	DND_MESSAGE_RFC822,	/* message/rfc822 */
	DND_TEXT_URI_LIST	/* text/uri-list */
};

static GtkTargetEntry ml_drag_types[] = {
	{ (gchar *) "x-uid-list", 0, DND_X_UID_LIST },
	{ (gchar *) "text/uri-list", 0, DND_TEXT_URI_LIST },
};

static void                
mfv_drag_data_get (GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *data, guint info, guint time, gpointer user_data)
{
	MailFolderView *mfv = (MailFolderView *)user_data;
	GPtrArray *uids;
	GtkTreeIter iter;
	GtkTreeSelection *sel = gtk_tree_view_get_selection (mfv->tree);

	gtk_tree_selection_get_selected (sel, NULL, &iter);
	uids = em_tree_store_get_child_sorted_tree ((EMTreeStore *)mfv->model, &iter);

	if (uids->len > 0) {
		switch (info) {
		case DND_X_UID_LIST:
			em_utils_selection_set_uidlist(data, mfv->uri, uids);
			break;
		case DND_TEXT_URI_LIST:
			em_utils_selection_set_urilist(data, mfv->priv->folder, uids);
			break;
		}
	}

	/* FIXME: Free uids*/
}	

static void
mfv_drag_data_delete (GtkWidget *w, GdkDragContext *drag_context, gpointer data)
{
	g_signal_stop_emission_by_name (w, "drag-data-delete");
}

static gboolean
mfv_motion_tree (GtkWidget *w, GdkEventMotion *event, MailFolderView *mfv)
{
	int x, y;
	GtkTreePath *path = NULL;
	GtkTreeViewColumn *column = NULL;
	int cell_x=0, cell_y=0;


	x = (int) event->x;
	y = (int) event->y;

	if (gtk_tree_view_get_path_at_pos (mfv->tree, x, y, &path, &column, &cell_x, &cell_y) && column == mfv->priv->cols[0]) {
		GtkTreeIter iter;
		
		mfv->x_pos = x;
		mfv->y_pos = y;
		gtk_tree_model_get_iter (mfv->model, &iter, path);
		if (!mfv->priv->last_active_cell || mfv->priv->last_active_cell != iter.user_data) {
			mfv->priv->last_active_cell = iter.user_data;
		}
	}

	return FALSE;
}

void
mail_folder_view_construct (MailFolderView *shell)
{
	MailFolderViewPrivate *priv = shell->priv;
	GtkWidget *viewbox, *infolabel, *align;
	GtkTreeViewColumn *column;
	GtkCellRenderer *cell;
	GtkCellRenderer *hbox, *vbox;
	GtkTreeSelection *sel;
	
	viewbox = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (viewbox);
	infolabel = gtk_label_new (_("Please select a folder on the folder tree"));
	gtk_widget_show (infolabel);
	align = gtk_alignment_new (0, 0, 0, 0);
	gtk_widget_show (align);
	priv->info_bar = gtk_hbox_new (FALSE, 3);
	priv->info_spinner = e_spinner_new_spinning_small_shown ();
	gtk_widget_hide (priv->info_spinner);
	g_object_set_data ((GObject *)priv->info_bar, "label", infolabel);
	gtk_box_pack_start ((GtkBox *)priv->info_bar, align, FALSE, FALSE, 100);
	gtk_box_pack_start ((GtkBox *)priv->info_bar, priv->info_spinner, FALSE, FALSE, 0);
	gtk_box_pack_start ((GtkBox *)priv->info_bar, infolabel, FALSE, FALSE, 0);
	gtk_widget_show (priv->info_bar);
	gtk_box_pack_start ((GtkBox *)viewbox, priv->info_bar, TRUE, TRUE, 0);
	priv->view_scroller = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->view_scroller),
										 GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->view_scroller),
									GTK_POLICY_NEVER,
									GTK_POLICY_AUTOMATIC);

	gtk_box_pack_start ((GtkBox *)shell, viewbox, TRUE, TRUE, 0);
	gtk_widget_show ((GtkWidget *)shell);
	
	shell->tree = (GtkTreeView *)gtk_tree_view_new ();
	g_signal_connect (shell->tree, "motion-notify-event", G_CALLBACK(mfv_motion_tree), shell);
	//g_signal_connect (shell->tree, "enter-notify-event", G_CALLBACK(mfv_motion_tree), shell);
	//g_signal_connect (shell->tree, "leave-notify-event", G_CALLBACK(mfv_motion_tree), shell);

	sel  = gtk_tree_view_get_selection (shell->tree);
	gtk_tree_selection_set_mode (sel, GTK_SELECTION_BROWSE);
	gtk_tree_view_set_enable_search (shell->tree, FALSE);
	gtk_container_add ((GtkContainer *)priv->view_scroller, (GtkWidget *)shell->tree);
	gtk_tree_view_set_fixed_height_mode (shell->tree, TRUE);
	gtk_tree_view_set_rules_hint (shell->tree, TRUE);
	gtk_box_pack_start ((GtkBox *)viewbox, priv->view_scroller, TRUE, TRUE, 0);
	gtk_widget_show ((GtkWidget *)shell->tree);
	gtk_tree_view_set_headers_visible (shell->tree, FALSE);
	gtk_tree_view_set_show_expanders (shell->tree, shell->priv->show_thread);

	g_signal_connect (shell->tree,  "row-activated", G_CALLBACK (mfv_message_activated), shell);
	g_signal_connect (shell->tree, "button-press-event", G_CALLBACK(mfv_button_clicked), shell);
	g_signal_connect (shell->tree, "key-press-event", G_CALLBACK(mfv_key_pressed), shell);

	/* Setup DND */
	gtk_drag_source_set((GtkWidget *)shell->tree, GDK_BUTTON1_MASK,
			       ml_drag_types, sizeof(ml_drag_types)/sizeof(ml_drag_types[0]),
			       GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);

	g_signal_connect(shell->tree, "drag-data-get",
			 G_CALLBACK(mfv_drag_data_get), shell);
	g_signal_connect(shell->tree, "drag-data-delete",
			 G_CALLBACK(mfv_drag_data_delete), shell);

	/* Create the single column for flags  */
	column = gtk_tree_view_column_new ();
	column->editable_widget = (gpointer)0xdeadbeef;

	gtk_tree_view_column_set_fixed_width (column, 24);
	gtk_tree_view_column_set_sizing  (column, GTK_TREE_VIEW_COLUMN_FIXED);	
	gtk_tree_view_column_set_title (column, _("Flags"));
	gtk_tree_view_append_column (GTK_TREE_VIEW (shell->tree), column);
	gtk_tree_view_column_set_resizable (column, TRUE);
	shell->priv->cols[0] = column;

	vbox = custom_cell_renderer_vbox_new ();
	g_object_set_data ((GObject *)vbox, "mfv", shell);
	g_object_set ((GObject *)vbox, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
	gtk_tree_view_column_pack_start (column, vbox, TRUE);
	gtk_tree_view_column_set_cell_data_func (column, vbox, (GtkTreeCellDataFunc)draw_flags, shell, NULL);

	/* dummy renderers for nice packing */
	if (!shell->priv->light && shell->priv->show_preview) {
		cell = custom_cell_renderer_toggle_pixbuf_new (gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm), gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm));	
		custom_cell_renderer_vbox_append (vbox, cell);
	}

	/* Pack a renderer for unread indication */
	cell = custom_cell_renderer_toggle_pixbuf_new (mail_utils_get_icon("anjal-mail-new",GTK_ICON_SIZE_MENU), mail_utils_get_icon("anjal-mail-new",GTK_ICON_SIZE_MENU));
	g_object_set_data ((GObject *)cell, "mfv", shell);
	g_object_set_data ((GObject *)cell, "activate_func", mfv_msg_unread);
	if (shell->priv->light)
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (COL_FLAGS));
	else 
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_UNREAD));
	custom_cell_renderer_vbox_append (vbox, cell);
	shell->priv->unread_toggle = cell; /* Store the cell_render */
	g_object_set_data ((GObject *)cell, "mfv", shell);

	/* dummy renderers for nice packing */
	if (!shell->priv->light && shell->priv->show_preview) {
		cell = custom_cell_renderer_toggle_pixbuf_new (gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm), gdk_pixbuf_new_from_xpm_data ((const char **) empty_xpm));	
		custom_cell_renderer_vbox_append (vbox, cell);
	}
	
	/* Create the single column */
	column = gtk_tree_view_column_new ();
	shell->priv->cols[1] = column;
	/* FIXME: A Horrible Gtk+ hack I do. If the cell is activatable, keyboard scroll is *very* slow.
	   Drawing the focus seems bad takes CPU there. Avoiding it. Specially when you do 5 down arrow and do
	   the first up-arrow. I takes ~2 secs to respond. I bypass it by this.*/
	column->editable_widget = (gpointer)0xdeadbeef;
	
	gtk_tree_view_column_set_sizing  (column, GTK_TREE_VIEW_COLUMN_FIXED);	
	/*gtk_tree_view_column_set_fixed_width (column, 720);*/

	gtk_tree_view_column_set_title (column, _("Messages"));
	gtk_tree_view_append_column (GTK_TREE_VIEW (shell->tree), column);
	gtk_tree_view_column_set_resizable (column, TRUE);

	g_object_set_data((GObject *)shell->tree, "shell", shell);
	g_signal_connect (shell->tree,  "size-allocate", G_CALLBACK(mfv_tree_resize), column);
	/* Main VBOX renderer, that shows multi line. */
	vbox = custom_cell_renderer_vbox_new ();

	gtk_tree_view_column_pack_start (column, vbox, TRUE);
	gtk_tree_view_column_set_cell_data_func (column, vbox, (GtkTreeCellDataFunc)draw_text, shell, NULL);

	/* Create the hbox renderer for the first line to be shown.*/
	hbox = custom_cell_renderer_hbox_new ();
	g_object_set_data ((GObject *)hbox, "data", GINT_TO_POINTER (-1));	
	custom_cell_renderer_vbox_append (vbox, hbox);
	
	/* Create a renderer for FROM to be shown, */
	cell = gtk_cell_renderer_text_new ();
	if (shell->priv->light)
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (COL_FROM));
	else 
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_FROM));
	shell->priv->from_to = cell;
	g_object_set_data ((GObject *)cell, "p-ellipsize", GINT_TO_POINTER (1));
	g_object_set_data ((GObject *)cell, "p-markup", GINT_TO_POINTER (1));
	g_object_set_data ((GObject *)cell, "p-bold", GINT_TO_POINTER (0));
	g_object_set_data ((GObject *)cell, "p-strike", GINT_TO_POINTER (1));
	/* Pack From at the start  of the cell */
	custom_cell_renderer_hbox_pack_start (hbox, cell, FALSE);

#if 0
	/* Not required, since we pack a separate column for this. */
	/* Pack a renderer for unread indication */
	cell = gtk_cell_renderer_toggle_new ();
	if (shell->priv->light)
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (COL_FLAGS));
	else 
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_UNREAD));
	/* Pack toggle  at the start  of the cell */
	custom_cell_renderer_hbox_pack_start (hbox, cell, FALSE);
#endif

	/* Show a box for number of mails */
	if (!shell->priv->light) {
		 cell = gtk_cell_renderer_text_new ();
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_THREADCOUNT));
		g_object_set_data ((GObject *)cell, "p-markup", GINT_TO_POINTER (1));
		g_object_set_data ((GObject *)cell, "p-ellipsize", GINT_TO_POINTER (0));
		g_object_set_data ((GObject *)cell, "p-bold", GINT_TO_POINTER (0));
		g_object_set_data ((GObject *)cell, "p-strike", GINT_TO_POINTER (0));
		g_object_set_data ((GObject *)cell, "p-custom", GINT_TO_POINTER (1));
		/* Pack Date at the end of the cell */
		custom_cell_renderer_hbox_pack_end (hbox, cell, FALSE);
	}
	
	/* Show the attachment icon */
	if (!shell->priv->light) {
		cell = gtk_cell_renderer_pixbuf_new ();
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_ATTACHMENT));

		/* Pack Date at the end of the cell */
		custom_cell_renderer_hbox_pack_end (hbox, cell, FALSE);
	}

	/* Create a renderer for Date to be shown */
	cell = gtk_cell_renderer_text_new ();
	if (shell->priv->light)
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (COL_DATE));
	else {
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_DATE));
		g_object_set_data ((GObject *)cell, "conv-func", filter_date);
	}
	g_object_set_data ((GObject *)cell, "p-ellipsize", GINT_TO_POINTER (0));
	g_object_set_data ((GObject *)cell, "p-bold", GINT_TO_POINTER (1));
	g_object_set_data ((GObject *)cell, "p-strike", GINT_TO_POINTER (1));
	/* Pack Date at the end of the cell */
	custom_cell_renderer_hbox_pack_end (hbox, cell, FALSE);



	/* Create a cell renderer for Subject */
	cell = gtk_cell_renderer_text_new ();
	if (shell->priv->light)
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (COL_SUBJECT));
	else
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_SUBJECT));
	g_object_set_data ((GObject *)cell, "p-ellipsize", GINT_TO_POINTER (1));
	g_object_set_data ((GObject *)cell, "p-bold", GINT_TO_POINTER (1));
	g_object_set_data ((GObject *)cell, "p-strike", GINT_TO_POINTER (1));				

	/* Append, subject to second row. */
	custom_cell_renderer_vbox_append (vbox, cell);
	
	if (!shell->priv->light && shell->priv->show_preview) {
		/* Incase of non-light or non mobile mode,  */
	//	hbox  = custom_cell_renderer_hbox_new ();
	//	g_object_set_data (hbox, "data", GINT_TO_POINTER (-1));	
	//	custom_cell_renderer_vbox_append (vbox, hbox);
		
		cell = gtk_cell_renderer_text_new ();
		g_object_set_data ((GObject *)cell, "data", GINT_TO_POINTER (EMTS_COL_THREADPREVIEW));
		g_object_set_data ((GObject *)cell, "p-ellipsize", GINT_TO_POINTER (1));
		g_object_set_data ((GObject *)cell, "p-bold", GINT_TO_POINTER (0));
		g_object_set_data ((GObject *)cell, "p-strike", GINT_TO_POINTER (1));
		g_object_set_data ((GObject *)cell, "p-markup", GINT_TO_POINTER (1));
	//	custom_cell_renderer_hbox_pack_start (hbox, cell, FALSE);
		custom_cell_renderer_vbox_append (vbox, cell);
	}

	/* Add another column for the flags. */
	column = gtk_tree_view_column_new ();
	column->editable_widget = (gpointer)0xdeadbeef;

	gtk_tree_view_column_set_fixed_width (column, 24);
	gtk_tree_view_column_set_sizing  (column, GTK_TREE_VIEW_COLUMN_FIXED);	
	gtk_tree_view_append_column (GTK_TREE_VIEW (shell->tree), column);
	gtk_tree_view_column_set_resizable (column, TRUE);
	shell->priv->cols[2] = column;

	/* Another VBox for Delete/Junk */
	vbox = custom_cell_renderer_vbox_new ();
	g_object_set_data ((GObject *)vbox, "mfv", shell);
	g_object_set ((GObject *)vbox, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
	if (shell->priv->show_preview)
		gtk_tree_view_column_pack_end (column, vbox, FALSE);
	g_object_set_data ((GObject * )column, "widget", shell);
	if (shell->priv->show_preview)
		gtk_tree_view_column_set_cell_data_func (column, vbox, (GtkTreeCellDataFunc)draw_img, NULL, NULL);

	
	/* Cell rendere for Delete */
	cell = custom_cell_renderer_toggle_pixbuf_new (mail_utils_get_icon ("edit-delete", GTK_ICON_SIZE_MENU), mail_utils_get_icon ("edit-delete", GTK_ICON_SIZE_MENU));
	g_object_set_data ((GObject *)cell, "mfv", shell);
	custom_cell_renderer_vbox_append (vbox, cell);
	g_object_set_data ((GObject *)cell, "data", "edit-delete");

	g_object_set_data ((GObject *)cell, "sel-highlight", GINT_TO_POINTER(1));
	g_object_set_data ((GObject *)cell, "activate_func", mfv_msg_delete);
	

	/* Empty image */
	if (!shell->priv->light && shell->priv->show_preview) {
		cell =   gtk_cell_renderer_pixbuf_new ();
		custom_cell_renderer_vbox_append (vbox, cell);
		g_object_set_data ((GObject *)cell, "data", NULL);
		g_object_set_data ((GObject *)cell, "activate_func", NULL);		
	}	
	
	/* Cell rendere for Junk */
	cell = custom_cell_renderer_toggle_pixbuf_new (mail_utils_get_icon ("mail-mark-junk", GTK_ICON_SIZE_MENU), mail_utils_get_icon ("mail-mark-junk", GTK_ICON_SIZE_MENU));
	g_object_set_data ((GObject *)cell, "mfv", shell);
	custom_cell_renderer_vbox_append (vbox, cell);
	g_object_set_data ((GObject *)cell, "sel-highlight", GINT_TO_POINTER(1));
	g_object_set_data ((GObject *)cell, "data", "mail-mark-junk");
	g_object_set_data ((GObject *)cell, "activate_func", mfv_msg_junk);	

	gtk_tree_view_columns_autosize (shell->tree);

	shell->mail = mail_conv_view_new ();
	gtk_box_pack_start ((GtkBox *)viewbox, (GtkWidget *)shell->mail, TRUE, TRUE, 0);
	gtk_widget_hide ((GtkWidget *)shell->mail);
}

MailFolderView *
mail_folder_view_new ()
{
	MailFolderView *shell = g_object_new (MAIL_FOLDER_VIEW_TYPE, NULL);
	mail_folder_view_construct (shell);

	return shell;
}



static void
popup_place_widget(GtkMenu *menu, int *x, int *y, gboolean *push_in, gpointer user_data)
{
	GtkWidget *w = user_data;

	gdk_window_get_origin(gtk_widget_get_parent_window(w), x, y);
	*x += w->allocation.x;
	*y += w->allocation.y  + w->allocation.height - 1;
}

static void
mfv_set_sort (GtkCheckMenuItem *item, MailFolderView *view)
{
	if (gtk_check_menu_item_get_active (item)) {
		if (GPOINTER_TO_INT(g_object_get_data((GObject *)item, "data")) != view->priv->sort_selected) {
			view->priv->sort_selected = GPOINTER_TO_INT(g_object_get_data((GObject *)item, "data"));
			((EMTreeStore *)view->model)->func = sorting[view->priv->sort_selected-1].func;
			em_tree_store_resort ((EMTreeStore *)view->model);
			gtk_widget_queue_draw ((GtkWidget *)view->tree);
		}
			
	}
}

static void
mfv_set_sort_state (GtkCheckMenuItem *item, MailFolderView *view)
{
	if (gtk_check_menu_item_get_active (item)) {
		if ((GPOINTER_TO_INT(g_object_get_data((GObject *)item, "data")) != 0) != view->priv->sort_ascending) {
			view->priv->sort_ascending= GPOINTER_TO_INT(g_object_get_data((GObject *)item, "data")) != 0;
			((EMTreeStore *)view->model)->sort_ascending = view->priv->sort_ascending;
			em_tree_store_resort ((EMTreeStore *)view->model);
			gtk_widget_queue_draw ((GtkWidget *)view->tree);
		}
	}
}


void
mail_folder_view_show_sort_popup  (MailFolderView *mfv, GtkWidget *button)
{
	GtkWidget *menu = gtk_menu_new ();
	GtkWidget *titem=NULL, *item;
	int cnt =G_N_ELEMENTS(sorting), i;

	item =gtk_radio_menu_item_new_with_mnemonic (NULL, _("_Ascending"));
	g_object_set_data ((GObject *)item, "data", GINT_TO_POINTER(1));
	g_signal_connect (item, "toggled", G_CALLBACK (mfv_set_sort_state), mfv);
	gtk_menu_shell_append ((GtkMenuShell *)menu, item);
	if (mfv->priv->sort_ascending)
		gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE);
	gtk_widget_show (item);
	
	item =gtk_radio_menu_item_new_with_mnemonic_from_widget ((GtkRadioMenuItem *)item, _("D_escending"));
	g_object_set_data ((GObject *)item, "data", GINT_TO_POINTER(0));
	g_signal_connect (item, "toggled", G_CALLBACK (mfv_set_sort_state), mfv);
	gtk_menu_shell_append ((GtkMenuShell *)menu, item);
	if (!mfv->priv->sort_ascending)
		gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE);
	gtk_widget_show (item);

	item = gtk_separator_menu_item_new ();
	gtk_menu_shell_append ((GtkMenuShell *)menu, item);
	gtk_widget_show (item);
	
	for (i=0; i<cnt;  i++) {
		if (titem)
			item = gtk_radio_menu_item_new_with_mnemonic_from_widget ((GtkRadioMenuItem *)titem, _(sorting[i].label));
		else
			item = gtk_radio_menu_item_new_with_mnemonic (NULL, _(sorting[i].label));
		g_object_set_data ((GObject *)item, "data", GINT_TO_POINTER(sorting[i].value));
		g_signal_connect (item, "toggled", G_CALLBACK (mfv_set_sort), mfv);
		gtk_menu_shell_append ((GtkMenuShell *)menu, item);
		gtk_widget_show (item);
		if (!titem)
			titem = item;
		if (mfv->priv->sort_selected == sorting[i].value)
			gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE);
	}

	gtk_menu_popup((GtkMenu *)menu, NULL, NULL, (GtkMenuPositionFunc)popup_place_widget, button, 0, gtk_get_current_event_time());
}

void
mail_folder_view_activate (MailFolderView *mfv, GtkWidget *tree, GtkWidget *folder_tree, GtkWidget *check_mail, GtkWidget *sort_by, GtkWidget *slider, gboolean act)
{
	 if (!folder_tree || !check_mail || !sort_by)
		  return;
	 if (mfv->priv->message_shown) {
		  gtk_widget_show (folder_tree);
		  g_signal_emit (mfv, signals[MESSAGE_SHOWN], 0);
	 } else {
		  gtk_widget_show(folder_tree);
		  gtk_widget_hide (slider);
	 }
	 gtk_widget_set_sensitive (folder_tree, act);
	 gtk_widget_set_sensitive (check_mail, act);
	 gtk_widget_set_sensitive (sort_by, act);
	 if (mfv->priv->folder) {
		  em_folder_tree_set_selected ((EMFolderTree *)tree, mfv->uri, FALSE);
	 }
}

void
mail_folder_view_check_mail (MailFolderView *mfv)
{
	 
}


void
mail_folder_view_save (MailFolderView *mfv)
{
	 mfv_save(mfv);
}

static void
mail_folder_view_search_done (MailFolderView *mfv, CamelFolder *folder, const char *uri)
{
		gtk_tree_view_set_model (GTK_TREE_VIEW (mfv->tree), mfv->model);	
}

void
mail_folder_view_set_search (MailFolderView *mfv, const char *search)
{
	if (mfv->search) {
		g_free (mfv->search);
		mfv->search = NULL;
	}

	if (search|| 1) {
		struct _db_read_msg *m;

		mfv->search = search ? g_strdup(search) : NULL;

		gtk_tree_view_set_model (GTK_TREE_VIEW (mfv->tree), NULL);
		m = mail_msg_new (&db_read_info);
		m->mfv = mfv;
		m->load = FALSE;
		m->uri = g_strdup(mfv->uri);
		m->folder = mfv->priv->folder;
		m->done = mail_folder_view_search_done;
		mail_msg_unordered_push (m);		
	}

}

void
mail_folder_view_set_folder_pane (MailFolderView *mfv, GtkWidget *pane)
{
	mfv->priv->folder_pane = pane;
}

