/* ====================================================================
 * FTD4Linux Software License, Version 1.0
 *
 * Copyright (c) 2000-2004 The FTD4Linux Development Team.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        FTD4Linux Development Team (http://www.ftd4linux.2y.net/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "FTD" and "FTD4Linux" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact alguno@ftd4linux.2y.net.
 *
 * 5. Products derived from this software may not be called "FTD4Linux",
 *    nor may "FTD4Linux" appear in their name, without prior written
 *    permission of the FTD4Linux Development Team.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE FTD4LINUX DEVELOPMENT TEAM OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**
 * @file
 * FTD4linux core interface.
 *
 * Deze file beschrijft de volledige interface van de core van ftd.
 * Alle frontends dienen deze en alleen deze header te includen om de
 * volledige functionaliteit van ftd te kunnen gebruiken.
 */

#ifndef _FTD4LINUX_H_
#define _FTD4LINUX_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <time.h>
#include <glib.h>
#include <string.h>
#include <libxml/tree.h>

#include "ftd_define.h"

/* In deze header staan alle declaraties van de functies en
   structs die van buitenaf benadert mogen worden */

typedef struct FTDEventlist FTDEventlist;
typedef struct FTDEventObject FTDEventObject;
typedef struct FTDFilterlist FTDFilterlist;
typedef struct FTDFilterObject FTDFilterObject;

typedef GString                     FtdString;                      ///< Een string-type voor gebruik in FTD4linux.
typedef GSList                      FtdList;                        ///< Een lijst met pointers voor gebruik in FTD4linux.
//typedef GTree                       FtdTree;                        ///< Een boom met pointers voor gebruik in FTD4Linux
typedef GHashTable                  FtdTree;                        ///< Een boom met pointers voor gebruik in FTD4Linux
typedef struct _ftd_config          FtdConfig;                      ///< De configuratiegegevens van FTD.
typedef struct _ftd_event           FtdEvent;                       ///< De gegevens van een post (technische term: event) op FTD.
typedef struct _ftd_category        FtdCategory;                    ///< De gegevens van een categorie.
typedef FtdList                     FtdCategoryList;                ///< Een lijst met pointers naar ::FtdCategory structuren.
typedef struct _ftd_group           FtdGroup;                       ///< De gegevens van een nieuwsgroep.
typedef struct _ftd_mail_bericht    FtdMailBericht;                 ///< De gegevens van een FTD-mail.
typedef FtdList                     FtdGroupList;                   ///< Een lijst met pointers naar ::FtdGroup structuren.
typedef struct _ftd_filter          FtdFilter;                      ///< De gegevens van een filter voor events.
typedef struct _ftd_tag             FtdTag;                         ///< De gegevens van een tag voor een event.

/**
 * Een callback functie-type voor gebruik bij de functie ::ftd_events_fetch.
 *
 * @arg     totaal      Het totaal aantal dump-bestanden dat gedownload wordt van de server.
 * @arg     huidig      Het (volg)nummer van het dump-bestand dat nu gedownload wordt van de server.
 */
typedef void (*FtdEventFileCallback) (int totaal, int huidig);
/**
 * Een callback functie-type voor gebruik bij de functie ::ftd_events_fetch.
 *
 * @arg     totaal      Het totaal aantal events dat ingevoegd moet worden in de totaal-lijst.
 * @arg     huidig      Het (volg)nummer van het event dat nu ingevoegd wordt.
 * @arg     data        Callback data
 */
typedef void (*FtdEventParseCallback) (int totaal, int huidig, gpointer data);
/**
 * Een callback functie-type voor gebruik bij de functie ::ftd_events_fetch.
 *
 * De eerste keer dat deze callback wordt aangeroepen zijn alle events binnengehaald en opgeslagen.
 * De tweede keer is de volledige verwerking, inclusief het genereren van een eventueel overzicht, klaar.
 */
typedef void (*FtdEventStatusCallback) (gpointer data);
/**
 * Callback functie welke de opgegeven FtdString analyseert en eventueel
 * smilies en URL's omzet naar HTML code
 */
typedef FtdString * (*FtdParseFunc) (FtdString *);

typedef struct _ftd_http_parameter          FtdHttpParameter;       ///< De gegevens van een parameter voor HTTP aanroepen via de curl-functies. @see ftd_http_curl.c

