/*
 *  Copyright (C) 2000 Helix Code Inc.
 *
 *  Authors: Michael Zucchi <notzed@helixcode.com>
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 *  USA
 */

#ifndef _CAMEL_FOLDER_SUMMARY_H
#define _CAMEL_FOLDER_SUMMARY_H

#include <camel/camel-object.h>
#include <stdio.h>
#include <time.h>
#include <camel/camel-mime-parser.h>
#include <libibex/ibex.h>

#define CAMEL_FOLDER_SUMMARY(obj)         GTK_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary)
#define CAMEL_FOLDER_SUMMARY_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass)
#define IS_CAMEL_FOLDER_SUMMARY(obj)      GTK_CHECK_TYPE (obj, camel_folder_summary_get_type ())

/*typedef struct _CamelFolderSummary      CamelFolderSummary;*/
typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;

/* these structs from camel-folder-summary.h ... (remove comment after cleanup soon) */
/* TODO: perhaps they should be full-block objects? */
/* FIXME: rename this to something more suitable */
typedef struct {
	gchar *name;
	gint nb_message;	/* ick, these should be renamed to something better */
	gint nb_unread_message;
	gint nb_deleted_message;
} CamelFolderInfo;

/* A tree of message content info structures
   describe the content structure of the message (if it has any) */
typedef struct _CamelMessageContentInfo {
	struct _CamelMessageContentInfo *next;

	struct _CamelMessageContentInfo *childs;
	struct _CamelMessageContentInfo *parent;

	struct _header_content_type *type;
	char *id;
	char *description;
	char *encoding;

	/* information about where this object lives in the stream.
	   if pos is -1 these are all invalid */
	off_t pos;
	off_t bodypos;
	off_t endpos;
} CamelMessageContentInfo;

/* system flag bits */
enum _CamelMessageFlags {
	CAMEL_MESSAGE_ANSWERED = 1<<0,
	CAMEL_MESSAGE_DELETED = 1<<1,
	CAMEL_MESSAGE_DRAFT = 1<<2,
	CAMEL_MESSAGE_FLAGGED = 1<<3,
	CAMEL_MESSAGE_SEEN = 1<<4,
	/* following flags are for the folder, and are not really permanent flags */
	CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */
	CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */
};

typedef struct _CamelFlag {
	struct _CamelFlag *next;
	char name[1];
} CamelFlag;

/* information about a given object */
typedef struct {
	/* public fields */
	gchar *subject;
	gchar *from;
	gchar *to;
	gchar *cc;

	gchar *uid;
	guint32 flags;
	guint32 size;

	time_t date_sent;
	time_t date_received;

	/* Message-ID / References structures */
	char *message_id;	/* for this message */
	struct _header_references *references; /* from parent to root */

	struct _CamelFlag *user_flags;

	/* tree of content description - NULL if it is not available */
	CamelMessageContentInfo *content;
} CamelMessageInfo;

enum _CamelFolderSummaryFlags {
	CAMEL_SUMMARY_DIRTY = 1<<0,
};

struct _CamelFolderSummary {
	CamelObject parent;

	struct _CamelFolderSummaryPrivate *priv;

	/* header info */
	guint32 version;	/* version of file required, should be set by implementors */
	guint32 flags;		/* flags */
	guint32 nextuid;	/* next uid? */
	guint32 saved_count;	/* how many were saved/loaded */
	time_t time;		/* timestamp for this summary (for implementors to use) */

	/* sizes of memory objects */
	guint32 message_info_size;
	guint32 content_info_size;

	char *summary_path;
	gboolean build_content;	/* do we try and parse/index the content, or not? */

	GPtrArray *messages;	/* CamelMessageInfo's */
	GHashTable *messages_uid; /* CamelMessageInfo's by uid */
};

struct _CamelFolderSummaryClass {
	CamelObjectClass parent_class;

	/* load/save the global info */
	int (*summary_header_load)(CamelFolderSummary *, FILE *);
	int (*summary_header_save)(CamelFolderSummary *, FILE *);

	/* create/save/load an individual message info */
	CamelMessageInfo * (*message_info_new)(CamelFolderSummary *, struct _header_raw *);
	CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
	CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
	int		   (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
	void		   (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *);

	/* save/load individual content info's */
	CamelMessageContentInfo * (*content_info_new)(CamelFolderSummary *, struct _header_raw *);
	CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
	CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
	int		          (*content_info_save)(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
	void		          (*content_info_free)(CamelFolderSummary *, CamelMessageContentInfo *);
};

guint			 camel_folder_summary_get_type	(void);
CamelFolderSummary      *camel_folder_summary_new	(void);

void camel_folder_summary_set_filename(CamelFolderSummary *, const char *);
void camel_folder_summary_set_index(CamelFolderSummary *, ibex *);
void camel_folder_summary_set_build_content(CamelFolderSummary *, gboolean state);

guint32  camel_folder_summary_next_uid        (CamelFolderSummary *s);
char    *camel_folder_summary_next_uid_string (CamelFolderSummary *s);

/* load/save the summary in its entirety */
int camel_folder_summary_load(CamelFolderSummary *);
int camel_folder_summary_save(CamelFolderSummary *);

/* set the dirty bit on the summary */
void camel_folder_summary_touch(CamelFolderSummary *s);

/* add a new raw summary item */
void camel_folder_summary_add(CamelFolderSummary *, CamelMessageInfo *info);

/* build/add raw summary items */
CamelMessageInfo *camel_folder_summary_add_from_header(CamelFolderSummary *, struct _header_raw *);
CamelMessageInfo *camel_folder_summary_add_from_parser(CamelFolderSummary *, CamelMimeParser *);

/* removes a summary item, doesn't fix content offsets */
void camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info);
void camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid);
/* remove all items */
void camel_folder_summary_clear(CamelFolderSummary *s);

