/*
 *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
 *
 *  This program 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 2, or (at your option)
 *  any later version.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef GALEON_EMBED_H
#define GALEON_EMBED_H

#ifdef __cplusplus
extern "C" {
#endif

#include "galeon-embed-types.h"
#include "galeon-embed-event.h"
#include "galeon-encodings.h"

#include <glib-object.h>
#include <glib.h>
#include <gtk/gtkwidget.h>
	
typedef struct GaleonEmbedClass GaleonEmbedClass;

#define GALEON_EMBED_TYPE             (galeon_embed_get_type ())
#define GALEON_EMBED(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GALEON_EMBED_TYPE, GaleonEmbed))
#define GALEON_EMBED_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), GALEON_EMBED_TYPE, GaleonEmbedClass))
#define IS_GALEON_EMBED(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GALEON_EMBED_TYPE))
#define IS_GALEON_EMBED_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GALEON_EMBED_TYPE))
#define GALEON_EMBED_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GALEON_EMBED_TYPE, GaleonEmbedClass))

typedef struct _GaleonEmbed GaleonEmbed;

typedef enum
{
	EMBED_STATE_UNKNOWN = 0,
	EMBED_STATE_START = 1 << 0,
  	EMBED_STATE_REDIRECTING = 1 << 1,
  	EMBED_STATE_TRANSFERRING = 1 << 2,
	EMBED_STATE_NEGOTIATING = 1 << 3,
  	EMBED_STATE_STOP = 1 << 4,
  
  	EMBED_STATE_IS_REQUEST = 1 << 5,
  	EMBED_STATE_IS_DOCUMENT = 1 << 6,
  	EMBED_STATE_IS_NETWORK = 1 << 7,
 	EMBED_STATE_IS_WINDOW = 1 << 8
} EmbedState;

typedef enum
{
	EMBED_CLIPBOARD_CAP = 1 << 0,
	EMBED_COOKIES_CAP = 1 << 1,
	EMBED_LINKS_CAP = 1 << 2,
	EMBED_ZOOM_CAP = 1 << 3,
	EMBED_PRINT_CAP = 1 << 6,
	EMBED_FIND_CAP = 1 << 7,
	EMBED_SCROLL_CAP = 1 << 8,
	EMBED_SECURITY_CAP = 1 << 9,
	EMBED_CHARSET_CAP = 1 << 10,
	EMBED_SHISTORY_CAP = 1 << 11,
	EMBED_FINE_SCROLL_CAP = 1 << 12
} EmbedCapabilities;


typedef enum
{
	EMBED_RENDER_QUIRKS    = 1,
	EMBED_RENDER_STANDARDS = 2
} EmbedPageRenderMode;

typedef enum
{
	EMBED_SOURCE_NOT_CACHED    = 0,
	EMBED_SOURCE_DISK_CACHE    = 1,
	EMBED_SOURCE_MEMORY_CACHE  = 2,
	EMBED_SOURCE_UNKNOWN_CACHE = 3
} EmbedPageSource;

typedef struct
{
	char *content_type;
	char *encoding;
	char *referring_url;

	gint size;
	GTime expiration_time;
	GTime modification_time;

	EmbedPageRenderMode rendering_mode;
	EmbedPageSource page_source;

	char *cipher_name;
	char *cert_issuer_name;
	gint key_length;
	gint secret_key_length;

	/* lists of hashtables with gvalues */
	GList *metatags;    /* name, value */
	GList *images;      /* url, alt, title, width, height */
	GList *forms;       /* name, method, action */
	GList *links;       /* url, title, relation */
	GList *stylesheets; /* url, title */
} EmbedPageProperties;

typedef struct
{
	char *name;
	char *content;
} EmbedPageMetaTag;

typedef struct
{
	char *name;
	char *method;
	char *action;
} EmbedPageForm;

typedef struct
{
	char *url;
	char *title;
	char *rel;
} EmbedPageLink;

typedef struct
{
	char *url;
	char *alt;
	char *title;
	gint width;
	gint height;
} EmbedPageImage;

typedef enum
{
	EMBED_RELOAD_NORMAL = 1 << 1,
  	EMBED_RELOAD_FORCE  = 1 << 2,
	EMBED_RELOAD_FRAME  = 1 << 3
} EmbedReloadFlags;

