// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef WAPPLICATION_
#define WAPPLICATION_

#include <vector>
#include <string>
#include <set>

#include <Wt/WObject>
#include <Wt/WCssStyleSheet>
#include <Wt/WEvent>
#include <Wt/WString>
#include <Wt/WMessageResourceBundle>
#include <Wt/WSignal>

/*! \file WApplication
 */

namespace Wt {

class WLogEntry;

class WApplication;
class WContainerWidget;
class WEnvironment;
class WResource;
class WServerPushResource;
class WebSession;
class WText;
class Iframe;
class UpdateLockImpl;
class WEvent;

extern WT_API void RemoveExposedSignal(EventSignalBase *s);
extern WT_API void AddExposedSignal(EventSignalBase *s);

/*! \brief Typedef for a function that creates WApplication objects.
 *
 * \sa WRun()
 *
 * \relates WApplication
 */
typedef WApplication* (*ApplicationCreator)(const WEnvironment& env);

/*! \class WApplication Wt/WApplication Wt/WApplication
 *  \brief A class that represents an instance of a %Wt Application,
 *         corresponding to a single session.
 *
 * For every new session, an instance of WApplication must be
 * created, before creating widgets. For this purpose, the user passes
 * a function that creates applications to WRun(). A general
 * structure for starting a %Wt Application could be:
 *
 * \code
 *   WApplication *createApplication(const WEnvironment WEnvironment& env) {
 *     //
 *     // Optionally, check the environment and redirect to an error page.
 *     //
 *     bool valid = ...;
 *    
 *     if (!valid) {
 *       WApplication *app = new WApplication(env);
 *       app->redirect("error.html");
 *       app->quit();
 *       return app;
 *     }
 *
 *     WApplication *app = new WApplication(env);
 *
 *     //
 *     // Add widgets to app->root() and return the application object.
 *     //
 *     return app;
 *   }
 * \endcode
 *
 * Throughout the application, the instance is available through
 * WApplication::instance() (or through #wApp). The application may be
 * quited either by calling quit(), or because of a timeout (when the
 * user has closed the window, or crashed its computer or was eaten by
 * a virus). In either case, the application object is deleted,
 * allowing for cleanup of the entire widget tree, and any other
 * resources.
 *
 * The %WApplication object provides access to:
 * <ul>
 *   <li>WEnvironment information through environment(), which gives
 *     details about the user and start-up
 *     arguments.</li>
 *   <li>inline and external style sheets using styleSheet() and
 *     useStyleSheet() respectively.</li>
 *   <li>the top-level widget, which is the root of the widget hierarchy,
 *     with root().</li>
 *   <li>localisation information and message resources bundles, with
 *     setLocale(), locale() and messageResourceBundle().
 *   <li>the maximum configured request size (maximumRequestSize()) and
 *     a signal WApplication::requestTooLarge to react to too large
 *     requests.</li>
 *   <li>defining cookies using setCookie(). These cookies may provide
 *     context across sessions, and may be inspected using
 *     WEnvironment::getCookie() in a future session.</li>
 *   <li>support for browser history (back and forward buttons), and
 *     bookmarks using the setState() and state() methods, and
 *     the WApplication::stateChanged signal.</li>
 *   <li>support for server-initiated updates with enableUpdates(),
 *     triggerUpdate() and getUpdateLock().</li>
 * </ul>
 *
 */
class WT_API WApplication : public WObject
{
public:
  /*! \brief Enumeration that indicates the Ajax communication method.
   *
   * \sa setAjaxMethod()
   */
  enum AjaxMethod {
    XMLHttpRequest,  //!< Use the XMLHttpRequest object (real AJAX)
    DynamicScriptTag //!< Use dynamic script tags (for cross-domain AJAX)
  };

  /*! \brief Typedef for a function that creates WApplication objects.
   *
   * \sa WRun()
   */
  typedef Wt::ApplicationCreator ApplicationCreator;

  /*! \brief Construct a WApplication
   */
  WApplication(const WEnvironment& environment);

  /*! \brief Destroys the WApplication.
   *
   * This automatically destroys root(), and as a consequence the entire
   * widget tree.
   */
  ~WApplication();

