/*
 * Copyright (c) 2004 Nokia. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of Nokia nor the names of its contributors may be
 * used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <glib.h>
#include <glib-object.h>
#ifndef __WEBI_H__
#define __WEBI_H__

/**
 *  Gtk API for KHTML library.
 * 
 * Straight C API to use KHTML library.
 * work in progress, suggestions and patches welcome.
 *
 * currently coding standards follow gtk coding standards
 * except for indenting (gnu style)
 *
 * current documentation written in doxygen format, but
 * may be chaged to glib/gtk format.
 */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */



#include <gtk/gtk.h>


/*
 * Type checking and casting macros
 */
#define WEBI_TYPE_KHTML	(webi_get_type())
#define WEBI(obj)	G_TYPE_CHECK_INSTANCE_CAST((obj), webi_get_type(), Webi)
#define WEBI_CONST(obj)	G_TYPE_CHECK_INSTANCE_CAST((obj), webi_get_type(), Webi const)
#define WEBI_CLASS(klass)	G_TYPE_CHECK_CLASS_CAST((klass), webi_get_type(), WebiClass)
#define WEBI_IS_WEBI(obj)	G_TYPE_CHECK_INSTANCE_TYPE((obj), webi_get_type ())

#define WEBI_GET_CLASS(obj)	G_TYPE_INSTANCE_GET_CLASS((obj), webi_get_type(), WebiClass)

/* Private structure type */
typedef struct _WebiPrivate WebiPrivate;

/*
 * Main object structure
 */
typedef struct _Webi Webi;

struct _Webi {
  GtkBin __parent__;
  /*< private >*/
  WebiPrivate *_priv;
};

/** Structure used to set device type. */
typedef enum {
  WEBI_DEVICE_TYPE_SCREEN,
  WEBI_DEVICE_TYPE_HANDHELD,
  WEBI_DEVICE_TYPE_PRINTER
} WebiDeviceType;
  
/** Rendering engine settings structure
 *  Rendering engine settings structure. 
 */

typedef struct _WebiSettings WebiSettings;
struct _WebiSettings {
  gboolean javascript_enabled;
  gboolean java_enabled;
  gboolean plugins_enabled;
  gboolean autoload_images;
  gfloat minimum_font_size;
  gfloat default_font_size;
  gfloat default_fixed_font_size;
  const gchar* default_text_encoding; 
  const gchar* serif_font_family; 
  const gchar* sans_serif_font_family; 
  const gchar* fixed_font_family; 
  const gchar* standard_font_family; 
  const gchar* cursive_font_family; 
  const gchar* fantasy_font_family;

  /** Full url (including port) of the proxy to use. If NULL, empty (""), */
  const gchar* http_proxy;

  /** Rendering Mode */
  const WebiDeviceType device_type;
};

typedef struct _WebiLoadStatus WebiLoadStatus;

/** Type of the status message. */
typedef enum
{
  /** Report start loading a resource */
  WEBI_LOADING_START,
  /** Report progress in loading a resource */
  WEBI_LOADING,
  /** Report a successful resource load */
  WEBI_LOADING_COMPLETE,
  /** Report an error in resource loading. */
  WEBI_LOADING_ERROR  
} WebiStatus;

/** Status message. */
struct _WebiLoadStatus {
  /** Status of the loading process. */
  WebiStatus status;

  /** Number of files to download */
  guint files;

  /** Number of files received with Content-Length set*/
  guint filesWithSize;

  /** Number of files received */
  guint ready;

  /** Bytes available for resource. */
  guint size;

  /** Bytes received from resource. */
  guint received;

  /** Total size of the resources including those that didn't have
      Content-Length set. */
  guint totalSize;

  /** Bytes received total. */
  guint totalReceived;

  /** Error code. */
  gint statusCode;
};


  
typedef struct _WebiPromptArgs WebiPromptArgs;


/** Type of message prompt if message prompt was an alert (ok button), confirm (yes/no) or input (textfield, ok, cancel).
 */
typedef enum
{
  /** alert (ok button)*/
  WEBI_ALERT,
  /**confirm (yes/no)*/
  WEBI_CONFIRM,
  /**or input (textfield, ok, cancel) */
  WEBI_INPUT
} WebiPromptType;