typedef enum
{
        DISPLAY_AS_SOURCE = 1U,
        DISPLAY_NORMAL = 2U
} EmbedDisplayType;

typedef struct
{
        gboolean print_to_file;
        gchar *printer;
        gchar *file;
        gint paper;
        gdouble top_margin;
        gdouble bottom_margin;
        gdouble left_margin;
        gdouble right_margin;
        gint pages;
        gint from_page;
        gint to_page;
        gint frame_type;
        gint orientation;
        gboolean print_color;

         /* 
         * &T - title
         * &U - Document URL
         * &D - Date/Time
         * &P - Page Number
         * &PT - Page Number with total Number of Pages (example: 1 of 34)
         *
         * So, if headerLeftStr = "&T" the title and the document URL
         * will be printed out on the top left-hand side of each page.
         */
        gchar *header_left_string;
        gchar *header_center_string;
        gchar *header_right_string;
        gchar *footer_left_string;
        gchar *footer_center_string;
        gchar *footer_right_string;

	gboolean preview;
}
EmbedPrintInfo;

typedef enum
{
	PRINTPREVIEW_GOTO_PAGENUM = 0,
	PRINTPREVIEW_PREV_PAGE = 1,
	PRINTPREVIEW_NEXT_PAGE = 2,
	PRINTPREVIEW_HOME = 3,
	PRINTPREVIEW_END = 4
} EmbedPrintPreviewNavType;

typedef enum
{
	EMBED_SCROLL_UP,
	EMBED_SCROLL_DOWN,
	EMBED_SCROLL_LEFT,
	EMBED_SCROLL_RIGHT
} EmbedScrollDirection;

typedef enum
{
	STATE_IS_UNKNOWN,
	STATE_IS_INSECURE,
	STATE_IS_BROKEN,
	STATE_IS_SECURE_MED,
	STATE_IS_SECURE_LOW,
	STATE_IS_SECURE_HIGH
} EmbedSecurityLevel;

typedef enum
{
	STYLESHEET_NONE,      /* no stylesheet */
	STYLESHEET_BASIC,     /* no named stylesheets */
	STYLESHEET_NAMED,     /* Named stylesheet */
        STYLESHEET_USER_NONE, /* No User stylesheet */
        STYLESHEET_USER       /* User specified stylesheet */
} EmbedStyleSheetType;
                                                                                                                                              
typedef struct
{
	gchar *name;    /* stylesheet name */
	gpointer sheet; /* opaque pointer to the underlying sheet object */
	EmbedStyleSheetType type;
} EmbedStyleSheet;


struct GaleonEmbedClass
{
        GTypeInterface base_iface;

  	void (* link_message)    (GaleonEmbed *embed,
				  const char *link);
  	void (* js_status)       (GaleonEmbed *embed,
				  const char *status);
  	void (* location)        (GaleonEmbed *embed);
  	void (* title)           (GaleonEmbed *embed);
  	void (* progress)        (GaleonEmbed *embed, 
				  const char *uri,
                	          gint curprogress, 
				  gint maxprogress);
  	void (* net_state)       (GaleonEmbed *embed, 
				  const char *uri,
			          EmbedState state);
  	void (* new_window)      (GaleonEmbed *embed, 
			          GaleonEmbed **new_embed,
                                  EmbedChromeMask chromemask);
  	void (* visibility)      (GaleonEmbed *embed, 
			          gboolean visibility);
  	void (* destroy_brsr)    (GaleonEmbed *embed);
  	gint (* open_uri)        (GaleonEmbed *embed, 
			          const char *uri);
  	void (* size_to)         (GaleonEmbed *embed, 
			          gint width, 
			          gint height);
  	gint (* dom_mouse_click) (GaleonEmbed *embed, 
			          GaleonEmbedEvent *event);
	gint (* dom_mouse_down)  (GaleonEmbed *embed,
				  GaleonEmbedEvent *event);
	void (* security_change) (GaleonEmbed *embed, 
                                  EmbedSecurityLevel level);
	void (* zoom_change) 	 (GaleonEmbed *embed, 
                                  guint new_zoom);
	void (* favicon)	 (GaleonEmbed *embed,
			          const char *uri);