  /*! \brief Returns the environment for this application session.
   *
   * This is the environment that was used when constructing the
   * application. The environment contains all settings that constrain
   * the application from outside.
   */
  const WEnvironment& environment() const;

  /*! \brief Returns a reference to the inline style sheet.
   *
   *  Widgets may allow configuration of their look and feel through
   *  style classes. These may be defined in this inline stylesheet,
   *  or in external style sheets.
   *
   * \sa useStyleSheet()
   */
  WCssStyleSheet& styleSheet() { return styleSheet_; }

  /*! \brief Add an external style sheet.
   *
   * Widgets may allow configuration of their look and feel through
   * style classes. These may be defined in this inline stylesheet,
   * or in external style sheets.
   *
   * If not empty, <i>dep</i> is a string that is used to make the
   * stylesheet browser-dependent. This works only to differentiate
   * between specific versions of Microsoft Internet Explorer versions
   * versus other browsers.  Values for dep are for example "gte IE 5"
   * or "!IE 7".
   *
   * The <i>uri</i> indicates a relative or absolute URL to the
   * stylesheet.
   *
   * \sa styleSheet()
   */
  void useStyleSheet(const std::string& uri,
		     const std::string& dep = std::string());

  /*! \brief The root container of this application.
   *
   * This is the top-level container for displaying widgets in the
   * application. The user interface of your application is
   * represented by the content of this container.
   */
  WContainerWidget *root() const { return widgetRoot_; }

  void bindWidget(WWidget *widget, const std::string& divId);

  /*! \brief Returns the application url.
   *
   * Returns the (relative) URL for this application instance (thus
   * including the session ID if necessary). The URL includes the full
   * application path, but excludes the protocol, host name and port
   * number.
   *
   * If you want to present URLs that are suitable for bookmarking the
   * current application state, see bookmarkUrl().
   *
   * \sa redirect(), WEnvironment::hostName(), WEnvironment::urlScheme()
   * \sa applicationName(), bookmarkUrl()
   */
  std::string url() const;

  /*! \brief Returns a bookmarkable URL that captures the application state.
   *
   * Returns the (relative) URL for this application, excluding
   * session ID, but including the encoded state for
   * bookmarking. Tries to return a URL that is as short as possible
   * (excluding protocol, host name, port, and application path).
   *
   * \sa url(), bookmarkUrl(const std::string&, const std::string&)
   */
  std::string bookmarkUrl() const;

  /*! \brief Get the name of the application.
   *
   * Returns the name of the application in the application directory.
   * This name is the file path of the url (without path and session
   * ID).
   *
   * You could use this if you have deployed the same application
   * under two different names, and want to have a different behaviour
   * for one versus the other.
   */
  const std::string &applicationName() const;

  /*! \brief Set the application title.
   *
   * Set the title that appears as the browser window title.
   *
   * The default title is "".
   *
   * \sa title()
   */
  void setTitle(const WString& text);

  /*! \brief Returns the application title.
   *
   * \sa setTitle(const WString&)
   */
  const WString& title() const { return title_; }

  /*! \brief Returns the current application instance.
   *
   * This is the same as the global variable #wApp. In a
   * multi-threaded server, it returns the application-specific
   * application instance.
   */
  static WApplication *instance();

  /*! \brief Returns the message resource bundle for this application.
   *
   * The message resource bundle defines the list of external XML
   * files that are used to lookup localized strings.
   *
   * \sa WString::tr(const char *key)
   */
  WMessageResourceBundle& messageResourceBundle()
    { return messageResourceBundle_; }

  /*! \brief Set the current locale.
   *
   * Specifying an empty locale assumes the default locale.
   * A different value (such as e.g. "nl") will cause WString values to be
   * resolved in the respect message resource files.
   *
   * When the locale get changed, refresh() is called which will re-localize
   * messages.
   *
   * The defualt locale is copied from the environment
   * (WEnvironment::locale()), and indicates the locale that was
   * configured by the user in his browser preferences.
   *
   * \sa WMessageResourceBundle::use(), WString::tr()
   */
  void setLocale(const std::string& locale);