/* lookup functions */
int camel_folder_summary_count(CamelFolderSummary *);
CamelMessageInfo *camel_folder_summary_index(CamelFolderSummary *, int);
CamelMessageInfo *camel_folder_summary_uid(CamelFolderSummary *, const char *uid);

/* shift content ... */
void camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset);

/* summary file loading/saving helper functions */
int camel_folder_summary_encode_fixed_int32(FILE *, gint32);
int camel_folder_summary_decode_fixed_int32(FILE *, gint32 *);

int camel_folder_summary_encode_uint32(FILE *, guint32);
int camel_folder_summary_decode_uint32(FILE *, guint32 *);

int camel_folder_summary_encode_string(FILE *, char *);
int camel_folder_summary_decode_string(FILE *, char **);

/* basically like strings, but certain keywords can be compressed and de-cased */
int camel_folder_summary_encode_token(FILE *, char *);
int camel_folder_summary_decode_token(FILE *, char **);

/* message flag operations */
gboolean	camel_flag_get(CamelFlag **list, const char *name);
void		camel_flag_set(CamelFlag **list, const char *name, gboolean state);
int		camel_flag_list_size(CamelFlag **list);
void		camel_flag_list_free(CamelFlag **list);

#endif /* ! _CAMEL_FOLDER_SUMMARY_H */
621dde4ca9'>Add NO_STAGE all over the place in preparation for the staging support (cat: ...</a></td><td>Baptiste Daroussin</td><td><span title='2013-09-21 00:03:29 +0800'>2013-09-21</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=9c7a77ab1e2aff61f3f6d7e6f08fdf7089ef125a'>For all my ports</a></td><td>Christian Weisgerber</td><td><span title='2013-08-02 04:22:27 +0800'>2013-08-02</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+0</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=0062a3fa62e39adf1e45243972dbf2171597d057'>Remove pointless header lines from ports I created once upon a time.</a></td><td>Christian Weisgerber</td><td><span title='2012-09-16 04:00:32 +0800'>2012-09-16</span></td><td>1</td><td><span class='deletions'>-4</span>/<span class='insertions'>+0</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=61932104bcf10486fa81b56366409492cae8b240'>* Minor update to 2.0.9.</a></td><td>Christian Weisgerber</td><td><span title='2011-11-20 00:57:09 +0800'>2011-11-20</span></td><td>5</td><td><span class='deletions'>-120</span>/<span class='insertions'>+12</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=bb86cbe5d232690f52a27fe9a2d7246e03eef9c4'>- Get Rid MD5 support</a></td><td>Martin Wilke</td><td><span title='2011-03-20 20:54:45 +0800'>2011-03-20</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+0</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=75a6657bad3c6aa6be08ef92e9486ba9500b4c23'>Mark MAKE_JOBS_SAFE for parallel building.</a></td><td>Christian Weisgerber</td><td><span title='2009-03-28 02:03:20 +0800'>2009-03-28</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=3a22d6f92c0e4d219f7a2d7d3fa9d50d3bf0c96e'>Fix building with gcc4.</a></td><td>Christian Weisgerber</td><td><span title='2006-12-15 05:06:37 +0800'>2006-12-15</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+98</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=acd87b4ad806ea86233e2a9bdf896c6028bb5222'>SHA256ify</a></td><td>Edwin Groothuis</td><td><span title='2006-01-22 16:34:46 +0800'>2006-01-22</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=8905042799632bd2a106c9b88c375c63fb417f43'>Use MASTER_SITE_LOCAL.  The real master site uses a temporary redirect to</a></td><td>Christian Weisgerber</td><td><span title='2005-10-28 03:43:37 +0800'>2005-10-28</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+4</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=38069212cc107506da433f5e12b060c30b22023f'>Add size data, approved by maintainers.</a></td><td>Trevor Johnson</td><td><span title='2004-03-19 04:59:15 +0800'>2004-03-19</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=7fdd98bd024ad2982db3d6ba370cc50c40e571ce'>maintenance update to 2.0.8</a></td><td>Christian Weisgerber</td><td><span title='2003-08-23 02:36:32 +0800'>2003-08-23</span></td><td>2</td><td><span class='deletions'>-2</span>/<span class='insertions'>+2</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=b07036274f8c89151745721df2ad91b5c5da8e2c'>Update to 2.0.6.</a></td><td>Christian Weisgerber</td><td><span title='2003-02-21 23:27:08 +0800'>2003-02-21</span></td><td>2</td><td><span class='deletions'>-2</span>/<span class='insertions'>+2</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=32b8021ea597dce557c90853579b05ce303dea33'>pkg-comment -&gt; COMMENT</a></td><td>Christian Weisgerber</td><td><span title='2003-02-21 20:52:52 +0800'>2003-02-21</span></td><td>2</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr>
<tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/comms/wy60?id=63c8d22076e560d1bc23ae667b909f576c9a26fc'>Update to 2.0.4: emulation improvements.</a></td><td>Christian Weisgerber</td><td><span title='2002-09-08 08:36:47 +0800'>2002-09-08</span></td><td>4</td><td><span class='deletions'>-6</span>/<span class='insertions'>+21</span></td></tr>