	void (* popupblocked)	 (GaleonEmbed *embed,
				  const char *uri);

	void (* contextmenu)	 (GaleonEmbed *embed,
			          GaleonEmbedEvent *event);

  	void (* net_stop)        (GaleonEmbed *embed);
  	void (* net_start)       (GaleonEmbed *embed);

	/* Methods  */
        void (* get_capabilities)          (GaleonEmbed *embed,
				            EmbedCapabilities *caps);
	gresult   (* load_url)             (GaleonEmbed *embed, 
					    const char *url);
	gresult   (* stop_load)            (GaleonEmbed *embed);
	gresult   (* can_go_back)          (GaleonEmbed *embed);
	gresult   (* can_go_forward)       (GaleonEmbed *embed);
	gresult   (* can_go_up)            (GaleonEmbed *embed);
	gresult   (* get_go_up_list)       (GaleonEmbed *embed, GSList **l);
	gresult   (* go_back)              (GaleonEmbed *embed);
	gresult   (* go_forward)           (GaleonEmbed *embed);
	gresult   (* go_up)                (GaleonEmbed *embed);
	gresult   (* render_data)          (GaleonEmbed *embed, 
					    const char *data,
					    guint32 len,
					    const char *base_uri, 
					    const char *mime_type);
	gresult   (* open_stream)          (GaleonEmbed *embed,
					    const char *base_uri,
					    const char *mime_type);
	gresult   (* append_data)          (GaleonEmbed *embed,
					    const char *data, 
					    guint32 len);
	gresult   (* close_stream)         (GaleonEmbed *embed);
	gresult   (* get_title)            (GaleonEmbed *embed,
					    char **title);
	gresult   (* get_location)         (GaleonEmbed *embed, 
				            gboolean toplevel,
				            gboolean requested,
				            char **location);
	gresult   (* reload)               (GaleonEmbed *embed, 
				       	    EmbedReloadFlags flags);
	gresult   (* copy_page)		   (GaleonEmbed *dest,
					    GaleonEmbed *source,
					    EmbedDisplayType display_type);
	gresult   (* grab_focus)           (GaleonEmbed *embed);
	gresult   (* get_link_tags)        (GaleonEmbed *embed,
					    const char *link_type,
					    GList **tags);
	gresult   (* zoom_set)             (GaleonEmbed *embed, 
					    int zoom, 
					    gboolean reflow);
	gresult   (* zoom_get)             (GaleonEmbed *embed,
				            int *zoom);
	gresult   (* selection_can_cut)    (GaleonEmbed *embed);
	gresult   (* selection_can_copy)   (GaleonEmbed *embed);
	gresult   (* can_paste)            (GaleonEmbed *embed);
	gresult   (* selection_cut)        (GaleonEmbed *embed);
	gresult   (* selection_copy)       (GaleonEmbed *embed);
	gresult   (* paste)                (GaleonEmbed *embed);
	gresult   (* select_all)           (GaleonEmbed *embed);
	gresult   (* shistory_count)	   (GaleonEmbed *embed,
					    int *count);
	gresult   (* shistory_get_nth)     (GaleonEmbed *embed, 
				            int nth,
				            gboolean is_relative,
				            char **url,
				            char **title);
	gresult   (* shistory_get_pos)     (GaleonEmbed *embed,
				            int *pos);
	gresult   (* shistory_go_nth)      (GaleonEmbed *embed, 
					    int nth);
	gboolean  (* shistory_copy)	   (GaleonEmbed *source,
					    GaleonEmbed *dest,
					    gboolean back_history,
					    gboolean forward_history,
					    gboolean set_current);
	gresult   (* shistory_clear)       (GaleonEmbed *embed);
	gresult   (* scroll)               (GaleonEmbed *embed, 
		  			    EmbedScrollDirection direction);
	gresult	  (* fine_scroll)	   (GaleonEmbed *embed, 
					    int horiz, int vert);
	gresult   (* get_security_level)   (GaleonEmbed *embed, 
					    EmbedSecurityLevel *level, 
					    char **description);
	gresult   (* find_next)            (GaleonEmbed *embed,
		  		            gboolean backwards);
	gresult   (* find_set_properties)  (GaleonEmbed *embed,
					    char *search_string,
					    gboolean case_sensitive,
					    gboolean wrap_around);