  /*! \brief Get the currently used locale.
   *
   * \sa setLocale(const std::string&)
   */
  std::string locale() const { return locale_; }

  /*! \brief Refresh the application.
   *
   * This method is called in response to the user hitting the refresh
   * (or reload) button, and causes the application to refresh its data,
   * including messages from message-resource bundles.
   */
  virtual void refresh();

  /*! \brief Redirect the application to another location.
   *
   * The client will be redirected to a new location. Use this in
   * conjunction with quit() if you want to the application to be
   * terminated as well.
   *
   * Calling redirect() does not imply quit(), since it may be useful
   * to switch between a non-secure and secure (SSL) transport
   * connection.
   */
  void redirect(const std::string& url);

  /*! \brief Checkpoint the current application state with a key/value pair.
   *
   * The user may browse through application states using the browser back
   * and forward buttons, or bookmark a particular state of your application.
   *
   * You may also create URL's corresponding to particular states, and use
   * them in WAnchor's so that the user may follow this anchor in a new
   * window or tab to open a second session to your application that starts
   * in that state.
   *
   * An application object (such as a widget) that wishes to generate history
   * events, and respond to state changes, should:
   * <ul>
   *   <li>reserve a unique key for itself;</li>
   *   <li>use calls to setState() to indicate a new state;</li>
   *   <li>examine an initial state using state() when the object is created,
   *     which may reflect a bookmarked state;</li>
   *   <li>respond to state changes by listening to the
   *     WApplication::stateChanged signal for state related to its key.</li>
   * </ul>
   *
   * For an example, see the WMenu implementation.
   *
   * Changing application state is conveniently used together with a
   * WAnchor. By using \link bookmarkUrl(const std::string&, const std::string&) bookmarkUrl()\endlink, you can set the URL for the anchor
   * so that it matches the application state that is set in the
   * anchor's \link WAnchor::clicked clicked<>\endlink signal handler.
   * When the user follows the anchor to a new window or tab, it behaves as if
   * the user uses the bookmarked URL, to spawn a new session.
   *
   * With Ajax, this feature only works well for Firefox and Internet
   * Explorer, and requires the following resource:
   *
   * <ul>
   * <li><i>resourcesURL</i>/dhtml_dhtmlHistory.js</li>
   * </ul>
   *
   * This file may be found in the resources/ folder of the %Wt distribution. 
   *
   * The default value for <i>resourcesURL</i> is "resources/". This
   * value may be overridden with any valid URL which points to the
   * location where this file may be found, by configuring the
   * <i>resourcesURL</i> property in your %Wt configuration file.
   *
   * \sa state(), stateChanged, bookmarkUrl()
   */
  void setState(const std::string& key, const std::string& value);

  /*! \brief Returns the current application state value associated
   *         with a specific key.
   *
   * \sa setState(), bookmarkUrl()
   */
  std::string state(const std::string& key) const;

  /*! \brief Returns a bookmarkable URL that captures the application state.
   *
   * Like bookmarkUrl(), this method returns the (relative) URL for
   * this application, excluding session ID, but including the encoded
   * state for bookmarking. This method however returns the URL when
   * the state <i>state</i> would be set for the indicated
   * <i>scope</i>. This is useful for generating URLs for anchors
   * which a click event which generates that state.
   *
   * \sa url(), bookmarkUrl(), setState()
   */
  std::string bookmarkUrl(const std::string& scope,
			  const std::string& state);

  /*! \brief %Signal which indicates a change in application state,
   *         because the user navigates through the browser history.
   *
   * An application object that wishes to react to state changes should
   * listen to this signal. 
   *
   * \sa setState()
   */
  Signal<std::string, std::string> stateChanged;

  /*! \brief Unique identifier for the current session
   *
   * The session id is a string that uniquely identifies the current session.
   * Note that the actual contents has no particular meaning and client
   * applications should in no way try to interpret its value.
   */
  std::string sessionId() const;

  WebSession *session() { return session_; }

