/*
     This file is part of GNUnet
     Copyright (C) 2005, 2006, 2010, 2012 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/fs/gnunet-fs-gtk_open-uri.c
 * @author Christian Grothoff
 * @brief code for the 'Open URI' dialog.
 *
 * TODO:
 * - automatically populate dialog from clipboard?
 */
#include "gnunet-fs-gtk_common.h"
#include "gnunet-fs-gtk_download-save-as.h"
#include "gnunet-fs-gtk_open-uri.h"
#include "gnunet-fs-gtk.h"
#include <gdk/gdkkeysyms.h>


/**
 * Handle a URI string by running the appropriate action.
 *
 * @param uris string we got
 * @param anonymity_level anonymity level to use
 * @return #GNUNET_OK on success, #GNUNET_NO if the URI type is not supported, #GNUNET_SYSERR if we failed to
 *         parse the URI
 */
int
GNUNET_FS_GTK_handle_uri_string (const char *uris, guint anonymity_level)
{
  struct GNUNET_FS_Uri *uri;
  char *perr;

  uri = GNUNET_FS_uri_parse (uris, &perr);
  if (uri == NULL)
  {
    GNUNET_free (perr);
    return GNUNET_SYSERR;
  }
  GNUNET_FS_GTK_handle_uri (uri, anonymity_level);
  return GNUNET_OK;
}


/**
 * User selected "execute" in the open-URI dialog.
 *
 * @param button the execute button
 * @param user_data the `GtkBuilder` of the URI dialog
 */
void
GNUNET_GTK_open_url_dialog_execute_button_clicked_cb (GtkButton *button,
                                                      gpointer user_data)
{
  GtkBuilder *builder = GTK_BUILDER (user_data);
  GtkWidget *dialog;
  GtkTextBuffer *tb;
  GtkTextIter ti_start;
  GtkTextIter ti_end;
  guint anonymity_level;
  char *uris;

  dialog =
    GTK_WIDGET (gtk_builder_get_object (builder, "GNUNET_GTK_open_url_window"));
  tb = GTK_TEXT_BUFFER (
    gtk_builder_get_object (builder,
                            "GNUNET_GTK_open_url_dialog_url_textview_buffer"));
  gtk_text_buffer_get_iter_at_offset (tb, &ti_start, 0);
  gtk_text_buffer_get_iter_at_offset (tb, &ti_end, -1);

  uris = gtk_text_buffer_get_text (tb, &ti_start, &ti_end, FALSE);
  if (! GNUNET_GTK_get_selected_anonymity_level (
        builder,
        "GNUNET_GTK_open_url_dialog_anonymity_combobox",
        &anonymity_level))
  {
    GNUNET_break (0);
    gtk_widget_destroy (dialog);
    g_object_unref (G_OBJECT (builder));
    return;
  }
  GNUNET_break (GNUNET_OK ==
                GNUNET_FS_GTK_handle_uri_string (uris, anonymity_level));
  g_free (uris);
  gtk_widget_destroy (dialog);
  g_object_unref (G_OBJECT (builder));
}


/**
 * User selected "cancel" in the open-URI dialog.
 *
 * @param button the cancel button
 * @param user_data the 'GtkBuilder' of the URI dialog
 */
void
GNUNET_GTK_open_url_dialog_cancel_button_clicked_cb (GtkButton *button,
                                                     gpointer user_data)
{
  GtkBuilder *builder = GTK_BUILDER (user_data);
  GtkWidget *dialog;

  dialog =
    GTK_WIDGET (gtk_builder_get_object (builder, "GNUNET_GTK_open_url_window"));
  gtk_widget_destroy (GTK_WIDGET (dialog));
  g_object_unref (G_OBJECT (builder));
}


/**
 * User closed the window of the open-URI dialog.
 *
 * @param widget the window
 * @param event the deletion event
 * @param user_data the 'GtkBuilder' of the URI dialog
 * @return FALSE (allow destruction)
 */
gboolean
GNUNET_GTK_open_url_window_delete_event_cb (GtkWidget *widget,
                                            GdkEvent *event,
                                            gpointer user_data)
{
  GtkBuilder *builder = GTK_BUILDER (user_data);

  g_object_unref (G_OBJECT (builder));
  return FALSE;
}