typedef struct _ftd_event_forum             FtdEventForum;          ///< De gegevens van een forum bij een event.
typedef struct _ftd_event_forum_reactie     FtdEventForumReactie;   ///< De gegevens van een reactie op een forum bij een event.

/**
 * De configuratiegegevens van FTD.
 *
 * Dit zijn zo'n beetje alle opties die de gebruiker van FTD4linux kan beinvloeden.
 */
struct _ftd_config {
    gboolean         firstTime;                             ///< True indien dit de eerste keer is dat FTD4linux gebruikt wordt.
    time_t           lastCheck;                             ///< De timestamp van de laatste keer dat een geslaagde update werd uitgevoerd.
    time_t           prevCheck;                             ///< De timestamp van de voorlaatste keer dat een geslaagde update werd uitgevoerd.
    int              ledenCount;                            ///< Het aantal leden dat bij de vorige update geregistreerd was.
    FtdString       *numUsersOnline;                        ///< Het aantal leden dat tijdens de vorige update online was.
    FtdString       *username;                              ///< De gebruikersnaam voor FTD.
    FtdString       *password;                              ///< Het wachtwoord om op FTD in te loggen.
    FtdString       *proxyHost;                             ///< De hostname van de proxy of NULL als er geen proxy is.
    FtdString       *proxyPort;                             ///< De port die op de proxy gebruikt moet worden.
    FtdString       *proxyUser;                             ///< De gebruikersnaam om aan te melden bij de proxy.
    FtdString       *proxyPassword;                         ///< Het wachtwoord om in te loggen bij de proxy.
#ifndef BUILTIN_PLUGIN
    FtdString       *authPlugin;                            ///< De locatie van een eventuele plugin voor de authenticatie over HTTP.
#endif
    FtdString       *htmlRenderer;                         ///< De naam van de gebruikte HTML renderer in de GUI.
    FtdList         *watchlist;                             ///< Een lijst met ::FtdString pointers met daarin de FTD-ids van de events in de watchlist.
    FtdList         *badwords;                              ///< Een lijst met ::FtdString pointers met daarin de woorden die als 'bad word' zijn bestempeld.
    gboolean         updatenBijOpstarten;                   ///< True indien bij het opstarten meteen een update uitgevoerd dient te worden.
    gboolean         toonInfoBijEenZoekresultaat;           ///< True indien bij het vinden van slechts 1 event als resultaat van een zoekopdracht deze direct getoond dient te worden in plaats van de lijst die maar 1 groot is.
    gboolean         startMaximized;                        ///< True indien een GUI gemaximaliseerd gestart dient te worden.
    gboolean         toonStatusBijLaden;                    ///< True indien een status-venster bij het laden van een HTML-pagina in een GUI getoond dient te worden.
    gboolean         toonCategoriseerdeLijstBijKnopNieuw;   ///< True indien een gecategoriseerde lijst getoond dient te worden indien de nieuwe events opgevraagd worden.
    gboolean         trayIcon;                              ///< True indien een GUI een tray-icon dient te hebben.
    gboolean         toonGUIGroupFilter;                    ///< True indien een GUI een lijst met alle nieuwsgroepen die getoond worden moet laten zijn.
    gboolean         recursiveUpdate;                       ///< True indien een update recursief uitgevoerd moet worden totdat er niet meer updates gedaan kunnen worden.
    gboolean         groupFilter;                           ///< True indien er een groepsfilter is.
    FtdList         *groupFilterList;                       ///< Een lijst met ::FtdString pointers met daarin de nummers van de toegestane nieuwsgroepen.
    int              verwijderPostsNaXDagen;                ///< Het aantal dagen waarna een event uit de lijst verwijderd dient te worden.
    gboolean         gebruikFontFamily;                     ///< True indien gebruik gemaakt moet worden van voorgedefinieerde lettertypen in de gegenereerde HTML pagina's.
    gboolean         geenTabbedBrowsing;                    ///< True indien er voor de postinfo maar 1 tab gebruikt moet worden
    FtdList         *watcher;                               ///< Lijst met daarin alle zoektermen van de FTD4Linux Watcher
    gboolean         toonWatcherNotifications;              ///< True indien notifications getoond dienen te worden als de FTD4Linux Watcher nieuwe postings ontdekt
    gboolean         openPostinfoOpAchtergrond;             ///< True indien de GUI niet automatisch een postinfo moet tabblad moet activeren als een posting wordt aangeklikt
    FtdString       *ircNickname;
    FtdString       *ircAltNickname;
    gboolean         toonIRCClient;
    int              ratingScale;
    FtdList         *statusList;                            ///< Een lijst van FtdStatus'en met daarin de status'en welke getoond moeten worden.
};
/**
 * De gegevens van een filter voor events.
 * Deze filters werken op basis van acceptatie: de gegevens die zijn ingevuld in een filter moeten matchen tegen een event, wil dit event geaccepteerd worden door het filter.
 * Om een voorbeeld te geven: neem een filter met daarin alleen de poster ingevuld als 'aa'. Alle events met posters als 'blaat' en 'aapje' zullen geaccepteerd worden,
 * maar een event met als poster 'dombo' zal niet geaccepteerd worden.
 */
