/*
     This file is part of GNUnet.
     Copyright (C) 2013-2014, 2018 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/conversation/gnunet-conversation-gtk_zones.c
 * @brief manages the widget which shows the zones (to select
 *        which one will be used to populate the address book)
 * @author yids
 * @author hark
 * @author Christian Grothoff
 */
#include "gnunet-conversation-gtk.h"
#include "gnunet-conversation-gtk_zones.h"


/**
 * Columns in the #zone_liststore.
 */
enum ZoneListstoreValues
{
  /**
   * Human-readable name of the ego.
   */
  ZONE_LS_NAME = 0,

  /**
   * Handel to the ego (of type `struct GNUNET_IDENTITY_Ego *ego`).
   */
  ZONE_LS_EGO = 1
};


/**
 * Handle to identity service.
 */
static struct GNUNET_IDENTITY_Handle *id;

/**
 * list of zones
 */
static GtkListStore *zone_liststore;

/**
 * Ego to select by default.
 */
static char *default_ego;


/**
 * Obtain the currently selected zone.
 *
 * @param name[out] set to the name of the ego
 * @return NULL if no ego is selected
 */
struct GNUNET_IDENTITY_Ego *
GCG_ZONES_get_selected_zone (const char **name)
{
  struct GNUNET_IDENTITY_Ego *ego;
  GtkTreeIter iter;
  GtkComboBox *cb;

  cb = GTK_COMBO_BOX (GCG_get_main_window_object (
    "gnunet_conversation_gtk_contacts_zone_combobox"));
  if (! gtk_combo_box_get_active_iter (cb, &iter))
  {
    *name = NULL;
    return NULL;
  }
  gtk_tree_model_get (GTK_TREE_MODEL (zone_liststore),
                      &iter,
                      ZONE_LS_EGO,
                      &ego,
                      ZONE_LS_NAME,
                      name,
                      -1);
  return ego;
}


/**
 * Function called by identity service with information about zones.
 *
 * @param cls NULL
 * @param ego ego handle for the zone
 * @param ctx unused
 * @param name name of the zone
 */
static void
identity_cb (void *cls,
             struct GNUNET_IDENTITY_Ego *ego,
             void **ctx,
             const char *name)
{
  GtkTreeIter iter;
  GtkTreeIter iter2;
  GtkTreeRowReference *rr;
  GtkTreePath *path;
  GtkComboBox *cb;

  if (NULL == ctx)
  {
    /* end of initial iteration, ignore */
    return;
  }
  rr = *ctx;
  if (NULL == rr)
  {
    /* new identity */
    GNUNET_assert (NULL != name);
    gtk_list_store_insert_with_values (zone_liststore,
                                       &iter,
                                       -1,
                                       ZONE_LS_NAME,
                                       name,
                                       ZONE_LS_EGO,
                                       ego,
                                       -1);
    cb = GTK_COMBO_BOX (GCG_get_main_window_object (
      "gnunet_conversation_gtk_contacts_zone_combobox"));
    if ((! gtk_combo_box_get_active_iter (cb, &iter2)) &&
        ((NULL == default_ego) || (0 == strcmp (name, default_ego))))
    {
      /* found an ego (or the ego) that we were supposed to use by
         default, select it! */
      gtk_combo_box_set_active_iter (cb, &iter);
    }
    path = gtk_tree_model_get_path (GTK_TREE_MODEL (zone_liststore), &iter);
    rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (zone_liststore), path);
    gtk_tree_path_free (path);
    *ctx = rr;
    return;
  }
  /* existing ego, locate and execute rename/delete */
  path = gtk_tree_row_reference_get_path (rr);
  GNUNET_assert (
    gtk_tree_model_get_iter (GTK_TREE_MODEL (zone_liststore), &iter, path));
  gtk_tree_path_free (path);
  if (NULL == name)
  {
    /* deletion operation */
    gtk_tree_row_reference_free (rr);
    *ctx = NULL;
    gtk_list_store_remove (zone_liststore, &iter);
    return;
  }
  /* rename operation */
  gtk_list_store_set (zone_liststore, &iter, ZONE_LS_NAME, &name, -1);
}


/**
 * Initialize the zones list
 *
 * @param ego_name default ego to pre-select
 */
void
GCG_ZONES_init (const char *ego_name)
{
  if (NULL != ego_name)
    default_ego = GNUNET_strdup (ego_name);
  zone_liststore = GTK_LIST_STORE (GCG_get_main_window_object (
    "gnunet_conversation_gtk_contacts_zone_liststore"));
  id = GNUNET_IDENTITY_connect (GCG_get_configuration (), &identity_cb, NULL);
}


/**
 * Shutdown the zone list
 */
void
GCG_ZONES_shutdown ()
{
  if (NULL != id)
  {
    GNUNET_IDENTITY_disconnect (id);
    id = NULL;
  }
  if (NULL != default_ego)
  {
    GNUNET_free (default_ego);
    default_ego = NULL;
  }
}

/* end of gnunet-conversation-gtk_zones.c */