/** Structure used to pass arguments of javascript prompt messages
 */
struct _WebiPromptArgs
{
  /*<public>*/
  
  /** Flag specifying if message prompt was an alert (ok button), confirm (yes/no) or
   *  input (textfield, ok, cancel). */
  WebiPromptType type;

  /** The prompt message*/
  const gchar* msg;
  
  /**  default input text.
   *  if type == WEBI_INPUT contains default input text to be shown in input field */
  const gchar* default_input; 

  /**  text entered in the prompt textfield
  *   should be set if type == WEBI_INPUT
   *  string will be deallocated by signaller with g_free().
   *  ie. there's an ownership change. */
  gchar* out_input;
  
  /** flag specifying if the button pressed was ok or cancel, yes or no
   * \TRUE means ok or yes
   * \FALSE means cancel or no
   */
  gboolean out_ok_pressed;    
};

typedef struct _WebiAuthArgs WebiAuthArgs;

/** Structure used to pass arguments of javascript prompt messages
 */
struct _WebiAuthArgs
{
  /*< public >*/
  /** realm of authentication */
  const gchar* realm;

  /** Out parameter containing username from user.
   *  string will be deallocated by caller with g_free().
   *  ie. there's an ownership change.*/
  gchar* out_username;

  /** Out parameter containing password from user.
   *  string will be deallocated by caller with g_free()
   *  ie. there's an ownership change. */
  
  gchar* out_password;
  
  /** flag specifying if the button pressed was ok or cancel
   * \TRUE means ok
   * \FALSE otherwise  */
  gboolean out_ok_pressed;    
};

typedef struct _WebiCookie WebiCookie;

/** Structure used to pass arguments of javascript prompt messages
 */
struct _WebiCookie
{
  /*<public>*/
  
  /** Whole cookie */
  const gchar* cookie;

  /** Cookie name */
  const gchar* name;

  /** Cookie value */
  const gchar* value;

  /* Cookie comment */
  const gchar* comment;

  /* Cookie domain */
  const gchar* domain;

  /* Cookie TTL */
  const gchar* maxAge;

  /* Cookie path */
  const gchar* path;

  /* Is cookie secure? */
  gboolean secure;

  /* Cookie-specification version. */
  gint version;

  /** Out argument - user accepted the cookie. */
  gboolean out_accept_cookie;
};

typedef struct _WebiWindowProperties WebiWindowProperties;

/** Structure used to pass arguments of javascript prompt messages
 */
struct _WebiWindowProperties
{
  /*<public>*/
  /* Are toolbars wisible. */
  gboolean toolbarsVisible;

  /* is status bar visible. */
  gboolean statusBarVisible;
  
  /* are scroll bars visible. */
  gboolean scrollbarsVisible;

  /* Is window resizable. */
  gboolean isResizable;
};

/** Structure used to get and set window size and content rectangle size. */
typedef enum {
  WEBI_CONTENT_SIZE,
  WEBI_WINDOW_SIZE
} WebiWindowSize;

/*
 * Class definition
 */
typedef struct _WebiClass WebiClass;
struct _WebiClass {
  GtkBinClass __parent__;
  
  /*signals*/
  
 
  /** Location change indication signal.
   * use \webi_get_location() to get the url string
   * @emited when current page changes.
   * @param self the engine which sent the signal   
   */
  void (* location) (Webi * self);
  
  /** Title change indication signal.
   * use \webi_get_title() to get the title string
   * @emited when title of current page changes.
   * @param self the engine which sent the signal   
   */
  void (* title) (Webi * self);
  
  /** Load start indication signal.
   * @emited when page loading is started
   * @param self the engine which sent the signal
   */
  void (* load_start) (Webi * self);
  
  /** Load start indication signal.
   * @emited when page loading is stopped.
   * @emited on error   
   * @param self the engine which sent the signal
   */
  void (* load_stop) (Webi * self);

  /** Set cookie indication signal.
   * @emited when a cookie is received from network
   * @param self the engine which sent the signal
   * @param cookie The actual cookie received.
   * @return \FALSE if don't allow cookie to be set
   *         \TRUE if cookie should be set
   */
  gboolean (* set_cookie) (Webi * self, WebiCookie * cookie);

