/*
 * 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 <gconf/gconf-client.h>
#include "mail-shell.h"
#include "mail-view.h"
#include "mail-component.h"
#include <gdk/gdkkeysyms.h>
#include "misc/e-filter-bar.h"
#include "mail-search.h"
#include <camel/camel-search-private.h>

enum {
	SEARCH_ACTIVATE,
	SEARCH_CLEAR,
	LAST_SIGNAL
};

static guint mail_search_signals[LAST_SIGNAL];

struct  _MailSearchPrivate {
	EFilterBar *bar;
};

G_DEFINE_TYPE (MailSearch, mail_search, GTK_TYPE_HBOX)

static void
mail_search_init (MailSearch  *shell)
{
	shell->priv = g_new0(MailSearchPrivate, 1);
}

static void
mail_search_finalize (GObject *object)
{
	G_OBJECT_CLASS (mail_search_parent_class)->finalize (object);
}

static void
mail_search_class_init (MailSearchClass *klass)
{
	GObjectClass * object_class = G_OBJECT_CLASS (klass);

	mail_search_parent_class = g_type_class_peek_parent (klass);
	object_class->finalize = mail_search_finalize;
	/*klass->backspace_pressed = ms_backspace_pressed;
	klass->slash_pressed = ms_slash_pressed;*/
	
	mail_search_signals [SEARCH_ACTIVATE] =
		g_signal_new ("search-activate",
				G_TYPE_FROM_CLASS (object_class),
				G_SIGNAL_RUN_FIRST,
				G_STRUCT_OFFSET (MailSearchClass, search_activate),
				NULL, NULL,
				g_cclosure_marshal_VOID__VOID,
				G_TYPE_NONE, 0);
	
	mail_search_signals [SEARCH_CLEAR] =
		g_signal_new ("slash_pressed",
				G_TYPE_FROM_CLASS (object_class),
				G_SIGNAL_RUN_FIRST,
				G_STRUCT_OFFSET (MailSearchClass, search_clear),
				NULL, NULL,
				g_cclosure_marshal_VOID__VOID,
				G_TYPE_NONE, 0);
	
};

static void
mail_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data)
{
	GList *partl;
	struct _camel_search_words *words;
	int i;
	GSList *strings = NULL;

	/* we scan the parts of a rule, and set all the types we know about to the query string */
	partl = rule->parts;
	while (partl) {
		FilterPart *part = partl->data;

		if (!strcmp(part->name, "subject")) {
			FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject");
			if (input)
				filter_input_set_value(input, query);
		} else if (!strcmp(part->name, "body")) {
			FilterInput *input = (FilterInput *)filter_part_find_element(part, "word");
			if (input)
				filter_input_set_value(input, query);

			words = camel_search_words_split((unsigned char *)query);
			for (i=0;i<words->len;i++)
				strings = g_slist_prepend(strings, g_strdup(words->words[i]->word));
			camel_search_words_free (words);
		} else if(!strcmp(part->name, "sender")) {
			FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender");
			if (input)
				filter_input_set_value(input, query);
		} else if(!strcmp(part->name, "to")) {
			FilterInput *input = (FilterInput *)filter_part_find_element(part, "recipient");
			if (input)
				filter_input_set_value(input, query);
		}

		partl = partl->next;
	}

	/*em_format_html_display_set_search(emfb->view.preview,
					  EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY|EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE,
					  strings);*/
	while (strings) {
		GSList *n = strings->next;
		g_free(strings->data);
		g_slist_free_1(strings);
		strings = n;
	}
}

static void
mail_search_activate (EFilterBar *bar, MailSearch *search)
{
	char *word, *state, *str;
	ESearchBar *esb = (ESearchBar *)bar;

	str = e_search_bar_get_text (esb);
	g_object_get (esb, "query", &word, NULL);
	g_object_get (esb, "state", &state, NULL);
	mail_view_set_search (search->view, word, state, str);
}


void
mail_search_construct (MailSearch *search_bar)
{
	MailSearchPrivate *priv = search_bar->priv;
	RuleContext *search_context = mail_component_peek_search_context (mail_component_peek ());
	const char *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
	const char *userrules = g_object_get_data (G_OBJECT (search_context), "user");

	priv->bar = e_filter_bar_lite_new (search_context, systemrules, userrules, mail_search_config_search, NULL);

	gtk_box_set_spacing (GTK_BOX (search_bar), 3);
	gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE);

	gtk_box_pack_start ((GtkBox *)search_bar, (GtkWidget *)priv->bar, TRUE, TRUE, 0);
	gtk_widget_show((GtkWidget *)priv->bar);
	gtk_widget_show ((GtkWidget *)search_bar);
	g_signal_connect (priv->bar, "search_activated", G_CALLBACK(mail_search_activate), search_bar);
}

MailSearch *
mail_search_new ()
{
	MailSearch *shell = g_object_new (MAIL_SEARCH_TYPE, NULL);
	mail_search_construct (shell);

	return shell;
}

void 
mail_search_set_state (MailSearch *search, const char *word, const char *state)
{
	if (!state || !*state)
		return;

	g_signal_handlers_block_by_func (search->priv->bar, mail_search_activate, search);
	e_search_bar_set_text ((ESearchBar *)search->priv->bar, (word && *word) ? word : "");
	g_object_set(search->priv->bar, "state", state, NULL);
	g_signal_handlers_unblock_by_func (search->priv->bar, mail_search_activate, search);
}

