/*
     This file is part of GNUnet
     Copyright (C) 2012, 2013 GNUnet e.V.

     GNUnet 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 3, or (at your
     option) any later version.

     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     Boston, MA 02110-1301, USA.
*/

/**
 * @file src/include/gnunet_gtk_namestore_plugin.h
 * @author Christian Grothoff
 * @brief API for plugins for the GNS record editor
 */
#ifndef GNUNET_GTK_NAMESTORE_PLUGIN_H
#define GNUNET_GTK_NAMESTORE_PLUGIN_H

#include "gnunet_gtk.h"
#include <gnunet/gnunet_namestore_service.h>
#include <gnunet/gnunet_dnsparser_lib.h>


/**
 * Context for edit operations and environment for plugins.
 * Typical plugins will only use the @e check_validity callback.
 */
struct GNUNET_GTK_NAMESTORE_PluginEnvironment
{

  /**
   * Function that should be called by the plugin whenever values in
   * the dialog were edited.  It will check the validity of the dialog
   * and update the "save" button accordingly.
   */
  void (*check_validity) (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc);

  /**
   * Builder for the dialog.
   */
  GtkBuilder *builder;

  /**
   * Main dialog window.
   */
  GtkDialog *dialog;

  /**
   * Where in the tree view are we editing?
   */
  struct RecordInfo *ri;

  /**
   * Name of the record.
   */
  gchar *name;

  /**
   * Value of the record in string format.
   */
  gchar *n_value;

  /**
   * Name of the zone into which the record should be placed.
   */
  gchar *new_zone_option;

  /**
   * Ego of the zone into which the record should be placed.
   */
  struct GNUNET_IDENTITY_Ego *ego;

  /**
   * List of all zones.
   */
  GtkListStore *zone_liststore;

  /**
   * The plugin we used to edit the value.
   */
  struct GNUNET_GTK_NAMESTORE_PluginFunctions *plugin;

  /**
   * Name of the plugin library.
   */
  char *liblow;

  /**
   * Expiration time value (absolute or relative).
   */
  guint64 n_exp_time;

  /**
   * Offset of the record we are editing in the 'rd' list of 'ri'.
   */
  unsigned int off;

  /**
   * Flag indicating if the old record was in the namestore.
   */
  int old_record_in_namestore;

  /**
   * Type of the record.
   */
  uint32_t record_type;

  /**
   * Is this record 'public'?
   */
  gboolean n_public;

  /**
   * Is the expiration time relative?
   */
  gboolean n_is_relative;

  /**
   * Is this record a shadow record?
   */
  gboolean n_is_shadow;

  /**
   * Is this record pending?
   */
  gboolean n_is_pending;
};


/**
 * Symbol to give to the GtkBuilder for resolution.
 */
struct GNUNET_GTK_NAMESTORE_Symbol
{
  /**
   * Name of the symbol.
   */
  const char *name;

  /**
   * Corresponding callback.
   */
  GCallback cb;
};


/**
 * Each plugin is required to return a pointer to a struct of this
 * type as the return value from its entry point.
 */
struct GNUNET_GTK_NAMESTORE_PluginFunctions
{

  /**
   * Closure for all of the callbacks.  Will typically contain
   * the `struct GNUNET_GTK_NAMESTORE_PluginEnvironment`.
   */
  void *cls;

  /**
   * This must be set to the name of the ".glade" file containing the
   * dialog.
   */
  const char *dialog_glade_filename;

  /**
   * This must be set to the name of the dialog widget in the ".glade"
   * file.
   */
  const char *dialog_widget_name;

  /**
   * NULL-terminated array of symbols to add to the gtk builder.
   */
  const struct GNUNET_GTK_NAMESTORE_Symbol *symbols;

  /**
   * Function that will be called to initialize the builder's
   * widgets from the existing record (if there is one).
   * The `n_value` is the existing value of the record as a string.
   */
  void (*load) (void *cls, gchar *n_value, GtkBuilder *builder);

  /**
   * Function that will be called to retrieve the final value of the
   * record (in string format) once the dialog is being closed.
   */
  gchar *(*store) (void *cls, GtkBuilder *builder);

  /**
   * Function to call to validate the state of the dialog.  Should
   * return #GNUNET_OK if the information in the dialog is valid, and
   * #GNUNET_SYSERR if some fields contain invalid values.  The
   * function should highlight fields with invalid inputs for the
   * user.
   */
  int (*validate) (void *cls, GtkBuilder *builder);

  /**
   * Record type.  Can be used by the plugin to override the
   * record type selected by the user originally.  Plugins
   * can leave this value at zero to preserve the record
   * type from the original user's selection.  Note that
   * the record type MUST be adjusted immediately when
   * the plugin is loaded, not during the execution of the
   * dialog.
   */
  uint32_t record_type;
};


#endif
