/* $Cambridge: hermes/src/prayer/session/abook.h,v 1.3 2008/09/16 09:59:58 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */

/* Various data structures for address books */

/* Allocate address book in reasonably small chunks */
#define ABOOK_POOL_SIZE       (1024)

struct abook_entry {            /* Warning: first two entries must be list hdr */
    struct abook_entry *next;   /* Linked list */
    char *alias;                /* Alias name */
    /* Okay to change from here */
    BOOL used;                  /* Reference flag to spot abook loops */
    char *name;                 /* Personal name */
    char *fcc;                  /* Fcc field from Pine abook. Not yet used */
    char *comment;              /* Comment field */
    char *email;                /* Email address or lists of addresses */
    unsigned long position;     /* For sorted addressbooks */
};

typedef enum {
    ABOOK_SORT_ORDER,
    ABOOK_SORT_ALIAS,
    ABOOK_SORT_NAME,
    ABOOK_SORT_COMMENT,
    ABOOK_SORT_EMAIL
} abook_sort_mode;

struct abook {
    struct pool *pool;          /* abook entries assigned against this pool */
    struct list *list;          /* Addressbook as simple list */
    struct assoc *hash;         /* Fast lookups mechanism into above list */
    struct abook_entry *search; /* Last entry to match abook search operation */
    abook_sort_mode sort_mode;  /* Field that we are sorting on, if any */
    BOOL          sort_reverse; /* Reverse sort? */
    struct abook_entry **sort;  /* Sorted list of addressbook entries */
    unsigned long unnamed;      /* Unique count for unnamed names */
    unsigned long current;      /* For addressbook listing */
};

/* ====================================================================== */

/* Addressbook search list typically small */
#define PREFERRED_ASL_POOL_SIZE (2048)

/* Search properties for addressbook search */
typedef enum {
    ABOOK_SEARCH_FIELD_NONE,
    ABOOK_SEARCH_FIELD_ALIAS,
    ABOOK_SEARCH_FIELD_NAME,
    ABOOK_SEARCH_FIELD_COMMENT,
    ABOOK_SEARCH_FIELD_EMAIL
} abook_search_field_type;

typedef enum {
    ABOOK_SEARCH_TYPE_NONE,
    ABOOK_SEARCH_TYPE_IS,
    ABOOK_SEARCH_TYPE_BEGINS,
    ABOOK_SEARCH_TYPE_ENDS,
    ABOOK_SEARCH_TYPE_CONTAINS
} abook_search_type_type;

struct abook_search_elt {       /* Single search criteria */
    struct abook_search_elt *next;      /* Linked list */
    abook_search_field_type field;      /* Field to match */
    abook_search_type_type type;        /* Type of match */
    char *value;                /* Value to match */
};

struct abook_search_list {      /* List of search criteria  */
    struct pool *pool;          /* Pool to allocate against */
    BOOL match_all;             /* T: all criteria must match. NIL: any */
    struct abook_search_elt *first;     /* Start of search_elt list */
    struct abook_search_elt *last;      /* End of search_elt list */
};

struct abook *abook_create(void);

void abook_free(struct abook *abook);

void
abook_parse_line(struct abook *abook, char *line, struct session *session);

void abook_print_options(struct abook *abook, struct buffer *b);


void
abook_add(struct abook *abook, char *alias, char *name,
          char *fcc, char *comment, char *address);

void
abook_replace(struct abook *abook, char *alias, char *name,
              char *fcc, char *comment, char *address);

void abook_remove(struct abook *abook, char *alias);

struct abook_entry *abook_lookup(struct abook *abook, char *alias);

struct abook_entry *abook_lookup_byoffset(struct abook *abook,
                                          unsigned long offset);

struct abook_entry *abook_lookup_sorted_byoffset(struct abook *abook,
                                                 unsigned long offset);

struct abook_entry *abook_find_email(struct abook *abook, char *email);

struct abook_search_list *abook_search_list_create(BOOL match_all);

void abook_search_list_free(struct abook_search_list *asl);

void
abook_search_list_add(struct abook_search_list *asl,
                      abook_search_field_type field,
                      abook_search_type_type type, char *value);

void abook_search_init(struct abook *abook);

struct abook_entry *abook_search_find_next(struct abook *abook, struct abook_search_list
                                           *search_list);

/* Various conversion functions */
char *abook_entry_to_string(struct pool *pool, struct abook_entry *abe);

char *abook_text_to_string(struct pool *pool, char *name, char *email);


char *abook_substitute(struct session *session,
                       struct pool *pool, struct abook *abook,
                       char *string);

BOOL
abook_substitute_buffer(struct session *session,
                        struct buffer *b, struct abook *abook,
                        char *string);

BOOL
abook_check_loop(struct pool *pool,
                 struct abook *abook, char *current, BOOL toplevel);

BOOL abook_import_pine_valid(char *s);

unsigned long abook_import_pine(struct abook *abook, char *text);

BOOL abook_import_csv_valid(char *s);

unsigned long abook_import_csv(struct abook *abook, char *text);

void abook_export_pine(struct abook *abook, struct buffer *b);

void abook_export_csv(struct abook *abook, struct buffer *b);

char *abook_export_text(struct abook *abook, struct pool *pool);

void abook_clear_sort(struct abook *abook);

void
abook_set_sort(struct abook *abook, abook_sort_mode sort_mode, BOOL reverse);

void abook_sort(struct abook *abook);