struct _ftd_filter {
    FtdString           *filterNaam;                        ///< De eventuele naam van dit filter.
    time_t               prevCheck;                         ///< Alleen events tussen prevCheck en nu moeten getoond worden, 0 indien dit niet uitmaakt.
    int                  postId;                            ///< Een FTD-id waarop gefilterd wordt. of 0 als dit niet uitmaakt.
    FtdString           *title;                             ///< Een deel van de titel waarop gefilterd wordt, of NULL als dit niet uitmaakt.
    FtdString           *poster;                            ///< Een deel van de posternaam waarop gefilterd wordt, of NULL als dit niet uitmaakt.
    int                  cat;                               ///< De ftd-categorie waarop gefilterd wordt, of -1 als dit niet uitmaakt.
    int                  sCat;                              ///< De ftd-sub-categorie waarop gefilterd wordt, of -1 als dit niet uitmaakt.
    FtdList             *tags;                              ///< Een lijst met ::FtdString pointers met daarin de codes van de tags waarop gefilterd moet worden. @see ::FtdTag.code
    FtdString           *extra_tag;                         ///< De extra tag die opgegeven werd bij een event, of NULL indien dit niet uitmaakt.
    FtdEventSortType     veld;                              ///< Het veld waarop gesorteerd moet worden.
    gboolean             asc;                               ///< True indien de sortering oplopend moet zijn.
    gboolean             categoriseerd;                     ///< True indien het resultaat gecategoriseerd gegenereerd dient te worden.
    gboolean             daySelector;                       ///< True indien een tijdspanne is gekozen binnen welke events gezocht worden.
    time_t               start_time;                        ///< De timestamp van het start van een eventuele tijdspanne binnen welke events gezocht wordem.
    time_t               end_time;                          ///< De timestamp van het eind van een eventuele tijdspanne binnen welke events gezocht wordem.
    FtdList             *groupFilterList;                   ///< Een lijst van ::FtdString pointers met daarin de nummers van de nieuwsgroepen in welke events gezocht worden.
    FtdList             *statusList;                        ///< Een lijst van FtdStatus'en met daarin de status'en welke getoond moeten worden.
};

/**
 * De gegevens van een categorie.
 * Het betreft hier een categorie zoals deze gebruikt wordt in de FTD-programma's om een hoeveelheid events onder te laten vallen.
 * Voorbeelden van categorieen in FTD4linux 1.0B1 (FTD 3.7.3) zijn onder meer 'Beeld->DVD' en 'Applicaties->Linux/MAC', zoals links
 * in de GUIs te vinden.
 */
struct _ftd_category {
    FtdString       *name;                                      ///< De naam van de categorie.
    int              cat;                                       ///< De ftd-categorie die in deze categorie te vinden is.
    gboolean         header;                                    ///< True indien deze categorie een header is voor andere, specifiekere categorieen.
    FtdFilter       *filter;                                    ///< De filter die de inhoud van deze categorie bepaald. Dit filter mag nooit vrijgegeven worden als header nul is.
    int              aantalPostings;                            ///< Het aantal events dat in deze categorie nieuw is sinds de vorige succesvolle update. Deze waarde wordt bepaald aan de hand van het toegepaste filter.
};

/**
 * De gegevens van een nieuwsgroep.
 */
