// ------------------------------------------------------------------------------------------------
// DESCRIPTION  Message MIME strusture 
// ------------------------------------------------------------------------------------------------
// NOTES build up from local message (surgeweb) or imaplib use of IMAP BODYSTRUCTURE command
// ------------------------------------------------------------------------------------------------

#ifndef PARTS_HEADER
#define PARTS_HEADER

typedef struct SWPART {
	// Primary part information
	char *name;			// Text IMAP partname (eg. "1.2.2")
	Pair *hdrs;			// All part headers (ie all message headers or just MIME headers for sub part)
	char *filename;		// Filename if the headers supply one
	int size;			// Size of the part (for various attachment size serving)

	// Decoded headers for rapid use
	char *type;			// MIME type
	char *subtype;		// MIME subtype
	char *encoding;		// MIME encoding
	char *cid;			// Content-Id (for images etc in multipart/related)
	char *cloc;			// Content-Location (for images etc in multipart/related, aimilar to cid)

	// other
	struct PARTSLIST *images;			// Mime parts that are actually attached images (only ever set on 
	struct PARTSLIST *attachments;		// Mime parts that are actually attachments
	struct PARTSLIST *attachments_mpr;	// Mime parts that are actually attachments

	struct SWPART *linked_next;			// Link multiple parts for display purposes if required
    int is_attachment;

	// Part tree / list iterators
	struct SWPART *children;			// iterator for tree walk
	struct SWPART *siblings;			// iterator for tree walk
	struct SWPART *parent;              // iterator for tree walk

	struct SWPART *next;				// primary parts list iterator
} SwPart;

#define MAX_MIME_DEPTH 10
typedef struct PARTALLOCATOR{
	SwPart *ancestors[MAX_MIME_DEPTH];
	SwPart **last_siblings[MAX_MIME_DEPTH];
	SwPart **last_next, *lastp, *top;
	int last_depth;
}PartAllocator;


void parts_init(PartAllocator *pa, SwPart **parts);
void parts_free(SwPart **parts);
SwPart *parts_display_part_basic(SwPart *parts);
void parts_display_part_basichtml(SwPart *parts, SwPart **text_part, SwPart **html_part);

SwPart* parts_new_part_real(PartAllocator *pa, int depth, char* dbg_filename, char *file, int line);
int parts_decode_file_real( SwPart **prt, FILE *f, char* dbg_filename, char *file, int line);

#define parts_new_part(a,b,c) parts_new_part_real(a,b,c,__FILE__,__LINE__)
#define parts_decode_file(a,b,c) parts_decode_file_real(a,b,c,__FILE__,__LINE__)



typedef struct PARTSLIST {SwPart *ptr; struct PARTSLIST *next;} PartsList;

#define partslist_add(a,b) partslist_add_real(a,b,FALSE,__FILE__,__LINE__)
#define partslist_add_atend(a,b) partslist_add_real(a,b,TRUE,__FILE__,__LINE__)

int partslist_add_real(PartsList**list, SwPart *ptr, int atend, char *file, int line);
int partslist_free(PartsList**list);

SwPart *parts_findpart_bycid(SwPart *parts, char *cid);
SwPart *parts_findpart_bycloc(SwPart *parts, char *cid);
SwPart *parts_findpart_byname(SwPart *parts, char *name);

int parts_ancestor_mixed(SwPart *part);
void parts_process_for_attachments(SwPart *parts);

#endif