  /*! \brief Enable server-initiated updates.
   *
   * By default, updates to the user interface are possible only at
   * startup, during any event (in a slot), or at regular time points
   * using WTimer. This is the normal %Wt event loop.
   *
   * In some cases, one may want to modify the user interface from a
   * second thread, outside the event loop, or from socket events
   * (using the WSocketNotifier). While this may be worked around by
   * the WTimer, in some cases, there are bandwidth and processing
   * overheads associated which may be unnecessary, and which create a
   * trade-off with time resolution of the updates.
   *
   * A call to this method starts a so-called "server push". Widgets
   * may then be modified, created or deleted outside of the event
   * loop (from another thread), and are subsequently propagated by
   * calling triggerUpdate().
   *
   * <i>This works only if JavaScript is available on the client, and
   * is not considered a production quality feature (there are some
   * unwanted side effects that have to do with typical browser
   * limitations, such as the maximum number of simultaneous open
   * connections to a single web server).</i>.
   *
   * \sa triggerUpdate()
   */
  void enableUpdates();

  /*! \brief Are server-initiated updates enabled ?
   *
   * True if server-initiated updates were enabled by a previous call to
   * enableUpdates().
   */
  bool updatesEnabled() const;

  /*! \brief Propagate server-initiated updates.
   *
   * Propagate changes made to the user interface outside of the main
   * event loop. This is only possible after a call to
   * enableUpdates(), and must be done while holding the UpdateLock
   * (or from within a socket event, see WSocketNotifier).
   *
   * \sa enableUpdates(), getUpdateLock()
   */
  void triggerUpdate();

  /*! \brief A synchronisation lock for manipulating and updating the
   *         application and its widgets outside of the event loop.
   *
   * You need to get this lock only when you want to manipulate
   * widgets outside of the event loop. Inside the event loop, this
   * lock is already held by the library itself.
   *
   * \sa getUpdateLock();
   */
  class WT_API UpdateLock {
  public:
    /*! \brief Copy the lock.
     *
     * By copying the lock, the lock is transferred. The original object
     * becomes empty, and its destructor has no effect of releasing the lock.
     */
    UpdateLock(const UpdateLock&);

    /*! \brief Releases and destroys the scope dependent lock
     */
    ~UpdateLock();

  private:
    UpdateLock(WApplication& app);

    mutable UpdateLockImpl *impl_;

    friend class WApplication;
  };

  /*! \brief Attach an auxiliary thread to this application.
   *
   * In a multi-threaded environment, WApplication::instance() uses
   * thread-local data to retrieve the application object that
   * corresponds to the session currently being handled by the
   * thread. This is set automatically by the library whenever an
   * event is delivered to the application, or when you use the
   * getUpdateLock() to modify the application from an auxiliary
   * thread outside the normal event loop.
   *
   * When you want to manipulate the widget tree inside the main event
   * loop, but from within an auxiliary thread, then you cannot use
   * the getUpdateLock() since this will create an immediate dead
   * lock. Instead, you may attach the auxiliary thread to the
   * application, by calling this method from the auxiliary thread,
   * and in this way you can modify the application from within that
   * thread without needing the update lock.
   */
  void attachThread();

  /*! \brief Grabs and returns the lock for manipulating widgets outside
   *         the event loop.
   *
   * You need to keep this lock in scope while manipulating widgets
   * outside of the event loop. In normal cases, inside the %Wt event loop,
   * you do not need to care about it.
   *
   * \sa enableUpdates(), triggerUpdate()
   */
  UpdateLock getUpdateLock();

  /*! \brief Execute some JavaScript code.
   *
   * This method may be used to call some custom JavaScript code as
   * part of an event response.
   *
   * This function does not wait until the JavaScript is run, but
   * returns immediately. The JavaScript will be run after the normal
   * event handling, unless <i>afterLoaded</i> is set to false.
   */
  void doJavaScript(const std::string& javascript, bool afterLoaded = true);

  void addAutoJavaScript(const std::string& javascript);

  void declareJavaScriptFunction(const std::string& name,
				 const std::string& function);