struct _ftd_group {
    int          groupId;                                   ///< Het nummer van een nieuwsgroep. Deze nummers worden door de FTD-servers geleverd.
    FtdString   *groupName;                                 ///< De naam van een nieuwsgroep.
};

/**
 * De gegevens van een post (technische term: event) op FTD.
 * In deze documentatie wordt gebruik gemaakt van de term 'event' omdat deze naast specifiek ook veel gebruikt is in de code.
 * Bij een event is het belangrijk te beseffen dat niet altijd alle gegevens zijn ingevuld. Lokaal worden alleen de basis-gegevens
 * bewaard die nodig zijn om eenlijst ervan te kunnen bouwen. Details als de aankondiging en het forum moeten apart opgehaald
 * worden van de FTD-servers. Let ook op de afhankelijkheid tussen cat, sCat en tags. sCat en tags ontlenen hun exacte betekenis
 * aan de context van de cat.
 */
struct _ftd_event {
    int              postId;                                ///< Het FTD-id van het event.
    time_t           stamp;                                 ///< De timestamp wanneer deze event gepost werd.
    time_t           updated;                               ///< De timestamp wanneer deze event voor het laatste geupdate werd.
    FtdStatus        status;                                ///< De status van deze event.
    FtdString       *fileName;                              ///< Het begin van de filename van deze event.
                                                            ///< Het gedeelte abc uit abc.part01.rar bijvoorbeeld.
    FtdString       *title;                                 ///< De titel van deze event.
    FtdList         *groups;                                ///< Een lijst met ::FtdString pointers met daarin de nummers van de nieuwsgroepen waarin deze event wordt gepost. @see ::FtdGroup.
    FtdString       *poster;                                ///< De naam van de poster.
    FtdString       *link;                                  ///< De URL waarnaar een link staat met meer informatie over de event. NULL indien er geen link is.
    int              cat;                                   ///< De FTD-categorie waarin deze event valt. Dit zijn 1 voor beeld, 2 voor geluid, 3 voor spelletjes en 4 voor applicaties.
    int              sCat;                                  ///< De FTD-sub-categorie waarin deze event valt. Dit is het nummer van de (eerste) a-tag die op de event van toepassing is. Bijvoorbeeld: de tag a1 geeft sCat = 1.
    FtdList         *tags;                                  ///< Een lijst met ::FtdString pointers met daarin de codes van de tags die op de event van toepassing zijn. @see ::FtdTag.code.
    FtdString       *extra_tag;                             ///< De extra tag die voor deze event is ingevoerd. Deze tag is de tag die in de FTD-programma's wordt aangeduidt met 'tag'. Om het allemaal wat makkelijker te maken. @see ::_ftd_tag
    int              rating;                                ///< De rating die deze event heeft.
    FtdString       *announcement;                          ///< De aankondiging.
    FtdString       *description;                           ///< De beschrijving.
    FtdString       *sig;                                   ///< Het repost-beleid. De benaming sig is waarschijnlijk vanwege historische redenen.
    FtdFiletype      fileType;                              ///< Het soort bestanden dat gepost wordt.
    int              aantalFiles;                           ///< Het totaal aantal bestanden dat gepost wordt.
    int              fileStart;                             ///< Het eerste bestand dat gepost wordt. 1 wordt beschouwd als het allereerste.
    FtdString       *image;                                 ///< De URL naar een image die bij de event getoond dient te worden.
    FtdEventForum   *forum;                                 ///< Het forum zoals bij de event te vinden is.
    int              parType;                               ///< Het type par-bestanden dat meegeleverd wordt. 0 voor geen, 1 voor par1 en 2 voor par2.
    int              aantalParFiles;                        ///< Het aantal blokken dat meegestuurd wordt. Het aantal bestanden als het om par1 gaat. -1 als er achteraf pas geleverd wordt.
    int              parBlockSize;                          ///< De grootte van 1 par-block in bytes.
    int              numViews;                              ///< Het aantal keer dat deze event is bekeken.
    int              kudos;                                 ///< Het aantal kudos dat de event verdiend heeft.
    FtdList         *mp3Tracks;                             ///< Een lijst met ::FtdString pointers met daarin de bestandsnamen van de mp3-files. Alleen gebruikt als fileType=FILETYPE_M3U.
    gboolean         locked;                                ///< Is de posting gelocked?
    FtdString       *reason;                                ///< Reden van verwijdering
    gboolean         geupdated_in_watchlist;
    gboolean         gevonden_voor_watcher;
};

