/*
     This file is part of GNUnet.
     Copyright (C) 2010 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_event-handler.h
 * @brief Main event handler for file-sharing
 * @author Christian Grothoff
 */
#ifndef GNUNET_FS_GTK_EVENT_HANDLER_H
#define GNUNET_FS_GTK_EVENT_HANDLER_H

#include "gnunet-fs-gtk_common.h"
#include "gnunet-fs-gtk.h"

/**
 * State we keep for each (search) result entry in the
 * tree view of a search tab.
 */
struct SearchResult;


/**
 * Context we keep for a search tab.
 */
struct SearchTab
{
  /**
   * This is a doubly-linked list.
   */
  struct SearchTab *next;

  /**
   * This is a doubly-linked list.
   */
  struct SearchTab *prev;

  /**
   * Set in case this is an inner search, otherwise NULL.
   */
  struct SearchResult *parent;

  /**
   * Handle for this search with FS library.
   */
  struct GNUNET_FS_SearchContext *sc;

  /**
   * Text of the search query.
   */
  char *query_txt;

  /**
   * GtkBuilder object for the search tab.
   */
  GtkBuilder *builder;

  /**
   * Frame instance of the search tab.
   */
  GtkWidget *frame;

  /**
   * The widget representing this search in the tab bar (not
   * a GtkLabel, contains the actual label and the buttons).
   */
  GtkWidget *tab_label;

  /**
   * Button to stop and close the search.
   */
  GtkWidget *close_button;

  /**
   * Button to resume the search.
   */
  GtkWidget *play_button;

  /**
   * Button to pause the search.
   */
  GtkWidget *pause_button;

  /**
   * Textual label in the 'tab_label'
   */
  GtkLabel *label;

  /**
   * Tree store with the search results.
   */
  GtkTreeStore *ts;

  /**
   * Animation handle associated with the tree store.
   */
  struct GNUNET_GTK_AnimationTreeViewHandle *atv;

  /**
   * Number of results we got for this search.
   */
  unsigned int num_results;
};


/**
 * Information we keep for each download.
 */
struct DownloadEntry
{

  /**
   * Download entry of the parent (for recursive downloads),
   * NULL if we are either a top-level download (from URI,
   * from opened directory, orphaned from search or direct
   * search result).
   */
  struct DownloadEntry *pde;

  /**
   * Associated search result, or NULL if we don't belong
   * to a search directly (download entry).
   */
  struct SearchResult *sr;

  /**
   * Where in the download tab is this result?  References the
   * #downloads_treestore.
   */
  GtkTreeRowReference *rr;

  /**
   * FS handle to control the download, NULL if the download
   * has not yet started.
   */
  struct GNUNET_FS_DownloadContext *dc;

  /**
   * URI for the download, never NULL.
   */
  struct GNUNET_FS_Uri *uri;

  /**
   * Suggested (or selected) filename for the download on the
   * local disk, or NULL for on suggestion.
   */
  char *filename;

  /**
   * Is this a recursive download?
   */
  int is_recursive;

  /**
   * Is this a directory? (#GNUNET_SYSERR is used for "maybe"!)
   */
  int is_directory;

  /**
   * Desired (default) anonymity level.
   */
  uint32_t anonymity;

  /**
   * Has the download completed (or failed)?
   */
  int is_done;
};


/**
 * Information we keep for each search result entry in any search tab.
 * An entry like this is also generated for downloads by-URI.  Used to
 * quickly identify the tab and row of the result; stored in the
 * user-context of the FS library for the search result.
 */
struct SearchResult
{

  /**
   * If this search result has a manually-activated probe,
   * we keep it in the 'pr_head' list.
   */
  struct SearchResult *next;

  /**
   * If this search result has a manually-activated probe,
   * we keep it in the 'pr_head' list.
   */
  struct SearchResult *prev;

  /**
   * URI corresponding to the result.
   */
  struct GNUNET_FS_Uri *uri;

  /**
   * Meta data associated with the result.
   */
  struct GNUNET_FS_MetaData *meta;

