/*
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
 * Copyright (C) 2002-2014 by the Claws Mail Team and Hiroyuki Yamamoto
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */

#ifndef MATCHER_H
#define MATCHER_H

#include <sys/types.h>
#include <regex.h>
#include <glib.h>
#include "proctypes.h"
#include "matchertypes.h"

/* constants generated by yacc */
#include "matcher_parser_lex.h"
#include "matcher_parser_parse.h"

struct _MatcherProp {
	int matchtype;
	int criteria;
	gchar *header;
	gchar *expr;
	int value;
	regex_t *preg;
	int error;
	gboolean result;
	gboolean done;
};

struct _MatcherList {
	GSList *matchers;
	gboolean bool_and;
};


/* map MATCHCRITERIA_ to yacc's MATCHER_ */
#define MC_(name) \
	MATCHCRITERIA_ ## name = MATCHER_ ## name

/* map MATCHTYPE_ to yacc's MATCHER_ */
#define MT_(name) \
	MATCHTYPE_ ## name = MATCHER_ ## name

/* map MATCHACTION_ to yacc's MATCHER_ */
#define MA_(name) \
	MATCHACTION_ ## name = MATCHER_ ## name

/* map MATCHBOOL_ to yacc's MATCHER_ */
#define MB_(name) \
	MATCHERBOOL_ ## name = MATCHER_ ## name

enum {
	/* match */
	MC_(ALL),
	MC_(UNREAD), MC_(NOT_UNREAD),
	MC_(NEW), MC_(NOT_NEW),
	MC_(MARKED), MC_(NOT_MARKED),
	MC_(DELETED), MC_(NOT_DELETED),
	MC_(REPLIED), MC_(NOT_REPLIED),
	MC_(FORWARDED), MC_(NOT_FORWARDED),
	MC_(LOCKED), MC_(NOT_LOCKED),
	MC_(SPAM),MC_(NOT_SPAM),
	MC_(HAS_ATTACHMENT), MC_(HAS_NO_ATTACHMENT),
	MC_(SIGNED), MC_(NOT_SIGNED),
	MC_(PARTIAL), MC_(NOT_PARTIAL),
	MC_(COLORLABEL), MC_(NOT_COLORLABEL),
	MC_(IGNORE_THREAD), MC_(NOT_IGNORE_THREAD),
	MC_(WATCH_THREAD), MC_(NOT_WATCH_THREAD),
	MC_(SUBJECT), MC_(NOT_SUBJECT),
	MC_(FROM), MC_(NOT_FROM),
	MC_(TO), MC_(NOT_TO),
	MC_(CC), MC_(NOT_CC),
	MC_(TO_OR_CC), MC_(NOT_TO_AND_NOT_CC),
	MC_(AGE_GREATER), MC_(AGE_LOWER),
	MC_(AGE_GREATER_HOURS), MC_(AGE_LOWER_HOURS),
	MC_(NEWSGROUPS), MC_(NOT_NEWSGROUPS),
	MC_(MESSAGEID), MC_(NOT_MESSAGEID),
	MC_(INREPLYTO), MC_(NOT_INREPLYTO),
	MC_(REFERENCES), MC_(NOT_REFERENCES),
	MC_(SCORE_GREATER), MC_(SCORE_LOWER),
	MC_(HEADER), MC_(NOT_HEADER),
	MC_(HEADERS_PART), MC_(NOT_HEADERS_PART),
	MC_(HEADERS_CONT), MC_(NOT_HEADERS_CONT),
	MC_(MESSAGE), MC_(NOT_MESSAGE),
	MC_(BODY_PART), MC_(NOT_BODY_PART),
	MC_(TEST), MC_(NOT_TEST),
	MC_(SCORE_EQUAL),
	MC_(SIZE_GREATER), 
	MC_(SIZE_SMALLER),
	MC_(SIZE_EQUAL),
	MC_(FOUND_IN_ADDRESSBOOK),MC_(NOT_FOUND_IN_ADDRESSBOOK),
	MC_(TAG),MC_(NOT_TAG),
	MC_(TAGGED),MC_(NOT_TAGGED),

	/* match type */
	MT_(MATCHCASE),
	MT_(MATCH),
	MT_(REGEXPCASE),
	MT_(REGEXP),
	/* actions */
	MA_(SCORE),
	MA_(EXECUTE),
	MA_(MOVE),
	MA_(COPY),
	MA_(DELETE),
	MA_(MARK),
	MA_(UNMARK),
	MA_(LOCK),
	MA_(UNLOCK),
	MA_(MARK_AS_READ),
	MA_(MARK_AS_UNREAD),
	MA_(MARK_AS_SPAM),
	MA_(MARK_AS_HAM),
	MA_(FORWARD),
	MA_(FORWARD_AS_ATTACHMENT),
	MA_(COLOR),
	MA_(REDIRECT),
	MA_(CHANGE_SCORE),
	MA_(SET_SCORE),
	MA_(STOP),
	MA_(HIDE),
	MA_(IGNORE),
	MA_(WATCH),
	MA_(ADD_TO_ADDRESSBOOK),
	MA_(SET_TAG),
	MA_(UNSET_TAG),
	MA_(CLEAR_TAGS),
	/* boolean operations */
	MB_(OR),
	MB_(AND)
};

void matcher_init(void);
void matcher_done(void);

const gchar *get_matchparser_tab_str	(gint id);
gint get_matchparser_tab_id		(const gchar *str); 

MatcherProp *matcherprop_new		(gint		 criteria, 
					 const gchar	*header,
					 gint		 matchtype, 
					 const gchar	*expr,
					 int	         value);
void matcherprop_free			(MatcherProp *prop);

MatcherProp *matcherprop_parse		(gchar	**str);

MatcherProp *matcherprop_copy		(const MatcherProp *src);

MatcherList * matcherlist_new		(GSList		*matchers, 
					 gboolean	bool_and);
MatcherList * matcherlist_new_from_lines(gchar		*lines,
					 gboolean	bool_and,
					 gboolean	case_sensitive);
void matcherlist_free			(MatcherList	*cond);

MatcherList *matcherlist_parse		(gchar		**str);

gboolean matcherlist_match		(MatcherList	*cond, 
					 MsgInfo	*info);

gint matcher_parse_keyword		(gchar		**str);
gint matcher_parse_number		(gchar		**str);
gboolean matcher_parse_boolean_op	(gchar		**str);
gchar *matcher_parse_regexp		(gchar		**str);
gchar *matcher_parse_str		(gchar		**str);
gchar *matcherprop_to_string		(MatcherProp	*matcher);
gchar *matcherlist_to_string		(const MatcherList	*matchers);
gchar *matching_build_command		(const gchar	*cmd, 
					 MsgInfo	*info);

void prefs_matcher_read_config		(void);
void prefs_matcher_write_config		(void);

gchar * matcher_quote_str(const gchar * src);

#endif
