#ifndef _ed2k_gui_core_conn_included_
#define _ed2k_gui_core_conn_included_

#include <glib-object.h>

#define GUI_TYPE_CORE_CONN            (gui_core_conn_get_type())
#define GUI_CORE_CONN(obj)            (G_TYPE_CHECK_INSTANCE_CAST (obj, GUI_TYPE_CORE_CONN, GuiCoreConn))
#define GUI_CORE_CONN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST (klass, GUI_TYPE_CORE_CONN, GuiCoreConnClass))
#define GUI_IS_CORE_CONN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE (obj, GUI_TYPE_CORE_CONN))
#define GUI_IS_CORE_CONN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GUI_TYPE_CORE_CONN))

enum
{
 CONN_STATUS_NONE = 0,
 CONN_STATUS_CONNECTING,                /* We are trying to connect                                   */
 CONN_STATUS_AUTHENTICATING,            /* We are trying to log in (user/pass)                        */
 CONN_STATUS_COMMUNICATING,             /* We are logged in                                           */
 CONN_STATUS_CLOSED_DELIBERATELY,       /* We've closed the connection deliberately                   */
 CONN_STATUS_CLOSED_UNEXPECTEDLY,       /* The connection broke unexpectedly                          */
 CONN_STATUS_CLOSED_TIMEOUT,            /* The connection timed out (no read for X seconds)           */
 CONN_STATUS_CLOSED_TIMEOUT_NO_DATA,    /* The connection timed out and we've never received any data */
} ;


typedef struct _CoreOptions        CoreOptions;
typedef struct _GuiCoreConn        GuiCoreConn;
typedef struct _GuiCoreConnClass   GuiCoreConnClass;
typedef struct _GuiCoreConnPrivate GuiCoreConnPrivate;


struct _CoreOptions
{
	gfloat    max_dl_speed;
	gfloat    max_ul_speed;
	gfloat    line_down_speed;

	guint     clientport;
	guint     adminport;

	guint     maxconns;

	guint     version;
	guint     baseversion;
	guint     builddate;
	guint     pid;

	gchar    *incomingdir;
	gchar    *tempdir;

	gchar    *nick;

	gboolean  always_connected; /* eDonkey */
	gboolean  autoremove_dead;  /* eDonkey */

	gboolean  allow_pm;
	gboolean  save_corrupted;

	guint     num_gotten_opts;
} ;



struct _GuiCoreConn
{
	GObject object;
	GuiCoreConnPrivate *priv;
};

struct _GuiCoreConnClass
{
	GObjectClass parent_class;

	/* signals */

	void (*connected)    (GuiCoreConn *conn);

	void (*disconnected) (GuiCoreConn *conn);

	void (*core_conn_status) (GuiCoreConn *conn, guint status);

	void (*overnet_status) (GuiCoreConn *conn, 
	                        const gchar *on_idstr,
	                        const gchar *on_fwstatus);

	void (*hybrid_status) (GuiCoreConn *conn, 
	                       const gchar *on_idstr,
	                       const gchar *on_fwstatus);

	void (*edonkey_status) (GuiCoreConn *conn, 
	                        guint        ed2kid,
	                        const gchar *ed2k_fwstatus);

	void (*core_options)   (GuiCoreConn *conn, const CoreOptions *opts);

	void (*remove_download)  (GuiCoreConn *conn, 
	                          gpointer     hash,
	                          guint        cancelled);

	void (*new_download)     (GuiCoreConn   *conn, 
	                          gconstpointer  hash,
	                          const gchar   *name,
	                          guint          size,
	                          guint          prio,
	                          const gchar   *tmpfn,
	                          guint          id);

	void (*download_status)  (GuiCoreConn *conn, 
	                          guint  id,
	                          guint  status,
	                          gfloat speed,
	                          guint  transfered,
	                          guint  availability,
	                          guint  sources);

	void (*download_gaps)          (GuiCoreConn    *conn, 
	                                gconstpointer   hash,
	                                guint           id,
	                                guint           num,
	                                const guint    *startarr,
	                                const guint    *endarr,
	                                const guint    *statusarr);

	void (*shared_file_hashing)    (GuiCoreConn *conn, 
	                                const gchar *fn);

	void (*shared_dirs)            (GuiCoreConn  *conn, 
	                                guint         num,
	                                const gchar **dirname_arr);

	void (*shared_files)           (GuiCoreConn   *conn, 
	                                guint          num,
	                                const guint8 **hash_arr,
	                                const gchar  **name_arr,
	                                guint         *size_arr,
	                                const gchar  **format_arr,
	                                const gchar  **type_arr,
	                                guint         *prio_arr);