  /** javascript status change indication signal
   * use \webi_get_status_text() to get the status string
   *
   * @emited when javascript status changes.
   * @param self the engine which sent the signal
   */
  void (* status_text) (Webi * self);

  /** Page load status change indication signal
   *
   * @emited when page load status changes.
   * @param self the engine which sent the signal
   * @param status status of the engine.
   */
  void (* status) (Webi * self, WebiLoadStatus * status);

  /** javascript prompt and alert request signal
   * must be synchronous
   * @emited when javascript generates an alert 
   * @emited when javascript generates an prompt
   * 
   * @param self the engine which sent the signal
   * @param args used to pass information between browser and engine (in and out)
   *        see #WebiPromptAgs
   */  
  void (* req_js_prompt) (Webi *self, WebiPromptArgs* args);

    /** HTTP Auth
   * must be synchronous
   * @emited when javascript generates an alert 
   * @emited when javascript generates an prompt
   * 
   * @param self the engine which sent the signal
   * @param args used to pass information between browser and engine (in and out)
   *        see #WebiPromptAgs
   */  
  void (* req_auth_prompt) (Webi *self, WebiAuthArgs* args);

  /** javascript/html new window request signal
   * must be synchronous
   *
   * @emited when javascript requests to create a new window
   * @emited when html link contains target="_blank" -attribute   *
   * @param self the engine which sent the signal
   * @param newengine The new engine of the new window
   *        or \NULL if new window creation is not allowed
   * @return \FALSE if don't allow window to be opened
   *         \TRUE if window was opened
   */    
  gboolean (* req_new_window) (Webi *self, Webi* newengine);

  void (* show_window) (Webi *self, WebiWindowProperties* features);
  void (* close_window) (Webi *self);

  void (* set_window_properties) (Webi *self, WebiWindowProperties* features);
  void (* get_window_size) (Webi *self, WebiWindowSize * type, GtkAllocation * size);
  void (* set_window_size) (Webi *self, WebiWindowSize * type, GtkRequisition * size); 


  /** Set device type signal 
   * must be synchronous
   *
   * @emited when user wants to change device type used in rendering and
   *         style sheet selection
   * @param self the engine which sent the signal
   * @param newDeviceType The new device type of current window
   */    
  void (* set_device_type) (Webi *self, WebiDeviceType type);

  /** Get device type signal 
   * must be synchronous
   *
   * @emited when user wants to change device type used in rendering and
   *         style sheet selection
   * @param self the engine which sent the signal
   * @param newDeviceType The new device type of current window
   */    
  WebiDeviceType (* get_device_type) (Webi *self);

  void (* mouse_over) (Webi *self, const gchar* link_title, const gchar* link_label, const gchar* link_url, const gchar* link_target);

  /** selection change signal*/
  void (* selection) (Webi *self);
#if 0
  /* not implemented at the moment */
  void (* req_file_attach) (Webi *self);  
  void (* file_upload_finished) (Webi *self);
  void (* file_upload_finished) (Webi *self);
#endif  

};


/*
 * Public methods
 */


/** Returns GObject type for KHTML html renderer class
 * Returns GObject type for KHTML html renderer class.
 *
 * @return type for KHTML html renderer class 
 */
GType webi_get_type ();


/** Creates new html rendering engine
 * Creates new html rendering engine widget. To be able to view web pages,
 * add returned widget to a container and show the container.
 * 
 * @return html rendering engine widget 
 */
GtkWidget * webi_new ();

/** Starts loading of a new url
 * Starts loading of a new url. Loading is asynchronous.
 *
 * @emit "load-start" signal on start
 * @emit "load-stop"  signal when loading stops, ie. succesfully loaded page, or error
 * @param self the engine to use
 * @param url the url to load
 */
void webi_load_url (Webi * self, const gchar * url);

/** Reloads current url
 * reloads current url
 */
void webi_refresh (Webi * self);

/** Cancels the load currently in progress, if any
 * Cancels the load currently in progress, if any.
 * @emit "load-stop"
 *
 * @param self the engine to use
 */