	gresult   (* print)                (GaleonEmbed *embed, 
				            EmbedPrintInfo *info);
	gresult	  (* print_preview_close)  (GaleonEmbed *embed);
	gresult   (* print_preview_num_pages)	(GaleonEmbed *embed,
						 gint *retNum);
	gresult   (* print_preview_navigate)	(GaleonEmbed *embed,
						 EmbedPrintPreviewNavType navType,
						 gint pageNum);
	gresult   (* set_encoding)          (GaleonEmbed *embed,
					    const char *charset);
	gresult   (* get_encoding_info)	    (GaleonEmbed *embed,
					     GaleonEncodingPageInfo **info);

	gresult	  (* get_page_properties)  (GaleonEmbed *embed,
					    EmbedPageProperties **retProperties);

	gresult   (* show_page_certificate)  (GaleonEmbed *embed);

	gresult   (* get_stylesheets)	   (GaleonEmbed *embed,
					    GList **retSheets);
	gresult   (* get_selected_stylesheet)   (GaleonEmbed *embed,
						 EmbedStyleSheet **retSheet);
	gresult   (* set_stylesheet)	   (GaleonEmbed *embed,
					    EmbedStyleSheet *sheet);
	gresult   (* apply_user_stylesheet)  (GaleonEmbed *embed,
					      const gchar *sheetfile,
					      EmbedStyleSheet **retSheet);
	gresult   (* remove_user_stylesheet)   (GaleonEmbed *embed,
						EmbedStyleSheet *sheet);
	gresult   (* has_modified_forms)       (GaleonEmbed *embed);

	gresult   (* can_view_source)          (GaleonEmbed *embed);
};	
	
GType         galeon_embed_get_type             (void);

/* Base */

GaleonEmbed  *galeon_embed_new                  (GObject *shell);

void          galeon_embed_get_capabilities     (GaleonEmbed *embed,
						 EmbedCapabilities *caps);

gresult       galeon_embed_load_url             (GaleonEmbed *embed, 
					         const char *url);

gresult       galeon_embed_stop_load            (GaleonEmbed *embed);

gresult       galeon_embed_can_go_back          (GaleonEmbed *embed);

gresult       galeon_embed_can_go_forward       (GaleonEmbed *embed);

gresult       galeon_embed_can_go_up            (GaleonEmbed *embed);

gresult       galeon_embed_get_go_up_list       (GaleonEmbed *embed, GSList **l);

gresult       galeon_embed_go_back              (GaleonEmbed *embed);

gresult       galeon_embed_go_forward           (GaleonEmbed *embed);

gresult       galeon_embed_go_up                (GaleonEmbed *embed);

gresult       galeon_embed_render_data          (GaleonEmbed *embed, 
					         const char *data,
					         guint32 len,
					         const char *base_uri, 
					         const char *mime_type);

gresult       galeon_embed_open_stream          (GaleonEmbed *embed,
					         const char *base_uri,
					         const char *mime_type);

gresult       galeon_embed_append_data          (GaleonEmbed *embed,
					         const char *data, 
						 guint32 len);

gresult       galeon_embed_close_stream         (GaleonEmbed *embed);

gresult       galeon_embed_get_title            (GaleonEmbed *embed,
						 char **title);

gresult       galeon_embed_get_location         (GaleonEmbed *embed, 
						 gboolean toplevel,
						 gboolean requested,
						 char **location);

gresult       galeon_embed_reload               (GaleonEmbed *embed, 
				       	         EmbedReloadFlags flags);

gresult	      galeon_embed_copy_page		(GaleonEmbed *dest,
						 GaleonEmbed *source,
						 EmbedDisplayType display_type);

gresult       galeon_embed_grab_focus           (GaleonEmbed *embed);

gresult       galeon_embed_can_view_source      (GaleonEmbed *embed);

/* Link */
gresult       galeon_embed_get_favicon_location (GaleonEmbed *embed,
						 char **url);

gresult       galeon_embed_get_link_tags        (GaleonEmbed *embed,
						 const char *link_type,
					         GList **tags);

/* Zoom */
gresult       galeon_embed_zoom_set             (GaleonEmbed *embed, 
					         int zoom, 
					         gboolean reflow);