	void (*upload_status)          (GuiCoreConn *conn, 
	                                guint   num,
	                                gfloat *speed_arr,
	                                guint  *slotid_arr);

	void (*remove_upload_slot)     (GuiCoreConn *conn, 
	                                guint        slotid);

	void (*change_upload_slot)     (GuiCoreConn   *conn, 
	                                guint          slotid,
	                                const gchar   *filename,
	                                const guint8  *filehash,
	                                const gchar   *username,
	                                const guint8  *userhash);

	void (*status_message)         (GuiCoreConn *conn, 
	                                const gchar *txt);

 	/* status_message_unfiltered: For advanced commands.
	 *  Will be called with a NULL argument if we
	 *  receive a non-status message */
	void (*status_message_unfiltered) (GuiCoreConn *conn, 
	                                   const gchar *msg);

	void (*error_message)          (GuiCoreConn *conn, 
	                                const gchar *txt);

	void (*client_stats)           (GuiCoreConn *conn, 
	                                gfloat space_tmp,
	                                gfloat space_in,
	                                gfloat space_needed,
	                                guint  clientid,
	                                guint  connections,
	                                guint  num_on_queue);

	void (*speed_total)            (GuiCoreConn *conn, 
	                                gfloat  dl_speed,
	                                gfloat  ul_speed);

	void (*server_connect_failed)  (GuiCoreConn *conn, 
	                                const gchar *serverstr);

	void (*server_connected)       (GuiCoreConn *conn, 
	                                const gchar *serverstr);

	void (*server_disconnected)    (GuiCoreConn *conn);

	void (*server_list) (GuiCoreConn *conn, 
	                     guint   num,
	                     guint  *ip_arr,
	                     guint  *port_arr,
	                     gchar  *name_arr,
	                     gchar **desc_arr,
	                     guint **users_arr,
	                     guint  *files_arr,
	                     guint  *ping_arr,
	                     guint  *pref_arr);

	void (*server_stats) (GuiCoreConn *conn, 
	                      guint files,
	                      guint users);

	void (*search_extended) (GuiCoreConn *conn, 
	                         const gchar *servername);

	void (*search_results) (GuiCoreConn *conn, 
	                        gboolean       from_main_server,
	                        gboolean       more,
	                        guint          num,
	                        const guint8 **hash_arr,
	                        const guint8 **servicehash_arr,
	                        const guint   *size_arr,
	                        const guint   *avail_arr,
	                        const gchar  **name_arr,
	                        const gchar  **type_arr,
	                        const gchar  **format_arr,
	                        const gchar  **artist_arr,
	                        const gchar  **album_arr,
	                        const gchar  **title_arr,
	                        const gchar  **length_arr,
	                        const guint   *bitrate_arr,
	                        const gchar  **codec_arr);

};


/* global variables */

extern GuiCoreConn *core;



/* function prototypes */

GType               gui_core_conn_get_type         (void);

GuiCoreConn        *gui_core_conn_new              (void);

gboolean            gui_core_conn_connect          (GuiCoreConn *conn,
                                                    const gchar *host,
                                                    guint        port,
                                                    const gchar *usr,
                                                    const gchar *pass);

gboolean            gui_core_conn_reconnect        (GuiCoreConn *conn);

void                gui_core_conn_disconnect       (GuiCoreConn *conn);

gboolean            gui_core_conn_is_overnet       (GuiCoreConn *conn);

gboolean            gui_core_conn_is_edonkey       (GuiCoreConn *conn);

gboolean            gui_core_conn_is_hybrid        (GuiCoreConn *conn);

gboolean            gui_core_conn_is_local         (GuiCoreConn *conn);

gboolean            gui_core_conn_is_alive         (GuiCoreConn *conn);

const CoreOptions  *gui_core_conn_get_core_options (GuiCoreConn *conn);

void                gui_core_conn_dump_message_stats (void);

/* guint               gui_core_conn_get_base_version (GuiCoreConn *conn); */

gboolean            gui_core_conn_is_newer_than    (GuiCoreConn *conn, guint day, guint month, guint year);

const gchar        *gui_core_conn_get_host         (GuiCoreConn *conn, guint *port);

/* --------------------------------------------------------------------------------- */

void                gui_core_connection_init       (void);

/* --------------------------------------------------------------------------------- */

void                gui_core_conn_send_get_serverlist (GuiCoreConn *conn);

void                gui_core_conn_send_connect_to_server (GuiCoreConn *conn, guint32 ip, guint16 port);

void                gui_core_conn_send_connect_to_any_server (GuiCoreConn *conn);

void                gui_core_conn_send_disconnect_from_server (GuiCoreConn *conn);

