/*

Copyright (C) 2000 - 2004 Christian Kreibich <christian@whoop.org>.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies of the Software and its documentation and acknowledgment shall be
given in the documentation and software packages that this Software was
used.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/
#ifndef __libnd_prefs_h
#define __libnd_prefs_h

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>

#include <libnd.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define LND_DOM_NETDUDE   "libnetdude"

typedef enum
{
  LND_PREFS_INT = 1,
  LND_PREFS_FLT = 2,
  LND_PREFS_STR = 3,
  LND_PREFS_UNK = 4
} LND_PrefsType;


typedef struct lnd_prefs_entry
{
  const char             *key;
  LND_PrefsType           type;

  int                     int_val;
  float                   flt_val;
  const char             *str_val;

} LND_PrefsEntry;


typedef struct lnd_prefs_domain LND_PrefsDomain;
/**
 * LND_PrefsCallback - signature of preferences-apply functions.
 * @domain: the preferences domain that got updated.
 * @user_data: arbitrary user data.
 *
 * This is the signature of functions passed to libnd_prefs_add_domain()
 * that get called when the user applies changes in preference settings.
 */
typedef void (*LND_PrefsCallback) (LND_PrefsDomain *domain, void *user_data);


struct lnd_prefs_domain
{
  /* The name of this domain */
  char                   *name;

  /* The preferences description for this domain */
  LND_PrefsEntry          *entries;
  int                     num_entries;

  /* The hashtable that stores the settings */
  GHashTable             *table;

  /* The callbacks that gets called when the current values
   * of this domain's preference settings are applied to
   * the application.
   */
  GList                  *apply_callbacks; /* GList<LND_PrefsCallback> */

  void                    *user_data;
};


/* You can use this to make statically initialized tables
 * more readable, see libnd_prefs.c.
 */
#define LND_UNUSED 0

/**
 * libnd_prefs_init - initializes preferences management.
 */
void             libnd_prefs_init(void);

/**
 * libnd_prefs_load - loads preferences from disk.
 *
 * This initializes the preferences as they're found in the 
 * user's config file, which is created if it doesn't yet
 * exist. Called during Netdude startup. You don't need this.
 */
void             libnd_prefs_load(void);

/**
 * libnd_prefs_save - saves current preference settings to disk
 *
 * Returns: %TRUE on success, %FALSE otherwise.
 */
int              libnd_prefs_save(void);

/**
 * libnd_prefs_apply - calls the registered preferences application callbacks.
 *
 * This function iterates over the registered preferences domains
 * and calls the apply callbacks registered for each of these
 * domains.
 */
void             libnd_prefs_apply(void);

/**
 * libnd_prefs_get_netdude_dir - returns netdude config directory.
 *
 * The function returns a pointer to static memory containing
 * the directory to the user's Netdude directory, where
 * preferences and locally-installed plugins are stored.
 *
 * Returns: user's Netdude directory.
 */
const char      *libnd_prefs_get_netdude_dir(void);

/**
 * libnd_prefs_get_config_file - returns filename of netdude config file.
 *
 * The function returns a pointer to static memory containing
 * the name of the user's Netdude config file.
 *
 * Returns: config file name.
 */
const char      *libnd_prefs_get_config_file(void);

/**
 * libnd_prefs_get_plugin_dir_global - returns global plugin directory.
 *
 * The function returns a pointer to static memory containing
 * the name of the system-wide feature plugin directory.
 *
 * Returns: global plugin directory.
 */
const char      *libnd_prefs_get_plugin_dir_global(void);

/**
 * libnd_prefs_get_plugin_dir_user - returns user's plugin directory.
 *
 * The function returns a pointer to static memory containing
 * the name of the user's feature plugin directory.
 *
 * Returns: user's plugin directory.
 */
const char      *libnd_prefs_get_plugin_dir_user(void);

/**
 * libnd_prefs_get_proto_dir_global - returns global protocol plugin directory.
 *
 * The function returns a pointer to static memory containing
 * the name of the system-wide protocol plugin directory.
 *
 * Returns: global protocol plugin directory.
 */
const char      *libnd_prefs_get_proto_dir_global(void);

/**
 * libnd_prefs_get_proto_dir_user - returns user's protocol plugin directory.
 *
 * The function returns a pointer to static memory containing
 * the name of the user's protocol plugin directory.
 *
 * Returns: user's plugin directory.
 */
