/*
  This file is part of ANASTASIS-GTK
  Copyright (C) 2024 Taler Systems SA

  ANASTASIS-GTK 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.

  ANASTASIS-GTK 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
  ANASTASIS-GTK; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
*/
/**
 * @file include/anastasis_gtk_util.h
 * @brief Interface for common utility functions
 * @author Christian Grothoff
 */
#ifndef ANASTASIS_GTK_UTIL_H
#define ANASTASIS_GTK_UTIL_H

#include <gnunet/gnunet_util_lib.h>


#include <gtk/gtk.h>
#include <gladeui/glade.h>
#include <gdk/gdkkeysyms.h>

#ifndef GDK_KEY_Return
#define GDK_KEY_Return GDK_Return
#endif
#ifndef GDK_KEY_Delete
#define GDK_KEY_Delete GDK_Delete
#endif

#define _(String) dgettext (PACKAGE, String)

#define DIR_SEPARATOR_STR "/"

#define DIR_SEPARATOR '/'


/**
 * Handle for our main loop.
 */
struct ANASTASIS_GTK_MainLoop;


/* ****************** Initialization *************** */


/**
 * Initialize natural language support.
 */
void
ANASTASIS_GTK_setup_nls (void);


/**
 * Initialize GTK search path for icons.
 *
 * @param pd project data to use
 */
void
ANASTASIS_GTK_set_icon_search_path (
  const struct GNUNET_OS_ProjectData *pd);


/**
 * Get the name of the directory where all of our package
 * data is stored ($PREFIX/share/)
 *
 * @param pd project data to use
 * @return name of the data directory
 */
const char *
ANASTASIS_GTK_get_data_dir (
  const struct GNUNET_OS_ProjectData *pd);


/**
 * @brief get the path to a specific GNUnet installation directory or,
 * with #GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation
 * directory
 * @author Milan
 *
 * @param dirkind which directory should be returned
 * @return a pointer to the dir path (to be freed by the caller)
 */
char *
ANASTASIS_GTK_installation_get_path (
  enum GNUNET_OS_InstallationPathKind dirkind);


/* **************** Glade/Gtk helpers *************** */

/**
 * Create an initialize a new builder based on the
 * GNUnet-GTK glade file.
 *
 * @param pd project data to use
 * @param filename name of the resource file to load
 * @param user_data user_data to pass to signal handlers,
 *        use "NULL" to pass the GtkBuilder itself.
 * @param cb function to call before connecting signals
 * @return NULL on error
 */
GtkBuilder *
ANASTASIS_GTK_get_new_builder2 (
  const struct GNUNET_OS_ProjectData *pd,
  const char *filename,
  void *user_data,
  GtkBuilderConnectFunc cb);


/**
 * Create an initialize a new builder based on the GNUnet-GTK glade
 * file.
 *
 * @param pd project data to use
 * @param filename name of the resource file to load
 * @param user_data user_data to pass to signal handlers,
 *        use "NULL" to pass the GtkBuilder itself.
 * @return NULL on error
 */
#define ANASTASIS_GTK_get_new_builder(pd, filename, user_data)      \
        ANASTASIS_GTK_get_new_builder2 (pd, filename, user_data, NULL)


/**
 * Convert a string from the current locale to UTF-8.
 *
 * @param str_loc string in current locale
 * @return string in UTF-8, NULL if str_loc was NULL
 */
char *
ANASTASIS_GTK_from_loc_to_utf8 (const char *str_loc);


/**
 * Returns filename form filechooser, encoded in UTF-8.
 *
 * @param fc file chooser to inspect
 * @return selected filename as UTF-8, NULL on errors
 */
char *
ANASTASIS_GTK_filechooser_get_filename_utf8 (GtkFileChooser *fc);


/* ******************* main loop ***************** */


/**
 * Initialize the main loop.
 *
 * @param pd project data of the program we are launching
 * @param binary_name binary name
 * @param binary_help help text for the binary
 * @param argc number of command line options
 * @param argv command line options
 * @param options allowed command line options
 * @param main_window_file glade file for the main window
 * @param main_task first task to run, closure will be set to the `struct
 * ANASTASIS_GTK_MainLoop`
 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (i.e. bad command-line
 * options, etc)
 */
int
ANASTASIS_GTK_main_loop_start (
  const struct GNUNET_OS_ProjectData *pd,
  const char *binary_name,
  const char *binary_help,
  int argc,
  char *const *argv,
  struct GNUNET_GETOPT_CommandLineOption *options,
  const char *main_window_file,
  GNUNET_SCHEDULER_TaskCallback main_task);


/**
 * Get an object from the main window.
 *
 * @param ml handle to the main loop
 * @param name name of the object
 * @return NULL on error, otherwise the object
 */
GObject *
ANASTASIS_GTK_main_loop_get_object (struct ANASTASIS_GTK_MainLoop *ml,
                                 const char *name);


/**
 * Get the builder from the main window.
 *
 * @param ml handle to the main loop
 * @return NULL on error, otherwise the builder
 */
GtkBuilder *
ANASTASIS_GTK_main_loop_get_builder (struct ANASTASIS_GTK_MainLoop *ml);


/**
 * Get remaining command line arguments.
 *
 * @param ml handle to the main loop
 * @param argc set to argument count
 * @param argv set to argument vector
 */
void
ANASTASIS_GTK_main_loop_get_args (struct ANASTASIS_GTK_MainLoop *ml,
                               int *argc,
                               char *const **argv);


/**
 * Initialize a GtkBuilder for the main window and exit
 * the main loop if this fails.
 *
 * @param pd project data to use
 * @param ml main loop contextual data
 * @param data additional argument to pass to #ANASTASIS_GTK_get_new_builder()
 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
 */
int
ANASTASIS_GTK_main_loop_build_window (
  const struct GNUNET_OS_ProjectData *pd,
  struct ANASTASIS_GTK_MainLoop *ml,
  gpointer data);


/**
 * Obtain the name of the configuration file that is being used
 * by gnunet-gtk.
 *
 * @param ml handle to the main loop
 * @return name of configuration file
 */
const char *
ANASTASIS_GTK_main_loop_get_gtk_configuration_file (
  struct ANASTASIS_GTK_MainLoop *ml);

/**
 * Obtain the name of the configuration file that is being used
 * by GNUnet (core).
 *
 * @param ml handle to the main loop
 * @return name of configuration file
 */
const char *
ANASTASIS_GTK_main_loop_get_gnunet_configuration_file (
  struct ANASTASIS_GTK_MainLoop *ml);


/**
 * Get the configuration.
 *
 * @param ml handle to the main loop
 * @return handle to the configuration, never NULL
 */
const struct GNUNET_CONFIGURATION_Handle *
ANASTASIS_GTK_main_loop_get_gtk_configuration (
  struct ANASTASIS_GTK_MainLoop *ml);


/**
 * Get the configuration.
 *
 * @param ml handle to the main loop
 * @return handle to the configuration, never NULL
 */
const struct GNUNET_CONFIGURATION_Handle *
ANASTASIS_GTK_main_loop_get_gnunet_configuration (struct ANASTASIS_GTK_MainLoop *ml);


/**
 * Trigger shutdown of the GUI and exit the main loop.
 *
 * @param ml handle to the main loop
 */
void
ANASTASIS_GTK_main_loop_quit (struct ANASTASIS_GTK_MainLoop *ml);


/**
 * Return project data used by Anastasis-Gtk.
 *
 * @return project data for anastasis-gtk
 */
const struct GNUNET_OS_ProjectData *
ANASTASIS_GTK_project_data (void);


#endif