/**
 * De gegevens van een reactie op een forum bij een event.
 * Alle forumberichten van een forum worden verzameld in een ::FtdForum.
 */
struct _ftd_event_forum_reactie {
    int          messageId;                                 ///< Het nummer van het forum-bericht.
    FtdString   *author;                                    ///< De naam van de auteur van het bericht.
    FtdString   *body;                                      ///< Het bericht zelf.
    time_t       stamp;                                     ///< De timestamp wanneer het bericht geplaatst werd.
    time_t       lastEdited;                                ///< De timestamp wanneer het bericht het laatste veranderd werd.
    int          kudos;                                     ///< Het aantal kudos dat bij dit bericht meegegeven werd.
    int          reply;
    FtdString   *avatar;
};

/**
 * De gegevens van een forum bij een event.
 */
struct _ftd_event_forum {
    FtdList     *forum_reacties;                            ///< Een lijst met ::FtdEventForumReactie pointers.
    time_t       lastUpdated;                               ///< De timestamp wanneer het forum voor het laatst werd bewerkt.
};

/**
 * De gegevens van een FTD-mail.
 */
struct _ftd_mail_bericht {
    FtdString   *from;                                      ///< De afzender van het bericht of, bij een verzonden bericht, de geadresseerde.
    FtdString   *subject;                                   ///< Het onderwerp van het bericht.
    FtdString   *body;                                      ///< Het bericht zelf.
    time_t       stamp;                                     ///< De timestamp wanneer het bericht verzonden werd.
    FtdMailType  type;                                      ///< Het type bericht (verzonden of ontvangen).
};

/**
 * De gegevens van een tag voor een event.
 * Dit is dus niet een tag zoals deze in de FTD programma's 'tag' genoemd wordt. Het is een eigenschap van de event zoals
 * het type medium (DVD of DivX) of het genre (Pop, Rock, Klassiek). Deze tags (binnen deze documentatie en in de code
 * is een tag altijd een tag zoals in deze structuur) hebben een naam en code en er zit een hierarcie in om de context van
 * een tag helder te maken (Rock heeft als genre vrij weinig betekenis bij een MAC-applicatie, om maar een zijweg te noemen,
 * de tag 'Rock' zal dan ook een parent hebben die met geluid te maken heeft).
 */
struct _ftd_tag {
    int          cat;                                       ///< De FTD-categorie waar deze tag voor geldt.
    FtdTag      *parent;                                    ///< De ouder van deze tag of NULL indien hij geen ouder heeft.
    FtdString   *code;                                      ///< De code van deze tag. Dit is altijd een enkele letter gevolgd door een getal.
    FtdString   *name;                                      ///< De naam van deze tag.
};

/**
 * De gegevens van een parameter voor HTTP aanroepen via de curl-functies.
 * Deze parameters worden gebruikt in de communicatie met de FTD servers.
 *
 * @see ftd_http_curl.c
 */
struct _ftd_http_parameter {
    FtdString                   *paramName;                 ///< De naam van de parameter.
    FtdString                   *paramValue;                ///< De waarde van de parameter.
};

typedef struct _ftd_profile {
    char *username;
    time_t stamp;
    int numPosts;
    int numSpots;
    int kudos;
    int given;
    int received;
    int rank;
    char *email;
    char *info;
    char *avatar;
    int status;
    char *site;
    char *im;
    char *isp;
    char *ns;
    char *hobby;
    int pstat;
} FtdProfile;


FtdString   *ftd_string_append(FtdString *string, const char *value);
void         ftd_string_free(FtdString *string);
gsize        ftd_string_length(FtdString *string);
void         ftd_string_append_printf (FtdString *string, const gchar *format, ...);
char        *ftd_string_upcase(char *);
char        *ftd_string_date(time_t);
FtdString   *ftd_string_integer(int);
char        *ftd_string_value(FtdString *);
FtdString   *ftd_string_new(const char *);
FtdString   *ftd_string_replace(FtdString *, char *, char *);
char        *ftd_string_strip_newsgroup(FtdString *);
FtdString   *ftd_string_add_http(FtdString *);
const char  *ftd_string_status(FtdStatus);
const char  *ftd_string_category(int);

