/* $Id: ggadu_repo.h,v 1.4 2004/12/26 22:23:16 shaster Exp $ */

/* 
 * GNU Gadu 2 
 * 
 * Copyright (C) 2001-2005 GNU Gadu Team 
 * 
 * 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 GGadu_REPO_H
#define GGadu_REPO_H 1

#include <glib.h>
#include <limits.h>

#ifndef GG2_CORE_H
#include "ggadu_types.h"
#endif

typedef void (*watch_ptr) (gchar *, gpointer, gint);
typedef gpointer GGaduRepoKey;

typedef struct
{
    gpointer key;
    gpointer value;
    gint type;
    GSList *watches;
} GGaduRepoValue;

typedef struct
{
    gchar *name;
    GSList *values;
    GSList *watches;
} GGaduRepo;

typedef struct
{
    gint actions;
    gint types;
    watch_ptr callback;
} GGaduRepoWatch;

gboolean ggadu_repo_check_value(gchar * repo_name, gpointer key);
gpointer ggadu_repo_find_value(gchar * repo_name, gpointer key);
gboolean ggadu_repo_exists(gchar * repo_name);

enum
{
    REPO_VALUE_DC = 0,		/* don't change */
    REPO_VALUE_CONTACT = 1,
    REPO_VALUE_SETTING = 2,
    REPO_VALUE_PROTOCOL = 4,
    REPO_VALUE_OTHER = 8,

    REPO_VALUE_ANY = INT_MAX
};

void ggadu_repo_disable_notification();
void ggadu_repo_enable_notification();

GGaduRepoKey ggadu_repo_key_from_string(gchar * key);
gboolean ggadu_repo_add(gchar * repo_name);
gboolean ggadu_repo_add_value(gchar * repo_name, gpointer key, gpointer value, gint type);
gboolean ggadu_repo_change_value(gchar * repo_name, gpointer key, gpointer value, gint type);
gboolean ggadu_repo_del_value(gchar * repo_name, gpointer key);
gboolean ggadu_repo_del(gchar * repo_name);

gpointer ggadu_repo_value_first(gchar * repo_name, gint type, gpointer * data);
gpointer ggadu_repo_value_next(gchar * repo_name, gint type, gpointer * data, gpointer index);
GSList*  ggadu_repo_get_as_slist(gchar * repo_name, gint type);

enum
{
    REPO_ACTION_NEW = 1,	/* dodanie nowego repo */
    REPO_ACTION_DEL = 2,	/* usunięcie danego repo */
    REPO_ACTION_CHANGE = 4,	/* zmiana w danym repo (wartości) */
    REPO_ACTION_VALUE_NEW = 8,	/* nowa wartość w repo */
    REPO_ACTION_VALUE_DEL = 16,	/* usunięcie wartości */
    REPO_ACTION_VALUE_CHANGE = 32	/* zmiana wartości */
};

extern const gint REPO_mask;
extern const gint REPO_value_mask;

/* Czym się różni REPO_ACTION_VALUE_* od REPO_ACTION_CHANGE?
 * Ano tym, że REPO_ACTION_CHANGE stwierdza tylko, czy coś się zmieniło w repo.
 * A to coś to dowolna wartość.
 *
 * REPO_ACTION_VALUE_* tyczy się tylko jednej, podanej wartości.
 *
 * Jeśli jeden callback obsługuje np. REPO_ACTION_VALUE_NEW
 * i REPO_ACTION_CHANGE,
 * to gdy zostanie dodana nowa wartość, to callback zostanie poinformowany
 * o REPO_ACTION_VALUE_NEW.
 *
 * Jeśli jest usuwane repo, to niezależnie od podanych masek, zawsze wysyłany
 * jest REPO_ACTION_DEL.
 *
 * Informacje o usunięciu są wysyłane przed usunięciem danych z repo, natomiast
 * inne informacje już po dodaniu/modyfikacji.
 */

/* GGaduRepo_watch_add(gchar *repo_name,gpointer key,gint actions,gpointer callback)
 *
 * repo_name - nazwa repo, w którym jest nasłuch
 * actions   - maska, określająca akcje, przy których wywoływany jest callback
 * key       - klucz, który ma być sprawdzany (jeśli w actions siedzi jedno
 *             z *_VALUE_*)
 * callback  - wskaźnik do funkcji, przyjmującej trzy argumenty:
 *             callback (gchar *repo_name, gpointer key, gint actions)
 *             actions zawiera informacje o akcji na danym repo lub key
 *
 * Kolejne wywołania GGaduRepo_watch_add z tymi samymi danymi (repo_name, key,
 * callback)
 * uaktualnia maskę akcji (dodaje brakujące elementy).
 * 
 * GGaduRepo_watch_del() usuwa podane akcje odnoszące się do danego repo
 * (repo_name), klucza
 * (key) oraz callbacku (callback). Jeśli actions jest równe actions podanym
 * funkcji
 * GGaduRepo_watch_add(), to watch jest całkowicie usuwany.
 */
gboolean ggadu_repo_watch_add(gchar * repo_name, gint actions, gint types, watch_ptr callback);
gboolean ggadu_repo_watch_del(gchar * repo_name, gint actions, gint types, watch_ptr callback);

gboolean ggadu_repo_watch_value_add(gchar * repo_name, gpointer key, gint actions, watch_ptr callback);
gboolean ggadu_repo_watch_value_del(gchar * repo_name, gpointer key, gint actions, watch_ptr callback);

gboolean ggadu_repo_watch_clear_callback(watch_ptr callback);

#endif