void webi_stop_load (Webi * self);

/** Checks the browsing history position relative to the beginning of the history
 * Checks if the engine is at the beginning of browsing history.
 * @return \TRUE if browsing history has previous elements
 *         \FALSE otherwise
 */
gboolean webi_can_go_back (Webi * self);


/** Checks the browsing history position relative to the end of the history
 * Checks if the engine is at the end of browsing history.
 * @return \TRUE if browsing history has successive elements
 *         \FALSE otherwise
 */
gboolean webi_can_go_forward (Webi * self);

/** Directs browser engine to the previous url in the browsing history
 * Directs browser engine to the previous url in the browsing history.
 * @emit "load-start" see \webi_load_url
 * @emit "load-stop" see \webi_load_url
 */
void webi_go_back (Webi * self);

/** Directs browser engine to the next url in the browsing history
 * Directs browser engine to the next url in the browsing history.
 *
 * @emit "load-start" see \webi_load_url
 * @emit "load-stop" see \webi_load_url
 */
void webi_go_forward (Webi * self);

/** Returns the url of the currently loaded page
 * Returns the url of the currently loaded page.
 * The string contains the full url used, including
 * the protocol. It can be absolute or relative.
 * The string must not be freed (const).
 *
 * @return  the url string of the currently loaded page.
 */
const gchar* webi_get_location (Webi * self);

/** Returns the title of the currently loaded page
 * Returns the title of the currently loaded page.
 * If the page contains a frameset, title is the title of the
 * frameset.
 *
 * @return the title of the currently loaded page.
 */
const gchar* webi_get_title (Webi * self);

/** Returns a status string set by javascript
 * Returns a string that javascript has set to be used
 * usually in the statusbar of the browser.
 *
 * @return javascript status string
 */
const gchar* webi_get_status_text (Webi * self);

/** Returns internal representation of the engine
 * Returns internal representation of the engine.
 * Can be used in C++ code. Exposes the public NRCore api
 * to the user. This may be needed if certain functionality
 * is not implemented in C interface.
 * usage not recommended
 * Used with:
 * OSBB::Bridge* engine = 0;
 * Webi* khtml_engine = webi_new();
 * engine = static_cast<OSB::Bridge*>(webi_get_internal (engine));
 *
 */
void* webi_get_internal (Webi * self);
  
/** Sets the settings of the rendering engine
 * Sets the settings of the rendering engine.
 * 
 */
void webi_set_settings (Webi * self, const WebiSettings* settings);

/** Returns the current settings of the rendering engine
 * Returns the current settings of the rendering engine. Fields
 * are read only and must not b
 */ 
const WebiSettings* webi_get_settings (Webi * self);

/**  Prints the internal render tree of the engine.
 * 
 * Can be used in C++ debug code. This 
 * usage not recommended
 * Used with:
 * Webi* khtml_engine = webi_new();
 * const gchar * url = "http://www.mysite.com/";
 * const ghar* presentation = webi_render_tree (engine, url));
 *
 */
const gchar* webi_render_tree (Webi * self);

/** Toggles the emission of internal constructed load status messages
 * Sets the emission of internal constructed load status messages
 * Signalö emitted is status-text
 *
 * @param flag \TRUE if you want to receive internal status messages
                     for loading
	       \FALSE if not
 */
void webi_set_emit_internal_status (Webi * self, gboolean flag);


/** Sets the device type used for current window.
 *
 * @param self the engine which sent the signal
 * @param newDeviceType The new device type of current window
 */    
void webi_set_device_type (Webi * self, WebiDeviceType device);

/** Gets the device type used for current window.
 *
 * @param self the engine which sent the signal
 * @param newDeviceType The new device type of current window
 */    
WebiDeviceType webi_get_device_type (Webi * self);

  
void webi_set_group (Webi* self, const gchar* group);

const gchar* webi_get_group (Webi* self);

void webi_set_text_multiplier (Webi* self, gfloat multiplier);
gfloat webi_get_text_multiplier (Webi* self);

gboolean webi_find (Webi* self, const gchar* text, gboolean case_sensitive, gboolean dir_down);

const gchar* webi_get_current_selection_as_text(Webi* self);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