void                gui_core_conn_send_add_server (GuiCoreConn *conn, guint32 ip, guint16 port);

void                gui_core_conn_send_remove_server (GuiCoreConn *conn, guint32 ip, guint16 port);

void                gui_core_conn_send_extended_search (GuiCoreConn *conn);

void                gui_core_conn_send_more_search (GuiCoreConn *conn);

void                gui_core_conn_send_get_shared_dirs (GuiCoreConn *conn);

void                gui_core_conn_send_get_shared_files (GuiCoreConn *conn);

void                gui_core_conn_send_get_options (GuiCoreConn *conn);

void                gui_core_conn_send_get_download_gaps (GuiCoreConn *conn, const guint8 *hash);

void                gui_core_conn_send_cancel_download (GuiCoreConn *conn, const guint8 *hash);

void                gui_core_conn_send_command_with_data (GuiCoreConn  *conn,
                                                          guint8        cmd,
                                                          const guint8 *buf,
                                                          gsize         buflen);

void                gui_core_conn_send_server_command    (GuiCoreConn *conn,
                                                          guint8       cmd,
                                                          guint32      ip,
                                                          guint        port);

void                gui_core_conn_send_login             (GuiCoreConn  *conn,
                                                          const gchar  *user,
                                                          const gchar  *pass);

void                gui_core_conn_send_logout            (GuiCoreConn  *conn);

void                gui_core_conn_send_set_server_pref   (GuiCoreConn *conn,
                                                          guint32      ip,
                                                          guint        port,
                                                          guint8       newpref);

void                gui_core_conn_send_simple_search     (GuiCoreConn  *conn,
                                                          const gchar  *str);
/*
void                gui_core_conn_send_type_search       (GuiCoreConn  *conn,
                                                          const gchar  *str,
                                                          const gchar  *type,
                                                          guint32       i_minbitrate);

void                gui_core_conn_send_type_search_with_extra_options (GuiCoreConn  *conn,
                                                                       const gchar  *str,
                                                                       const gchar  *type,
                                                                       guint32       i_minsize,
                                                                       guint32       i_maxsize,
                                                                       guint32       i_minavail,
                                                                       guint32       i_minbitrate);

void                gui_core_conn_send_search_with_extra_options (GuiCoreConn  *conn,
                                                                  const gchar  *str,
                                                                  guint32       i_minsize,
                                                                  guint32       i_maxsize,
                                                                  guint32       i_minavail);
*/

void                gui_core_conn_send_new_download      (GuiCoreConn   *conn,
                                                          const guint8  *hash,
                                                          guint32        size,
                                                          const gchar   *fn);

void                gui_core_conn_send_pause_download    (GuiCoreConn *conn, const guint8 *hash);

void                gui_core_conn_send_resume_download   (GuiCoreConn *conn, const guint8 *hash);


void                gui_core_conn_send_unshare_dir_no    (GuiCoreConn *conn, guint dir_no);

void                gui_core_conn_send_add_shared_dir    (GuiCoreConn *conn, const gchar *dir);

void                gui_core_conn_send_add_shared_dir_structure (GuiCoreConn *conn, const gchar *dir);

void                gui_core_conn_send_set_nickname        (GuiCoreConn *conn, const gchar *nick);

void                gui_core_conn_send_set_incoming        (GuiCoreConn *conn, const gchar *dir);

void                gui_core_conn_send_set_temp            (GuiCoreConn *conn, const gchar *dir);

void                gui_core_conn_send_command             (GuiCoreConn *conn, const gchar *cmdstr);

void                gui_core_conn_send_set_port            (GuiCoreConn *conn, guint16 port);

void                gui_core_conn_send_set_admin_port      (GuiCoreConn *conn, guint16 aport);

void                gui_core_conn_send_set_max_speeds      (GuiCoreConn *conn, gfloat dlmax, gfloat ulmax);

void                gui_core_conn_send_set_max_connections (GuiCoreConn *conn, guint maxcon);

void                gui_core_conn_send_auto_connect        (GuiCoreConn *conn, gboolean autoconnectON);

void                gui_core_conn_send_save_corrupted      (GuiCoreConn *conn, gboolean savecorruptedON);

void                gui_core_conn_send_auto_server_remove  (GuiCoreConn *conn, gboolean autoserverremoveON);

void                gui_core_conn_send_set_download_priority (GuiCoreConn *conn, const guint8 *hash, guint8 priority);

void                gui_core_conn_send_set_upload_priority   (GuiCoreConn *conn, const guint8 *hash, guint newprio);

void                gui_core_conn_send_get_stats             (GuiCoreConn *conn);

void                gui_core_conn_send_get_overnet_contacts  (GuiCoreConn *conn);


#endif