gresult       galeon_embed_zoom_get             (GaleonEmbed *embed,
						 int *zoom);

/* Clipboard */
gresult       galeon_embed_selection_can_cut    (GaleonEmbed *embed);

gresult       galeon_embed_selection_can_copy   (GaleonEmbed *embed);

gresult       galeon_embed_can_paste            (GaleonEmbed *embed);

gresult       galeon_embed_selection_cut        (GaleonEmbed *embed);

gresult       galeon_embed_selection_copy       (GaleonEmbed *embed);

gresult       galeon_embed_paste                (GaleonEmbed *embed);

gresult       galeon_embed_select_all           (GaleonEmbed *embed);

/* Session history */
gresult       galeon_embed_shistory_count       (GaleonEmbed *embed,
						 int *count);

gresult       galeon_embed_shistory_get_nth     (GaleonEmbed *embed, 
						 int nth,
						 gboolean is_relative,
						 char **url,
						 char **title);

gresult       galeon_embed_shistory_get_pos     (GaleonEmbed *embed,
						 int *pos);

gresult       galeon_embed_shistory_go_nth      (GaleonEmbed *embed, 
						 int nth);

gboolean      galeon_embed_shistory_copy	(GaleonEmbed *source,
						 GaleonEmbed *dest,
						 gboolean back_history,
						 gboolean forward_history,
						 gboolean set_current);

gresult       galeon_embed_shistory_clear	(GaleonEmbed *embed);

/* Utils */

gresult       galeon_embed_scroll               (GaleonEmbed *embed, 
		  			         EmbedScrollDirection direction);

gresult       galeon_embed_fine_scroll          (GaleonEmbed *embed, 
		  			         int horiz, int vert);

gresult       galeon_embed_get_security_level   (GaleonEmbed *embed, 
						 EmbedSecurityLevel *level, 
						 char **description);

gresult       galeon_embed_find_next            (GaleonEmbed *embed, 
						 gboolean backwards);

gresult       galeon_embed_find_set_properties (GaleonEmbed *embed, 
						char *search_string,
						gboolean case_sensitive,
						gboolean wrap_around);

gresult       galeon_embed_set_encoding         (GaleonEmbed *embed,
					         const char *charset);
gresult       galeon_embed_get_encoding_info    (GaleonEmbed *embed,
						 GaleonEncodingPageInfo **info);

gresult       galeon_embed_has_modified_forms   (GaleonEmbed *embed);
/* Printing */

gresult       galeon_embed_print                (GaleonEmbed *embed, 
						 EmbedPrintInfo *info);

gresult	      galeon_embed_print_preview_close  (GaleonEmbed *embed);

gresult       galeon_embed_print_preview_num_pages	(GaleonEmbed *embed,
							 gint *retNum);

gresult       galeon_embed_print_preview_navigate	(GaleonEmbed *embed,
							 EmbedPrintPreviewNavType navType,
							 gint pageNum);

gresult	      galeon_embed_get_page_properties		(GaleonEmbed *embed,
							 EmbedPageProperties **retProperties);

gresult       galeon_embed_show_page_certificate        (GaleonEmbed *embed);
							 
gresult   galeon_embed_get_stylesheets		(GaleonEmbed *embed,
						 GList **retSheets);
gresult   galeon_embed_get_selected_stylesheet	(GaleonEmbed *embed,
						 EmbedStyleSheet **retSheet);
gresult   galeon_embed_set_stylesheet		(GaleonEmbed *embed,
						 EmbedStyleSheet *sheet);
gresult   galeon_embed_apply_user_stylesheet	(GaleonEmbed *embed,
						 const gchar *sheetfile,
						 EmbedStyleSheet **retSheet);
gresult   galeon_embed_remove_user_stylesheet	(GaleonEmbed *embed,
						 EmbedStyleSheet *sheet);

/* helper functions */
gboolean  galeon_embed_stylesheet_compare	(EmbedStyleSheet *ess1, EmbedStyleSheet *ess2);
void	  galeon_embed_stylesheet_free		(EmbedStyleSheet *ess);
void	  galeon_embed_stylesheet_list_free	(GList *l);


#ifdef __cplusplus
}
#endif
#endif