  /*! \brief Load a JavaScript library.
   *
   * Attempt to load a JavaScript library. When <i>symbol</i> is not
   * empty, the library is only inserted in the page if the given
   * symbol is not yet defined.
   *
   * Returns true when the library was not yet loaded for this
   * application.
   *
   * JavaScript libraries may be loaded at any point in time. They
   * will be loaded before evaluating the normal event handling code,
   * but after javaScript that has been executed using
   * doJavaScript(..., false).
   */
  bool require(const std::string& uri,
	       const std::string& symbol = std::string());

  /*! \brief Process UI events.
   *
   * You may call this method during a long operation to:
   * <ul>
   *   <li>Propagate widget changes to the client.</li>
   *   <li>Process UI events.</li>
   * </ul>
   *
   * This method starts a recursive event loop, blocking the current
   * thread, and resumes when all events have been processed.
   */
  void processEvents();

  /*! \brief Read a configuration property.
   *
   * Tries to read a configured value for the property
   * <i>name</i>. The method returns whether a value is defined for
   * the property, and sets it to <i>value</i>.
   */
  static bool readConfigurationProperty(const std::string& name,
					std::string& value);

  /*! \brief Set the Ajax communication method.
   *
   * You may call this method only from your application constructor.
   *
   * The default method depends on your application type. For plain
   * applications, \link WApplication::XMLHttpRequest
   * XMLHttpRequest\endlink is used, while for embedded widget sets,
   * \link WApplication::DynamicScriptTag DynamicScriptTag\endlink is
   * used. The latter is less efficient, but has the benefit to allow
   * serving the application from a different server than the page
   * that hosts the embedded widgets.
   */
  void setAjaxMethod(AjaxMethod method);

  /*! \brief Returns the Ajax communication method.
   *
   * \sa setAjaxMethod()
   */
  AjaxMethod ajaxMethod() const { return ajaxMethod_; }

  std::string javaScriptClass() { return javaScriptClass_; }

  WContainerWidget *domRoot() const { return domRoot_; }
  WContainerWidget *domRoot2() const { return domRoot2_; }

  std::string fixRelativeUrl(const std::string& url) const;
  static std::string resourcesUrl();

  /*! \brief Initialize your application, post-construction.
   *
   * This method is invoked by the %Wt library after construction of a
   * new application. You may reimplement this method to do additional
   * initialization that is not possible from the constructor
   * (e.g. which uses virtual methods).
   */
  virtual void initialize();

  /*! \brief Finalize your application, pre-destruction.
   *
   * This method is invoked by the %Wt library before destruction of a
   * new application. You may reimplement this method to do additional
   * finalization that is not possible from the destructor (e.g. which
   * uses virtual methods).
   */
  virtual void finalize();

  /*! \brief Change the threshold for two-phase rendering.
   *
   * This changes the threshold for the communication size (in bytes) to
   * render invisible changes in one go. If the bandwidth for
   * rendering the invisible changes exceed the threshold, they will
   * be fetched in a second communication, after the visible changes
   * have been rendered.
   *
   * The value is a trade-off: setting it smaller will always use
   * two-phase rendering, increasing the total render time. Setting it
   * too large will increase the latency to render the visible
   * changes, since first all changes need to be received in the
   * browser.
   *
   * The initial value is read from the configuration file, see \ref
   * config_general.
   */
  void setTwoPhaseRenderingThreshold(int size);

  /*! \brief Set a new cookie.
   *
   * The name must be a valid cookie name (of type 'token': no special
   * characters or separators, see RFC2616 page 16). The value may be
   * anything. Specify the maximum age (in seconds) after which the
   * client must discard the cookie. To delete a cookie, use a value of '0'.
   *
   * By default the cookie only applies to the current path on the
   * current domain. To set a proper value for domain, see also RFC2109.
   *
   * Use cookies to recognize the same user returning at some later
   * time to your server or application.
   *
   * \sa WEnvironment::supportsCookies()
   */
  void setCookie(const std::string& name, const std::string& value,
		 int maxAge, const std::string& domain = "",
		 const std::string& path = "");

  /*! \brief Get the current maximum size of a request to the application.
   *
   * The maximum request size is configured in the configuration file,
   * see \ref config_general.
   *
   * \sa requestTooLarge
   */
  int maximumRequestSize() const;