FtdList     *ftd_splitted_list_duplicate(FtdList *);
void         ftd_splitted_list_free(FtdList **);
FtdList     *ftd_splitted_list_split(const char *);
FtdString   *ftd_splitted_list_concat(FtdList *);

FtdList     *ftd_list_prepend (FtdList *list, gpointer value);
FtdList     *ftd_list_append (FtdList *list, gpointer value);
FtdList     *ftd_list_remove (FtdList *list, gconstpointer value);
void         ftd_list_free(FtdList *list);
guint        ftd_list_length(FtdList *list);
gpointer     ftd_list_value(FtdList *list);
FtdList     *ftd_list_next(FtdList *list);
void         ftd_list_foreach (FtdList *list, GFunc func, gpointer user_data);
FtdList     *ftd_list_copy(FtdList *list);
FtdList     *ftd_list_find(FtdList *list, gconstpointer data);
FtdList     *ftd_list_reverse(FtdList *list);

FtdHttpParameter    *ftd_http_parameter_new(const char *, const char *);
void                 ftd_http_parameter_free(FtdHttpParameter *);
void                 ftd_http_parameter_free_all(FtdList *);

void                 ftd_http_curl_set_ftd_mail_callback(void (*cb) (gpointer), gpointer);
FtdErrorCode         ftd_http_curl_execute(const char *, FtdList *, gboolean, FtdString **, gboolean, char **, gboolean);
FtdErrorCode         ftd_http_curl_decode_events(char *, char *, unsigned char **);

gboolean         ftd_app_core_init(const char *, const char *, const char *, const char *, gboolean, char **, gboolean *);
void             ftd_app_core_cleanup(void);
gboolean         ftd_app_core_is_first_time(void);

gchar           *ftd_error_msg(int, const char *);

char            *ftd_file_parse_data_filename(const char *);
char            *ftd_file_parse_cache_filename(const char *, gboolean);
char            *ftd_file_parse_data_dir(const char *filename);
char            *ftd_file_parse_lib_dir(const char *filename);
FtdString       *ftd_file_load(const char *, gboolean);
int              ftd_file_save(const char *, FtdString *, gboolean);

FtdFilter       *ftd_filter_new_filter(void);
void             ftd_filter_free_filter(FtdFilter * filter);
FtdFilter       *ftd_filter_duplicate(const FtdFilter *orig_filter);
void             ftd_filter_save(void);

void             ftd_config_save(void);
FtdConfig       *ftd_config_get(void);
void             ftd_config_create_dummy(void);

FtdErrorCode     ftd_group_fetch(char **);
void             ftd_group_load(void);
const FtdList   *ftd_groups_get(void);
void             ftd_group_set_group_id_list(FtdList *);
void             ftd_group_unset_group_id_list(void);
gboolean         ftd_group_id_is_in_list(int);
FtdGroup        *ftd_group_by_id(int);
gboolean         ftd_group_list_ready(void);

FtdCategoryList *ftd_categories_get(void);
FtdCategory     *ftd_category_get_parent(int);
FtdList         *ftd_category_find(const FtdEvent *);
const char      *ftd_category_get_scat_name(int cat, int sCat);

int              ftd_xml_parse_int(xmlDocPtr, xmlNodePtr);
FtdString       *ftd_xml_parse_string(xmlDocPtr, xmlNodePtr);
int              ftd_xml_parse_int_attr(xmlDocPtr, xmlNodePtr, char *);

const FtdList   *ftd_get_tags(void);
const FtdTag    *ftd_tag_find(FtdString *, int);
FtdList         *ftd_tag_get_tags_in_cat(int);

FtdErrorCode     ftd_modje_send(int post_id, int forum_id, const char *msg, int *count, char **errmsg);

FtdErrorCode     ftd_profile_get(const char *username, FtdProfile **profile, char **errmsg);
void             ftd_profile_free(FtdProfile *profile);