  /**
   * Where in the tab is this result?
   */
  GtkTreeRowReference *rr;

  /**
   * Tab storing this result.
   */
  struct SearchTab *tab;

  /**
   * Search result for top-level results and
   * namespace-update results.
   */
  struct GNUNET_FS_SearchResult *result;

  /**
   * Associated search result we generated for probing;
   * thus, we need to run "GNUNET_FS_probe_cancel" on it
   * once we are done.  Only used if 'result' is NULL.
   */
  struct GNUNET_FS_SearchResult *probe;

  /**
   * Associated download, or NULL for none.
   */
  struct DownloadEntry *download;
};


/**
 * Head of search results with a manually-activated probe.
 */
extern struct SearchResult *pl_head;

/**
 * Tail of search results with a manually-activated probe.
 */
extern struct SearchResult *pl_tail;

/**
 * The "GNUNET_GTK_file_sharing_downloads_tree_store" with the
 * information about active (or completed) downloads.
 */
extern GtkTreeStore *downloads_treestore;


/**
 * Setup a new top-level entry in the URI/orphan tab.  If necessary, create
 * the URI tab first.
 *
 * @param anonymity anonymity level to use for probes
 * @param meta metadata for the new entry
 * @param uri URI for the new entry
 * @return the search result that was set up
 */
struct SearchResult *
GNUNET_GTK_add_to_uri_tab (uint32_t anonymity,
                           const struct GNUNET_FS_MetaData *meta,
                           const struct GNUNET_FS_Uri *uri);


/**
 * Add a search result to the given search tab.
 *
 * @param tab search tab to extend, never NULL
 * @param anonymity anonymity level to use for probes for this result
 * @param parent_rr reference to parent entry in search tab, NULL for normal
 *                  search results,
 * @param uri uri to add, can be NULL for top-level entry of a directory opened from disk
 *                        (in this case, we don't know the URI and should probably not
 *                         bother to calculate it)
 * @param meta metadata of the entry
 * @param result associated FS search result (can be NULL if this result
 *                        was part of a directory)
 * @param applicability_rank how relevant is the result
 * @return struct representing the search result (also stored in the tree
 *                model at 'iter')
 */
struct SearchResult *
GNUNET_GTK_add_search_result (struct SearchTab *tab,
                              uint32_t anonymity,
                              GtkTreeRowReference *parent_rr,
                              const struct GNUNET_FS_Uri *uri,
                              const struct GNUNET_FS_MetaData *meta,
                              struct GNUNET_FS_SearchResult *result,
                              uint32_t applicability_rank);


void
GNUNET_FS_GTK_set_item_downloaded_name (GtkTreeStore *ts,
                                        GtkTreeRowReference *rr,
                                        gchar *filename);

/**
 * Notification of FS to a client about the progress of an
 * operation.  Callbacks of this type will be used for uploads,
 * downloads and searches.  Some of the arguments depend a bit
 * in their meaning on the context in which the callback is used.
 *
 * @param cls closure
 * @param info details about the event, specifying the event type
 *        and various bits about the event
 * @return client-context (for the next progress call
 *         for this operation; should be set to NULL for
 *         SUSPEND and STOPPED events).  The value returned
 *         will be passed to future callbacks in the respective
 *         field in the GNUNET_FS_ProgressInfo struct.
 */
void *
GNUNET_GTK_fs_event_handler (void *cls,
                             const struct GNUNET_FS_ProgressInfo *info);


/**
 * Close the 'uri_tab'.
 */
void
GNUNET_FS_GTK_close_uri_tab_ ();


/**
 * Update the connection indicator widget.
 *
 * @param main_ctx context
 * @param connected TRUE if connected to arm, FALSE otherwise
 * @param tooltip new tooltip text
 */
void
GNUNET_FS_GTK_update_connection_indicator (
  struct GNUNET_GTK_MainWindowContext *main_ctx,
  gboolean connected,
  const gchar *tooltip);


#endif
/* end of gnunet-fs-gtk-event_handler.h */