  /*! \brief Add an entry to the application log.
   *
   * Starts a new log entry of the given <i>type</i> in the %Wt
   * application log file. This method returns a stream-like object to
   * which the message may be streamed.
   *
   * A typical usage would be:
   * \code
   *  wApp->log("notice") << "User " << userName << " logged in successfully.";
   * \endcode
   *
   * This would create a log entry that looks like:
   * \verbatim
[2008-Jul-13 14:01:17.817348] 16879 [/app.wt Z2gCmSxIGjLHD73L] [notice] "User bart logged in successfully." \endverbatim
   *
   * \sa \ref config_general
   */
  WLogEntry log(const std::string& type);

  std::string onePixelGifUrl();

  std::string docType() const;

public slots:
  /*! \brief Exit the application.
   *
   * Signaling this slot will cause the application to end after the
   * current event is completed.
   *
   * By default, the current widget tree (including any modifications
   * still pending) is rendered, and the application is terminated. A
   * "-- Quited" is appended to the application title.
   *
   * You might want to make sure no more events can be received from
   * the user, by not having anything clickable, for example by
   * displaying only text. A better approach may be to redirect the
   * user to another page using redirect().
   */
  void quit();

public:
  /*! \brief %Signal which indicates that too large POST was received.
   *
   * The integer parameter is the request that was received in bytes.
   */
  Signal<int> requestTooLarge; 

protected:
  /*! \brief Notify an event to the application.
   *
   * This method is called by the event loop for propagating an event
   * to the application. It provides a single point of entry for
   * events to the application.
   *
   * You will rarely want to reimplement this method, unless you wish
   * to have a single point for exception handling. In that case, you should
   * call the baseclass implementation WApplication::notify(), and surround it
   * in your own try - catch block for those exceptions you wish to handle.
   *
   * Any uncaught exception will terminate the application.
   */
  virtual void notify(const WEvent& e);

  /*! \brief Returns whether a widget is exposed in the interface.
   *
   * The default implementation simply returns true, unless a modal dialog
   * is active, in which case it returns true only for widgets that are
   * inside the dialog.
   *
   * You may want to reimplement this method if you wish to disallow events
   * from certain widgets even if they are inserted in the widget hierachy.
   */
  virtual bool isExposed(WWidget *w) const;

private:
  struct ScriptLibrary {
    ScriptLibrary(const std::string& uri, const std::string& symbol);

    std::string uri, symbol, beforeLoadJS;
    bool operator< (const ScriptLibrary& other) const;
    bool operator== (const ScriptLibrary& other) const;
  };

  struct StyleSheet {
    StyleSheet(const std::string& uri, const std::string& dependency);

    std::string uri, dependency;
  };

  typedef std::map<std::string, std::string> StateMap;
  typedef std::map<std::string, EventSignalBase *> SignalMap;
  typedef std::map<std::string, WResource *> ResourceMap;
  typedef std::map<std::string, WObject *> ObjectMap;

  /*
   * Basic application stuff
   */
  WebSession            *session_;
  WString                title_;
  bool                   titleChanged_;
  WContainerWidget      *widgetRoot_;  // widgets in main DOM root
  WContainerWidget      *domRoot_;     // main DOM root
  WContainerWidget      *domRoot2_;    // other virtual root for WidgetSet mode
  WContainerWidget      *timerRoot_;   // timers in main DOM root
  WCssStyleSheet         styleSheet_;
  WMessageResourceBundle messageResourceBundle_;
  std::string            locale_;
  StateMap               state_;
  std::set<std::string>  statesChanged_;
  WServerPushResource   *serverPush_;
  std::string            javaScriptClass_;
  AjaxMethod             ajaxMethod_;
  WContainerWidget      *dialogCover_;
  WContainerWidget      *dialogWindow_;
  bool                   quited_;
  std::string            onePixelGifUrl_;

  std::vector<ScriptLibrary> scriptLibraries_;
  int                        scriptLibrariesAdded_;

  std::vector<StyleSheet> styleSheets_;
  int                     styleSheetsAdded_;

  std::vector<Iframe *> iframes_;