/* Nieuwe GObject-gebaseerde interface */
#define FTD_EVENTLIST_TYPE_OBJECT       (ftd_eventlist_get_type ())
#define FTD_EVENTLIST(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), FTD_EVENTLIST_TYPE_OBJECT, FTDEventlist))
#define FTD_EVENTLIST_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), FTD_EVENTLIST_TYPE_OBJECT, FTDEventlistClass))
#define FTD_IS_EVENTLIST(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), FTD_EVENTLIST_TYPE_OBJECT))
#define FTD_IS_EVENTLIST_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), FTD_EVENTLIST_TYPE_OBJECT))
#define FTD_EVENTLIST_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), FTD_EVENTLIST_TYPE_OBJECT, FTDEventlistClass))

#define FTD_EVENT_TYPE_OBJECT              (ftd_event_object_get_type ())
#define FTD_EVENT_OBJECT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), FTD_EVENT_TYPE_OBJECT, FTDEventObject))
#define FTD_EVENT_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), FTD_EVENT_TYPE_OBJECT, FTDEventObjectClass))
#define FTD_EVENT_IS_OBJECT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), FTD_EVENT_TYPE_OBJECT))
#define FTD_EVENT_IS_OBJECT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), FTD_EVENT_TYPE_OBJECT))
#define FTD_EVENT_OBJECT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), FTD_EVENT_TYPE_OBJECT, FTDEventObjectClass))

#define FTD_FILTER_TYPE_OBJECT              (ftd_filter_object_get_type ())
#define FTD_FILTER_OBJECT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), FTD_FILTER_TYPE_OBJECT, FTDFilterObject))
#define FTD_FILTER_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), FTD_FILTER_TYPE_OBJECT, FTDFilterObjectClass))
#define FTD_FILTER_IS_OBJECT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), FTD_FILTER_TYPE_OBJECT))
#define FTD_FILTER_IS_OBJECT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), FTD_FILTER_TYPE_OBJECT))
#define FTD_FILTER_OBJECT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), FTD_FILTER_TYPE_OBJECT, FTDFilterObjectClass))

#define FTD_FILTERLIST_TYPE_OBJECT       (ftd_filterlist_get_type ())
#define FTD_FILTERLIST(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), FTD_FILTERLIST_TYPE_OBJECT, FTDFilterlist))
#define FTD_FILTERLIST_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), FTD_FILTERLIST_TYPE_OBJECT, FTDFilterlistClass))
#define FTD_IS_FILTERLIST(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), FTD_FILTERLIST_TYPE_OBJECT))
#define FTD_IS_FILTERLIST_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), FTD_FILTERLIST_TYPE_OBJECT))
#define FTD_FILTERLIST_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), FTD_FILTERLIST_TYPE_OBJECT, FTDFilterlistClass))

FTDEventlist    *ftd_eventlist_get(void);
void             ftd_eventlist_foreach(FTDEventlist *obj, gboolean filtered_list, gboolean read_only, GTraverseFunc cb, gpointer data);
gboolean         ftd_eventlist_load(FTDEventlist *obj, char **errmsg);
gboolean         ftd_eventlist_save(FTDEventlist *obj);
void             ftd_eventlist_foreach(FTDEventlist *obj, gboolean filtered_list, gboolean read_only, GTraverseFunc cb, gpointer data);
void             ftd_eventlist_merge (FTDEventlist *obj, FtdList *listNieuw, FtdEventParseCallback callback, gpointer callback_data);
void             ftd_eventlist_purge_deleted(FTDEventlist *obj);
void             ftd_eventlist_cleanup(FTDEventlist *obj);
int              ftd_eventlist_get_count(FTDEventlist *obj, gboolean filtered);
FtdEvent        *ftd_eventlist_get_first_filtered_event(FTDEventlist *obj);
void             ftd_eventlist_add_or_replace_event (FTDEventlist *obj, const FtdEvent *event);
FtdEvent        *ftd_eventlist_lookup_id(FTDEventlist *obj, int eventId);
FtdFilter       *ftd_eventlist_get_filter(FTDEventlist *obj);
void             ftd_eventlist_apply_filter(FTDEventlist *obj, FtdFilter *filter);
void             ftd_eventlist_set_posting_is_active(FTDEventlist *obj, int eventId, gboolean is_active);

FTDEventObject  *ftd_event_object_new(void);
void             ftd_event_object_destroy(FTDEventObject *obj);
FtdEvent        *ftd_event_duplicate(const FtdEvent *event_orig);
FtdEvent        *ftd_event_object_get_event(FTDEventObject *obj);
void             ftd_event_object_set_event(FTDEventObject *obj, const FtdEvent *event);