/**
 * User pushed a key in the open-URI dialog, check if we currently
 * have valid URI and if the key was 'RETURN', run the action.
 *
 * @param widget the window
 * @param event the deletion event
 * @param user_data the 'GtkBuilder' of the URI dialog
 */
gboolean
GNUNET_GTK_open_url_dialog_url_textview_key_press_event_cb (GtkWidget *widget,
                                                            GdkEventKey *event,
                                                            gpointer user_data)
{
  GtkBuilder *builder = GTK_BUILDER (user_data);
  GtkWidget *execute;

  if (event->keyval != GDK_KEY_Return)
    return FALSE;
  execute = GTK_WIDGET (
    gtk_builder_get_object (builder,
                            "GNUNET_GTK_open_url_dialog_execute_button"));
  if (gtk_widget_get_sensitive (execute))
    GNUNET_GTK_open_url_dialog_execute_button_clicked_cb (GTK_BUTTON (execute),
                                                          user_data);
  return TRUE;
}


/**
 * User edited the URI of the open-URI dialog, check if it is currently
 * a valid URI and update the sensitivity of the 'execute' button accordingly.
 *
 * @param textbuffer the updated buffer
 * @param user_data the 'GtkBuilder' of the URI dialog
 */
void
GNUNET_GTK_open_url_dialog_url_textview_buffer_changed_cb (
  GtkTextBuffer *textbuffer,
  gpointer user_data)
{
  GtkBuilder *builder = GTK_BUILDER (user_data);
  struct GNUNET_FS_Uri *uri;
  GtkTextBuffer *tb;
  GtkTextIter ti_start;
  GtkTextIter ti_end;
  char *perr;
  char *uris;

  perr = NULL;
  tb = GTK_TEXT_BUFFER (
    gtk_builder_get_object (builder,
                            "GNUNET_GTK_open_url_dialog_url_textview_buffer"));
  gtk_text_buffer_get_iter_at_offset (tb, &ti_start, 0);
  gtk_text_buffer_get_iter_at_offset (tb, &ti_end, -1);
  uris = gtk_text_buffer_get_text (tb, &ti_start, &ti_end, FALSE);
  if (uris != NULL)
    uri = GNUNET_FS_uri_parse (uris, &perr);
  else
    uri = NULL;
  g_free (uris);
  gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (
                              builder,
                              "GNUNET_GTK_open_url_dialog_execute_button")),
                            (uri == NULL) ? FALSE : TRUE);
  if (uri != NULL)
    GNUNET_FS_uri_destroy (uri);
  GNUNET_free (perr);
}


/**
 * User selected "Open URI" in main window.
 *
 * @param dummy the menu entry
 * @param user_data unused
 */
void
GNUNET_GTK_main_menu_file_download_uri_activate_cb (GtkWidget *dummy,
                                                    gpointer user_data)
{
  GtkBuilder *builder;
  GtkWidget *dialog;
  GtkTextBuffer *tb;
  GtkTextIter ti_start;
  GtkTextIter ti_end;
  GtkWidget *toplevel;
  GtkComboBox *combo;

  builder =
    GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_open_url_dialog.glade", NULL);
  if (NULL == builder)
  {
    GNUNET_break (0);
    return;
  }
  dialog =
    GTK_WIDGET (gtk_builder_get_object (builder, "GNUNET_GTK_open_url_window"));
  tb = GTK_TEXT_BUFFER (
    gtk_builder_get_object (builder,
                            "GNUNET_GTK_open_url_dialog_url_textview_buffer"));
  gtk_text_buffer_get_iter_at_offset (tb, &ti_start, 0);
  gtk_text_buffer_get_iter_at_offset (tb, &ti_end, -1);
  gtk_text_buffer_delete (tb, &ti_start, &ti_end);

  /* FIXME-FEATURE: query the clipboard, maybe there's valid URI in there?
   * If so, get it. */
  combo = GTK_COMBO_BOX (
    gtk_builder_get_object (builder,
                            "GNUNET_GTK_open_url_dialog_anonymity_combobox"));
  gtk_combo_box_set_model (combo,
                           GNUNET_FS_GTK_get_anonymity_level_list_store ());
  toplevel = gtk_widget_get_toplevel (dummy);
  if (GTK_IS_WINDOW (toplevel))
    gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
  gtk_widget_show (dialog);
}


/* end of gnunet-fs-gtk_open-uri.c */