  SignalMap   exposedSignals_;   // signals that may be accessed
  ResourceMap exposedResources_; // resources that may be accessed
  ObjectMap   encodedObjects_;   // objects encoded for internal purposes
                                 // like 'virtual pointers' (see D&D)

  bool exposeSignals_;           // if we are currently exposing signals
                                 // (see WViewWidget)

  std::string afterLoadJavaScript_, beforeLoadJavaScript_,
    newBeforeLoadJavaScript_, autoJavaScript_;
  bool autoJavaScriptChanged_;

  EventSignal<WResponseEvent> javaScriptResponse_;

  bool              isQuited() const { return quited_; }
  WContainerWidget *timerRoot() const { return timerRoot_; }
  WContainerWidget *dialogCover(bool create = true);
  WContainerWidget *dialogWindow(bool create = true);

  WEnvironment&     env();       // short-hand for session_->env()

  /*
   * Functions for exposed signals, resources, and objects
   */
  void              addExposedSignal(EventSignalBase* signal);
  void              removeExposedSignal(EventSignalBase* signal);
  EventSignalBase  *decodeExposedSignal(const std::string& signalName) const;
  EventSignalBase  *decodeExposedSignal(const std::string& objectId,
				       const std::string& name);
  const SignalMap&  exposedSignals() const;

  std::string       addExposedResource(WResource *resource);
  void              removeExposedResource(WResource *resource);
  WResource        *decodeExposedResource(const std::string& resourceName)
    const;

  std::string       encodeObject(WObject *object);
  WObject          *decodeObject(const std::string& objectId) const;

  /*
   * Methods to recycle iframes (for file inputs)
   */
  WWidget          *useIframe();
  void              releaseIframe(WWidget *iframe);

  /*
   * Methods for application state handling
   */
  bool              loadRsh();
  void              setCurrentHistoryKey(const std::string& stateStr);
  std::string       getCurrentHistoryKey() const;

  void handleJavaScriptResponse(WResponseEvent event);

  /*
   * Methods for accessing javaScript, which may have erase-on-read
   * semantics
   */
  std::string afterLoadJavaScript();
  std::string beforeLoadJavaScript();
  std::string newBeforeLoadJavaScript();

  /*
   * Methods for accessing exposeSignals_
   */
  void setExposeSignals(bool how) { exposeSignals_ = how; }
  bool exposeSignals() const { return exposeSignals_; }

  friend class WebRenderer;
  friend class WebSession;
  friend class WebController;
  friend class EventSignalBase;
  friend class JavaScriptEvent;
  friend class WWidget;
  friend class WTimer;
  friend class WResource;
  friend class WFileUpload;
  friend class WInteractWidget;
  friend class WServerPushResource;
  friend class WViewWidget;
  friend class WDialog;
};

#ifdef WIN32
  #ifdef WTHTTP_STATIC
    #define WTCONNECTOR_API
  #else
    #ifdef wthttp_EXPORTS
      #define WTCONNECTOR_API __declspec(dllexport)
    #else
      #define WTCONNECTOR_API __declspec(dllimport)
    #endif
  #endif
#else
  #define WTCONNECTOR_API
#endif

#ifdef DOXYGEN_ONLY
/*! \brief Runs the %Wt application server.
 *
 * This function runs the application server, and should be called
 * only once (e.g. from within your main function).
 *
 * The <i>createApplication</i> argument is a function pointer to
 * create new application instances for each new user surfing to your application.
 *
 * When using the built-in httpd, the implementation listens for POSIX
 * termination signals (or console CTRL-C) event. You can use the
 * WServer class for more flexible control on starting and stopping
 * the server.
 *
 * \relates WServer
 * \sa WApplication
 */
extern int WRun(int argc, char** argv,
		ApplicationCreator createApplication = 0);
#else
extern int WTCONNECTOR_API WRun(int argc, char** argv,
				ApplicationCreator createApplication = 0);

#endif

/*! \def wApp
 *  \brief Global constant for accessing the application instance.
 *
 * This is equivalent to WApplication::instance()
 *
 * \relates WApplication
 */
#define wApp Wt::WApplication::instance()

}

#endif // WAPPLICATION_