FTDFilterObject *ftd_filter_object_new(void);
void             ftd_filter_object_destroy(FTDFilterObject *obj);
FtdFilter       *ftd_filter_object_get_filter(FTDFilterObject *obj);
void             ftd_filter_object_set_filter(FTDFilterObject *obj, const FtdFilter *filter);

FTDFilterlist   *ftd_filterlist_get(void);
void             ftd_filterlist_load(FTDFilterlist *obj);
void             ftd_filterlist_save(FTDFilterlist *obj);
void             ftd_filterlist_foreach(FTDFilterlist *obj, gboolean read_only, GFunc cb, gpointer user_data);
void             ftd_filterlist_append_filter(FTDFilterlist *obj, const FtdFilter *filter);
void             ftd_filterlist_set_filters(FTDFilterlist *obj, FtdList *filters);

/* Oude niet-gobject gebaseerde code */
FtdErrorCode     ftd_events_fetch(FtdEventFileCallback, FtdEventParseCallback, FtdEventStatusCallback, char **, gpointer);
void             ftd_event_free(FtdEvent *);
FtdEvent        *ftd_event_duplicate(const FtdEvent *event_orig);

FtdString       *ftd_events_sort_total(FtdParseFunc);
FtdString       *ftd_events_sort_filtered(FtdParseFunc);
FtdString       *ftd_events_sort_print (FtdEvent *, gboolean, int, FtdParseFunc);

FtdErrorCode     ftd_events_forum_fetch(int, time_t, char **);
FtdErrorCode     ftd_events_forum_post(gchar *, int, gpointer, char **);
void             ftd_events_forum_free(FtdEventForum *);

FtdErrorCode     ftd_eventinfo_fetch(int, char **);

FtdErrorCode     ftd_post_send(FtdEvent *, void(*callback)(FtdSendState));

gboolean         ftd_watchlist_add(int);
gboolean         ftd_watchlist_remove(int);
void             ftd_watchlist_clear(void);
gboolean         ftd_watchlist_is_in_list(int);
int              ftd_watchlist_get_state(void);
void             ftd_watchlist_set_state(int);
FtdList         *ftd_watchlist_get(void);
FtdErrorCode     ftd_watchlist_download(char **errmsg);
FtdErrorCode     ftd_watchlist_upload(char **errmsg);

void             ftd_watcher_foreach(const char *zoekterm, void (*cb) (const FtdEvent *, const char *, gpointer), gpointer data);
int              ftd_watcher_get_state(void);
void             ftd_watcher_set_state(int value);

FtdErrorCode     ftd_mail_check(gboolean *, char **);
FtdErrorCode     ftd_mail_fetch(int *, char **);
FtdString       *ftd_mail_print(FtdMailBericht *, gboolean, FtdParseFunc);
const FtdList   *ftd_mail_get(void);
void             ftd_mail_delete(FtdMailBericht *);
int              ftd_mail_get_num_messages(void);
FtdErrorCode     ftd_mail_post(FtdMailBericht *, char **);

FtdErrorCode     ftd_signup_register(const char *, const char *, const char *, char **);

FtdErrorCode     ftd_kudos_get(int, int *, int *, char **);
FtdErrorCode     ftd_kudos_give(int, int, char **);

xmlDocPtr        ftd_myftd_print(FtdList *myftd_list);
int              ftd_myftd_parse(FtdString *buffer, FtdList **ret);
FtdErrorCode     ftd_myftd_update(int postId, char **errmsg);

const char       *ftd_svn_get_revision(void);

#ifdef HAVE_DBUS
typedef struct OpenFTDDBusObject OpenFTDDBusObject;

OpenFTDDBusObject *ftd_dbus_get_object(void);

/* Met de glib API functie g_signal_connect vallen de volgende
   callback functies aan bovenstaand GObject te hangen :

   "bring_to_front"     Het FTD4Linux venster moet gepresenteerd worden aan de gebruiker
   "open_post"          Er moet een bepaalde posting worden geopend
*/
#endif

#ifdef __cplusplus
}
#endif

#endif /* _FTD4LINUX_H_ */