const char      *libnd_prefs_get_proto_dir_user(void);


/**
 * libnd_prefs_add_domain - adds a preferences domain to the config system.
 * @domain: name of the domain.
 * @entries: array of LND_PrefsEntry structures describing preference settings.
 * @num_entries: length of @entries.
 *
 * Adds a new domain of configuration items, created from the given preference
 * entries, to the configuration system. The new preferences domain is
 * returned as well as registered.
 *
 * Returns: new preferences domain.
 */
LND_PrefsDomain *libnd_prefs_add_domain(const char *domain,
					LND_PrefsEntry *entries,
					int num_entries);

/**
 * libnd_prefs_get_domain - retrieves a configuration domain by name.
 * @domain: name of the domain to find.
 *
 * The function looks up and returns the domain namend @domain if possible.
 *
 * Returns: discovered domain, or %NULL if no such domain was found.
 */
LND_PrefsDomain *libnd_prefs_get_domain(const char *domain);


/**
 * libnd_prefs_domain_add_reply_cb - adds a callback to the domain, for applying settings.
 * @domain: domain to add callback to.
 * @apply_cb: the callback to register.
 *
 * The function registers @apply_cb for @domain, so that @apply_cb is
 * called whenever new configuration settings are applied.
 */
void             libnd_prefs_domain_add_apply_cb(LND_PrefsDomain *domain,
						 LND_PrefsCallback apply_cb);

/**
 * libnd_prefs_foreach_domain - configuration domain iterator.
 * @callback: callback to call for each domain.
 * @user_data: arbitrary data passed to @callback.
 *
 * The function iterates over all registered configuration domains,
 * passing each to @callback, alongside with @user_data.
 */
void             libnd_prefs_foreach_domain(LND_PrefsCallback callback, void *user_data);


/**
 * libnd_prefs_set_str_item - set string preference item.
 * @domain: domain of item.
 * @key: name of the item.
 * @data: new value of @key.
 *
 * The function stores @data as the value of @key in the preferences
 * database.
 */
void             libnd_prefs_set_str_item(const char *domain, const char *key, const char *data);

/**
 * libnd_prefs_set_flt_item - set float preference item.
 * @domain: domain of item.
 * @key: name of the item.
 * @data: new value of @key.
 *
 * The function stores @data as the value of @key in the preferences
 * database.
 */
void             libnd_prefs_set_flt_item(const char *domain, const char *key, float data);

/**
 * libnd_prefs_set_int_item - set integer preference item.
 * @domain: domain of item.
 * @key: name of the item.
 * @data: new value of @key.
 *
 * The function stores @data as the value of @key in the preferences
 * database.
 */
void             libnd_prefs_set_int_item(const char *domain, const char *key, int data);

/**
 * libnd_prefs_del_item - deletes a preference item.
 * @domain: domain of item.
 * @key: name of the item.
 *
 * The function removes the preference item from the database.
 */
void             libnd_prefs_del_item(const char *domain, const char *key);

/**
 * libnd_prefs_get_str_item - retrieves string preference item.
 * @domain: domain of item.
 * @key: name of item.
 * @result: pointer to result.
 * 
 * The function retrieves the specified preference item and stores
 * it in @result.
 *
 * Returns: %TRUE on success, %FALSE otherwise.
 */
gboolean         libnd_prefs_get_str_item(const char *domain, const char *key, char **result);

/**
 * libnd_prefs_get_flt_item - retrieves float preference item.
 * @domain: domain of item.
 * @key: name of item.
 * @result: pointer to result.
 * 
 * The function retrieves the specified preference item and stores
 * it in @result.
 *
 * Returns: %TRUE on success, %FALSE otherwise.
 */
gboolean         libnd_prefs_get_flt_item(const char *domain, const char *key, float *result);

/**
 * libnd_prefs_get_int_item - retrieves integer preference item.
 * @domain: domain of item.
 * @key: name of item.
 * @result: pointer to result.
 * 
 * The function retrieves the specified preference item and stores
 * it in @result.
 *
 * Returns: %TRUE on success, %FALSE otherwise.
 */
gboolean         libnd_prefs_get_int_item(const char *domain, const char *key, int   *result);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
