// 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>

// even boost/poolfwd.hpp includes <windows.h> ...
namespace boost {
  struct default_user_allocator_new_delete;

  template <typename UserAllocator>
  class pool;
}

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

namespace Wt {

class WApplication;
class WContainerWidget;
class WEnvironment;
class WEvent;
class WLoadingIndicator;
class WLogEntry;
class WResource;
class WText;

namespace Ext {
  class Dialog;
  class MessageBox;
}

class WebSession;
class UpdateLockImpl;
class SoundManager;

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

/*! \class WApplication Wt/WApplication Wt/WApplication
 *  \brief Represents an application instance for a single session.
 *
 * \if cpp
 *
 * Each user session of your application has a corresponding
 * %WApplication instance. You need to create a new instance and return
 * it as the result of the callback function passed to WRun(). The
 * instance is the main entry point to session information, and holds
 * a reference to the root() of the widget tree.
 *
 * \elseif java
 *
 * Each user session of your application has a corresponding
 * %WApplication instance. You need to create a new instance and return
 * it as the result of {javadoclink WtServlet#createApplication(WEnvironment)}. 
 * The instance is the main entry point to session information,
 * and holds a reference to the root() of the widget tree.
 *
 * \endif
 *
 * The recipe for a %Wt web application, which allocates new
 * WApplication instances for every user visiting the application is
 * thus:
 *
 * \if cpp
 * \code
 * WApplication *createApplication(const WEnvironment WEnvironment& env)
 * {
 *   //
 *   // Optionally, check the environment and redirect to an error page.
 *   //
 *   bool valid = ...;
 *
 *   WApplication *app;
 *   if (!valid) {
 *     app = new WApplication(env);
 *     app->redirect("error.html");
 *     app->quit();
 *   } else {
 *     // usually you will specialize your application class
 *     app = new WApplication(env);
 *
 *     //
 *     // Add widgets to app->root() and return the application object.
 *     //
 *   }
 *
 *   return app;
 * }
 * \endcode
 * \elseif java
 * \code
 * public class HelloServlet extends WtServlet {
 *  public HelloServlet() {
 *      super();
 *  }
 *
 *  public WApplication createApplication(WEnvironment env) {
 *      // In practice, you will specialize WApplication and simply
 *      // return a new instance.
 *      WApplication app = new WApplication(env);
 *      app.getRoot().addWidget(new WText("Hello world."));
 *      return app;
 *  }
 * }
 * \endcode
 * \endif
 *
 * \if cpp
 *
 * Throughout the session, the instance is available through
 * WApplication::instance() (or through #wApp). The application may be
 * quited either using the method quit(), or because of a timeout
 * after the user has closed the window, but not because the user does
 * not interact: keep-alive messages in the background will keep the
 * session around as long as the user has the page opened. In either
 * case, the application object is deleted, allowing for cleanup of
 * the entire widget tree, and any other resources.
 *
 * \elseif java
 *
 * Throughout the session, the instance is available through the
 * static method WApplication::instance(), which uses thread-specific
 * storage to keep track of the current session. The application may
 * be quited either using the method quit(), or because of a timeout
 * after the user has closed the window, but not because the user does
 * not interact: keep-alive messages in the background will keep the
 * session around as long as the user has the page opened.
 *
 * \endif
 *
 * The %WApplication object provides access to session-wide settings, including:
 *
 * - circumstancial information through environment(), which gives
 *   details about the user, start-up arguments, and user agent
 *   capabilities.
 * - the application title with setTitle().
 * - inline and external style sheets using styleSheet() and
 *   useStyleSheet().
 * - inline and external JavaScript using doJavaScript() and require().
 * - the top-level widget in root(), representing the entire browser window,
 *   or multiple top-level widgets using bindWidget() when deployed in
 *   %WidgetSet mode to manage a number of widgets within a 3rd party page.
 * - definition of cookies using setCookie() to persist information across
 *   sessions, which may be read using WEnvironment::getCookie() in a future
 *   session.
 * - management of the internal path (that enables browser history and
 *   bookmarks) using setInternalPath() and related methods.
 * - support for server-initiated updates with enableUpdates()
 * \if cpp
 * - localization information and message resources bundles using setLocale()
 *   and messageResourceBundle().
 * \elseif java
 * - localization information and message resources bundles, with
 *   setLocale() and setLocalizedStrings()
 * \endif
 */
class WT_API WApplication : public WObject
{
public:
  /*! \brief Enumeration that indicates the method for dynamic (AJAX-alike)
   *         updates.
   *
   * \sa setAjaxMethod()
   */
  enum AjaxMethod {
    XMLHttpRequest,  //!< Using the XMLHttpRequest object (real AJAX)
    DynamicScriptTag //!< Using dynamic script tags (for cross-domain AJAX)
  };

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

  /*! \brief Creates a new application instance.
   *
   * The \p environment provides information on the initial request,
   * user agent, and deployment-related information.
   */
  WApplication(const WEnvironment& environment);

#ifndef WT_TARGET_JAVA
  /*! \brief Destructor.
   *
   * The destructor deletes the root() container, and as a consequence
   * the entire widget tree.
   */
  ~WApplication();
#endif // WT_TARGET_JAVA

  /*! \brief Returns the current application instance.
   *
   * \if cpp
   * This is the same as the global define #wApp. In a multi-threaded server,
   * this method uses thread-specific storage to fetch the current session.
   * \elseif java
   * This method uses thread-specific storage to fetch the current session.
   * \endif
   */
  static WApplication *instance();

  /*! \brief Returns the environment information.
   *
   * This method returns the environment object that was used when
   * constructing the application. The environment provides
   * information on the initial request, user agent, and
   * deployment-related information.
   *
   * \sa url(), sessionId()
   */
  const WEnvironment& environment() const;

  /*! \brief Returns the root container.
   *
   * This is the top-level widget container of the application, and
   * corresponds to entire browser window. The user interface of your
   * application is represented by the content of this container.
   *
   * \if cpp
   *
   * The %root() widget is only defined when the application manages
   * the entire window. When deployed as a \link Wt::WidgetSet
   * WidgetSet\endlink application, there is no %root() container, and
   * \c 0 is returned.  Instead, use bindWidget() to bind one or more
   * root widgets to existing HTML &lt;div&gt; (or other) elements on
   * the page.
   *
   * \elseif java
   *
   * The root() widget is only defined when the application manages
   * the entire window. When deployed as a \link Wt::WidgetSet
   * WidgetSet\endlink application, there is no %root() container, and
   * <code>null</code> is returned. Instead, use bindWidget() to bind
   * one or more root widgets to existing HTML &lt;div&gt; (or other)
   * elements on the page.
   *
   * \endif
   */
  WContainerWidget *root() const { return widgetRoot_; }

  /*! \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.
   *
   * It is usually preferable to use external stylesheets (and
   * consider more accessible). Still, the internal stylesheet has as
   * benefit that style rules may be dynamically updated, and it is
   * easier to manage logistically.
   *
   * \sa useStyleSheet()
   * \sa WWidget::setStyleClass()
   */
  WCssStyleSheet& styleSheet() { return styleSheet_; }

  /*! \brief Adds an external style sheet.
   *
   * Widgets may allow configuration of their look and feel through
   * style classes. These may be defined in an inline stylesheet,
   * or in external style sheets.
   *
   * The \p url indicates a relative or absolute URL to the
   * stylesheet.
   *
   * External stylesheets are inserted after the internal style sheet,
   * and can therefore override default styles set by widgets in the
   * internal style sheet.
   *
   * \sa styleSheet(), useStyleSheet(const std::string&, const std::string&)
   * \sa WWidget::setStyleClass()
   */
  void useStyleSheet(const std::string& url);

  /*! \brief Adds an external style sheet, conditional to specific Internet
   *         Explorer browser.
   *
   * \p condition is a string that is used to apply the stylesheet
   * to specific versions of IE. Only a limited subset of the IE
   * conditional comments syntax is supported (since these are in fact
   * interpreted server-side instead of client-side). Examples are:
   * - "IE gte 6": only for IE version 6 or later. 
   * - "!IE gte 6": only for IE versions prior to IE6.
   * - "IE lte 7": only for IE versions prior to IE7.
   *
   * The \p url indicates a relative or absolute URL to the
   * stylesheet.
   *
   * \sa useStyleSheet()
   */
  void useStyleSheet(const std::string& url, const std::string& condition);

  /*! \brief Sets the theme.
   *
   * The theme provides the look and feel of several built-in widgets,
   * using CSS style rules. Rules for each theme are defined in the
   * <tt>resources/themes/</tt><i>theme</i><tt>/</tt> folder.
   *
   * The default theme is "default". When setting "", the external style
   * sheets related to the theme are not loaded.
   */
  void setCssTheme(const std::string& theme);

  /*! \brief Returns the theme.
   *
   * \sa setCssTheme()
   */
  std::string cssTheme() const { return theme_; }

  /*! \brief Sets the window title.
   *
   * Sets the browser window title to \p title.
   *
   * The default title is "".
   *
   * \sa title()
   */
  void setTitle(const WString& title);

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

  /*! \brief Returns the resource object that provides localized strings.
   *
   * \if cpp
   * The default value is a WMessageResourceBundle instance, which
   * uses XML files to resolve localized strings, but you can set a
   * custom class using setLocalizedStrings().
   * \elseif java
   * This returns the object previously set using setLocalizedStrings().
   * \endif
   *
   * WString::tr() is used to create localized strings, whose
   * localized translation is looked up through this object, using a
   * key.
   * 
   * \if cpp
   * \sa WString::tr(), messageResourceBundle()
   * \elseif java
   * \sa WString::tr()
   * \endif
   */
  WLocalizedStrings *localizedStrings() { return localizedStrings_; }

  /*! \brief Sets the resource object that provides localized strings.
   *
   * The \p translator resolves localized strings within the current
   * application locale.
   *
   * \if cpp
   * The previous resource is deleted, and ownership of the new resource
   * passes to the application.
   * \endif
   *
   * \sa localizedStrings(), WString::tr(const char *key)
   */
  void setLocalizedStrings(WLocalizedStrings *stringResolver);

#ifndef WT_TARGET_JAVA
  /*! \brief Returns the message resource bundle.
   *
   * The message resource bundle defines the list of external XML
   * files that are used to lookup localized strings.
   *
   * The default localizedStrings() is a WMessageResourceBundle
   * object, and this method returns localizedStrings() upcasted to
   * this type.
   *
   * \sa WString::tr(const char *key)
   */
  WMessageResourceBundle& messageResourceBundle() const;
#endif // WT_TARGET_JAVA

  /*! \brief Changes the locale.
   *
   * The locale is used by the localized strings resource to resolve
   * localized strings.
   *
   * By passing an empty \p locale, the default locale is
   * chosen.
   *
   * When the locale is changed, refresh() is called, which will
   * resolve the strings of the current user-interface in the new
   * locale.
   *
   * The default locale is copied from the environment
   * (WEnvironment::locale()), and this is the locale that was
   * configured by the user in his browser preferences, and passed
   * using an HTTP request header.
   *
   * \sa localizedStrings(), WString::tr()
   */
  void setLocale(const WT_LOCALE& locale);

  /*! \brief Returns the current locale.
   *
   * \sa setLocale(const std::string&)
   */
  WT_LOCALE locale() const { return locale_; }

  /*! \brief Refreshes the application.
   *
   * This lets the application to refresh its data, including strings
   * from message-resource bundles. This done by propagating
   * WWidget::refresh() through the widget hierarchy.
   *
   * This method is also called when the user hits the refresh (or
   * reload) button, if this can be caught within the current session.
   *
   * \if cpp
   *
   * The reload button may only be caught when %Wt is configured so that
   * reload should not spawn a new session. When URL rewriting is used for
   * session tracking, this will cause an ugly session ID to be added to the
   * URL. See \ref config_session for configuring the reload
   * behavior ("<reload-is-new-session>").
   *
   * \elseif java
   *
   * The reload button may only be caught when cookies for session
   * tracking are configured in the servlet container.
   *
   * \endif
   *
   * \sa WWidget::refresh()
   */
  virtual void refresh();

  /*! \brief Binds a top-level widget for a WidgetSet deployment.
   *
   * This method binds a \p widget to an existing element with DOM id
   * \p domId on the page. The element type should correspond with
   * the widget type (e.g. it should be a &lt;div&gt; for a
   * WContainerWidget, or a &lt;table&gt; for a WTable).
   *
   * \sa root()
   * \sa Wt::WidgetSet
   */
  void bindWidget(WWidget *widget, const std::string& domId);

  /*! \brief Returns a URL for the current session
   *
   * Returns the (relative) URL for this application session
   * (including the session ID if necessary). The URL includes the
   * full application path, and is expanded by the browser into a full
   * URL.
   *
   * For example, for an application deployed at
   * \code
   * http://www.mydomain.com/stuff/app.wt
   * \endcode
   * this method would return <tt>"/stuff/app.wt?wtd=AbCdEf"</tt>,
   * when using URL rewriting for session-tracking or
   * <tt>"/stuff/app.wt?a=a"</tt> when using cookies for
   * session-tracking 
   * \if cpp
   * (see also \ref config_session for configuring
   * the session-tracking method)
   * \endif
   * . As in each case, a query is
   * appended at the end of the URL, additional query parameters can
   * be appended in the form of <tt>"&param1=value&param2=value"</tt>.
   *
   * To obtain a URL that is suitable for bookmarking the current
   * application state, to be used across sessions, use bookmarkUrl()
   * instead.
   *
   * \sa redirect(), WEnvironment::hostName(), WEnvironment::urlScheme()
   * \sa bookmarkUrl()
   */
  std::string url() const;

  /*! \brief Returns a bookmarkable URL for the current internal path.
   *
   * Is equivalent to <tt>bookmarkUrl(internalPath())</tt>, see
   * bookmarkUrl(const std::string&) const.
   *
   * To obtain a URL that is refers to the current session of the
   * application, use url() instead.
   *
   * \sa url(), bookmarkUrl(const std::string&) const
   */
  std::string bookmarkUrl() const;

  /*! \brief Returns a bookmarkable URL for a given internal path.
   *
   * Returns the (relative) URL for this application that includes the
   * internal path \p internalPath, usable across sessions. The
   * URL is relative and expanded into a full URL by the browser.
   *
   * For example, for an application with current URL:
   * \code
   * http://www.mydomain.com/stuff/app.wt#/project/internal/
   * \endcode
   * when called with <tt>"/project/external"</tt>, this method would
   * return:
   *  - <tt>"app.wt/project/external/"</tt> when JavaScript is available, or
   *    the agent is a web spider, or
   *  - <tt>"app.wt/project/external/?wtd=AbCdEf"</tt> when no JavaScript
   *    is available and URL rewriting is used for session-tracking
   *    \if cpp
   *    (see also \ref config_session for configuring the session-tracking 
   *    method).
   *    \endif
   *
   * When the application is deployed at a folder (ending with '/'),
   * this style of URLs is not possible, and URLs are of the form:
   *  - <tt>"?_=/project/external/"</tt> when JavaScript is available, or
   *    the agent is a web spider, or
   *  - <tt>"?_=/project/external/&wtd=AbCdEf"</tt> when no JavaScript
   *    is available and URL rewriting is used for session-tracking.
   *
   * You can use bookmarkUrl() as the destination for a WAnchor, and
   * listen to a click event is attached to a slot that switches to
   * the internal path \p internalPath (see
   * WAnchor::setRefInternalPath()). In this way, an anchor can be
   * used to switch between internal paths within an application
   * regardless of the situation (browser with or without Ajax
   * support, or a web spider bot), but still generates suitable URLs
   * across sessions, which can be used for bookmarking, opening in a
   * new window/tab, or indexing.
   *
   * To obtain a URL that refers to the current session of the
   * application, use url() instead.
   *
   * \sa url(), bookmarkUrl()
   */
  std::string bookmarkUrl(const std::string& internalPath) const;

  /*! \brief Change the internal path.
   *
   * A %Wt application may manage multiple virtual paths. The virtual
   * path is appended to the application URL. Depending on the
   * situation, the path is directly appended to the application URL
   * or it is appended using a name anchor (#).
   *
   * For example, for an application deployed at:
   * \code
   * http://www.mydomain.com/stuff/app.wt
   * \endcode
   * for which an \p internalPath <tt>"/project/z3cbc/details/"</tt> is
   * set, the two forms for the application URL are:
   * <ul>
   * <li> in an AJAX session:
   * \code
   * http://www.mydomain.com/stuff/app.wt#/project/z3cbc/details/
   * \endcode
   * </li><li>
   * in a plain HTML session:
   * \code
   * http://www.mydomain.com/stuff/app.wt/project/z3cbc/details/
   * \endcode
   *    This has as major consequence that from the browser stand point,
   *    the application now serves many different URLs. As a consequence,
   *    relative URLs will break. Still, you can specify relative URLs
   *    within your application (in for example WAnchor::setRef() or
   *    WImage::setImageRef()) since %Wt will transform them
   *    to absolute URLs when needed. But, this in turn may break deployments
   *    behind reverse proxies when the context paths differ. For the same
   *    reason, you will need to use absolute URLs in any XHTML or CSS you
   *    write manually. <br>
   *    This type of URLs are only used when the your application is
   *    deployed at a location that does not end with
   *    a '/'. Otherwise, %Wt will generate URLS like:
   * \code
   * http://www.mydomain.com/stuff/?_=/project/z3cbc/details/
   * \endcode
   * </li></ul>
   *
   * When the internal path is changed, an entry is added to the
   * browser history. When the user navigates back and forward through
   * this history (using the browser back/forward buttons), an
   * internalPathChanged() event is emitted. You should listen to this
   * signal to switch the application to the corresponding state. When
   * \p emitChange is \c true, this signal is also emitted by setting
   * the path.
   *
   * A url that includes the internal path may be obtained using
   * bookmarkUrl().
   *
   * The \p internalPath must start with a '/'. In this way, you
   * can still use normal anchors in your HTML. Internal path changes
   * initiated in the browser to paths that do not start with a '/'
   * are ignored.
   *
   * \sa bookmarkUrl(), internalPath(), internalPathChanged()
   */
  void setInternalPath(const std::string& path, bool emitChange = false);

  /*! \brief Returns the current internal path.
   *
   * When the application is just created, this is equal to
   * WEnvironment::internalPath().
   *
   * \sa setInternalPath(), internalPathNextPart(), internalPathMatches()
   */
  std::string internalPath() const;

  /*! \brief Returns a part of the current internal path.
   *
   * This is a convenience method which returns the next \p folder
   * in the internal path, after the given \p path.
   *
   * For example, when the current internal path is
   * <tt>"/project/z3cbc/details"</tt>, this method returns
   * <tt>"details"</tt> when called with <tt>"/project/z3cbc/"</tt> as
   * \p path argument.
   *
   * The \p path must start with a '/', and internalPathMatches()
   * should evaluate to \c true for the given \p path. If not,
   * an empty string is returned and an error message is logged.
   *
   * \sa internalPath(), internalPathChanged()
   */
  std::string internalPathNextPart(const std::string& path) const;

  /*! \brief Checks if the internal path matches a given path.
   *
   * Returns whether the current internalPath() starts with
   * \p path (or is equal to \p path). You will typically use
   * this method within a slot conneted to the internalPathChanged()
   * signal, to check that an internal path change affects the
   * widget. It may also be useful before changing \p path using
   * setInternalPath() if you do not intend to remove sub paths when
   * the current internal path already matches \p path.
   *
   * The \p path must start with a '/'.
   *
   * \sa setInternalPath(), internalPath()
   */
  bool internalPathMatches(const std::string& path) const;

  /*! \brief %Signal which indicates that the user changes the internal path.
   *
   * This signal indicates a change to the internal path, which is
   * usually triggered by the user using the browser back/forward
   * buttons.
   *
   * The argument contains the new internal path.
   *
   * \sa setInternalPath()
   */
  Signal<std::string>& internalPathChanged() { return internalPathChanged_; }

  /*! \brief Redirects the application to another location.
   *
   * The client will be redirected to a new location identified by \p
   * url. 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 Returns the 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 Enables 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. 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.
   *
   * When \p enabled is \c true, this enables "server push" (what is
   * called 'comet' in AJAX terminology). Widgets may then be
   * modified, created or deleted outside of the event loop (e.g. in
   * response to execution of another thread), and these changes are
   * propagated by calling triggerUpdate().
   *
   * Note that you need to grab the application's update lock to avoid
   * concurrency problems, whenever you modify the application's state
   * from another thread.
   *
   * An example of how to modify the widget tree outside the event loop
   * and propagate changes is:
   * \if cpp
   * \code
   * // You need to have a reference to the application whose state
   * // you are about to manipulate.
   * // You should prevent the application from being deleted somehow,
   * // before you could grab the application lock.
   * Wt::WApplication *app = ...;
   *
   * {
   *   // Grab the application lock. It is a scoped lock.
   *   Wt::WApplication::UpdateLock lock = app->getUpdateLock();
   *
   *   // We now have exclusive access to the application: we can safely modify the widget tree for example.
   *   app->root()->addWidget(new Wt::WText("Something happened!"));
   *
   *   // Push the changes to the browser
   *   app->triggerUpdate();
   * }
   * \endcode
   * \else
   * \code
   * // You need to have a reference to the application whose state
   * // you are about to manipulate.
   * WApplication app = ...;
   *
   * // Grab the application lock
   * WApplication.UpdateLock lock = app.getUpdateLock();
   *
   * try {
   *   // We now have exclusive access to the application:
   *   // we can safely modify the widget tree for example.
   *   app.getRoot().addWidget(new WText("Something happened!"));
   *
   *   // Push the changes to the browser
   *   app.triggerUpdate();
   * } finally {
   *   lock.release();
   * }
   * \endcode
   * \endif
   *
   * \note This works only if JavaScript is available on the client.
   *
   * \sa triggerUpdate()
   */
  void enableUpdates(bool enabled = true);

  /*! \brief Returns whether server-initiated updates are enabled.
   *
   * \sa enableUpdates()
   */
  bool updatesEnabled() const { return serverPush_ > 0; }

  /*! \brief Propagates 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:
#ifndef WT_TARGET_JAVA
    /*! \brief Copy constructor.
     *
     * By copying the lock, the lock is transferred. The original
     * object becomes empty, and its destructor has no longer the
     * effect of releasing the lock.
     */
    UpdateLock(const UpdateLock&);

    /*! \brief Releases and destroys the scope dependent lock
     */
    ~UpdateLock();
#else
    void release();
#endif

  private:
    UpdateLock(WApplication& app);

#ifndef WT_TARGET_JAVA
    mutable UpdateLockImpl *impl_;
#endif // WT_TARGET_JAVA

    friend class WApplication;
  };

  /*! \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 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 Executes some JavaScript code.
   *
   * This method may be used to call some custom \p 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 \p afterLoaded is set to \c false.
   *
   * \sa addAutoJavaScript(), declareJavaScriptFunction()
   */
  void doJavaScript(const std::string& javascript, bool afterLoaded = true);

  /*! \brief Adds JavaScript statements that should be run continuously.
   *
   * This is an internal method.
   *
   * It is used by for example layout managers to adjust the layout
   * whenever the DOM tree is manipulated.
   *
   * \sa doJavaScript()
   */
  void addAutoJavaScript(const std::string& javascript);

  /*! \brief Declares an application-wide JavaScript function.
   *
   * This is an internal method.
   */
  void declareJavaScriptFunction(const std::string& name,
				 const std::string& function);

  /*! \brief Loads a JavaScript library.
   *
   * Loads a JavaScript library located at the URL \p url. %Wt keeps
   * track of libraries (with the same URL) that already have been
   * loaded, and will load a library only once. In addition, you may
   * provide a \p symbol which if already defined will also indicate
   * that the library was already loaded (possibly outside of %Wt when
   * in WidgetSet mode).
   *
   * This method returns \c true only when the library is loaded
   * for the first time.
   *
   * JavaScript libraries may be loaded at any point in time. Any
   * JavaScript code is deferred until the library is loaded, except
   * for JavaScript that was defined to load before, passing \c false
   * as second parameter to doJavaScript().
   */
  bool require(const std::string& url,
	       const std::string& symbol = std::string());

  /*! \brief Processes UI events.
   *
   * You may call this method during a long operation to:
   *   - propagate widget changes to the client.
   *   - process UI events.
   *
   * This method starts a recursive event loop, blocking the current
   * thread, and resumes when all pending user interface events have been
   * processed.
   *
   * Because a thread is blocked, this may affect your application
   * scalability.
   */
  void processEvents();

  /*! \brief Reads a configuration property.
   *
   * Tries to read a configured value for the property
   * \p name. The method returns whether a value is defined for
   * the property, and sets it to \p value.
   */
  static bool readConfigurationProperty(const std::string& name,
					std::string& value);
#ifdef WT_TARGET_JAVA
  /*! \brief Reads a configuration property.
   *
   * Tries to read a configured value for the property
   * \p name. If no value was configured, the default \p value
   * is returned.
   */
  static std::string *readConfigurationProperty(const std::string& name,
						const std::string& value);
#endif // WT_TARGET_JAVA

  /*! \brief Sets the Ajax communication method.
   *
   * You may change the communication method only from within the
   * application constructor.
   *
   * The default method depends on your application deployment
   * type.
   *
   * \if cpp
   * For \link Wt::Application plain\endlink applications, \link
   * WApplication::XMLHttpRequest XMLHttpRequest\endlink is used,
   * while for \link Wt::WidgetSet widget set\endlink
   * applications, \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.
   * \elseif java
   * For plain applications, \link WApplication::XMLHttpRequest 
   * XMLHttpRequest\endlink is used, while for WidgetSet 
   * applications, \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.
   * \endif
   */
  void setAjaxMethod(AjaxMethod method);

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

  /*! \brief Returns the name of the application JavaScript class.
   *
   * This JavaScript class encapsulates all JavaScript methods
   * specific to this application instance. The method is foreseen to
   * allow multiple applications to run simultaneously on the same
   * page in WidgtSet mode, without interfering.
   */
  std::string javaScriptClass() { return javaScriptClass_; }

  /*
   * The DOM root object. This contains not only the application root but
   * also other invisible objects (timers, dialog covers, ...).
   */
  WContainerWidget *domRoot() const { return domRoot_; }

  /*
   * A phony DOM root object, used to logically contain all widgets bound
   * in widgetset mode.
   */
  WContainerWidget *domRoot2() const { return domRoot2_; }

  /*
   * Encode an object to a string, to make it referencable from JavaScript.
   * Currently only used to encode the drag object in drag & drop.
   *
   * FIXME: provide a way to remove the encoding!
   *
   * \see decodeObject()
   */
  std::string encodeObject(WObject *object);

  /*
   * Decode an object.
   *
   * \see encodeObject()
   */
  WObject *decodeObject(const std::string& objectId) const;

  /*
   * Check if the url needs to be modified when it should be a
   * url relative to the application path, but the query info will make
   * it point to some internal path.
   */
  std::string fixRelativeUrl(const std::string& url) const;

  /*! \brief Returns the URL at which the resources are deployed.
   *
   * \if cpp
   * This returns the value of the 'resources' property set in the
   * configuration file.
   * \endif
   */
  static std::string resourcesUrl();

  /*! \brief Initializes the 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();

#ifndef WT_TARGET_JAVA
  /*! \brief Finalizes the 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();
#endif //WT_TARGET_JAVA

  /*! \brief Changes the threshold for two-phase rendering.
   *
   * This changes the threshold for the \p size of a JavaScript
   * response (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 but
   * reducing the latency for the visible changes. Setting it too
   * large will increase the latency to render the visible changes,
   * since first also all invisible changes need to be computed and
   * received in the browser.
   *
   * \if cpp
   * The initial value is read from the configuration file, see \ref
   * config_general.
   * \endif
   */
  void setTwoPhaseRenderingThreshold(int size);

  /*! \brief Sets a new cookie.
   *
   * Use cookies to transfer information across different sessions
   * (e.g. a user name). In a subsequent session you will be able to
   * read this cookie using WEnvironment::getCookie(). You cannot use
   * a cookie to store information in the current session.
   *
   * 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.
   *
   * \if cpp
   * \note %Wt provides session tracking automatically, and may be configured
   *       to use a cookie for this. You only need to use cookies yourself
   *       if you want to remember information <i>across sessions</i>.
   * \endif
   *
   * \sa WEnvironment::supportsCookies(), WEnvironment::getCookie()
   */
  void setCookie(const std::string& name, const std::string& value,
		 int maxAge, const std::string& domain = "",
		 const std::string& path = "");

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

  /*! \brief Adds an entry to the application log.
   *
   * Starts a new log entry of the given \p type in the %Wt
   * application log file. This method returns a stream-like object to
   * which the message may be streamed.
   * 
   * \if cpp
   * 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
   * \endif
   *
   * \if cpp
   * \sa \ref config_general
   * \endif
   */
  WLogEntry log(const std::string& type) const;

  /*! \brief Sets the loading indicator.
   *
   * The loading indicator is shown to indicate that a response from
   * the server is pending or JavaScript is being evaluated.
   *
   * The default loading indicator is a WDefaultLoadingIndicator.
   *
   * When setting a new loading indicator, the previous one is
   * deleted.
   */
  void setLoadingIndicator(WLoadingIndicator *indicator);

  /*! \brief Returns the loading indicator.
   *
   * \sa setLoadingIndicator()
   */
  WLoadingIndicator *loadingIndicator() const { return loadingIndicator_; }

  /*
   * A url to a resource that provides a one pixel gif. This is sometimes
   * useful for CSS hackery to make IE behave.
   */
  std::string onePixelGifUrl();

  /*
   * The doctype used to deliver the application.
   */
  std::string docType() const;

  /*! \brief Quits the application.
   *
   * The method returns immediately, but has as effect that the
   * application will be terminated after the current event is
   * completed.
   *
   * The current widget tree (including any modifications still
   * pending and applied during the current event handling) will still
   * be rendered, after which the application is terminated.
   *
   * 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. Even better is to redirect() the user to
   * another, static, page in conjunction with %quit().
   *
   * \sa redirect()
   */
  void quit();

  /*! \brief Returns whether the application is quited.
   *
   * \sa quit()
   */
  bool isQuited() const { return quited_; }

  /*! \brief %Signal which indicates that too a large request was received.
   *
   * The integer parameter is the request size that was received in bytes.
   */
  Signal<int>& requestTooLarge() { return requestTooLarge_; }

  /*
   * For persistent sessions only: redirect to another session.
   */
  void redirectToSession(const std::string& sessionId);

  /*
   * For persistent sessions only: return whether the persistent session
   * is connected to a browser.
   */
  bool isConnected() const { return connected_; }

  /*! \brief Sets a style class to the entire page &lt;body&gt;.
   *
   * \sa setHtmlClass()
   */
  void setBodyClass(const std::string& styleClass);

  /*! \brief Returns the style class set for the entire page &lt;body&gt;.
   *
   * \sa setBodyClass()
   */
  std::string bodyClass() const { return bodyClass_; }

  /*! \brief Sets a style class to the entire page &lt;html&gt;.
   *
   * \sa setBodyClass()
   */
  void setHtmlClass(const std::string& styleClass);

  /*! \brief Returns the style class set for the entire page &lt;html&gt;.
   *
   * \sa setHtmlClass()
   */
  std::string htmlClass() const { return htmlClass_; }

  /*! \brief Event signal emitted when a keyboard key is pushed down.
   *
   * The application receives key events when no widget currently
   * has focus. Otherwise, key events are handled by the widget in focus,
   * and its ancestors.
   *
   * \sa See WInteractWidget::keyWentDown()
   */
  EventSignal<WKeyEvent>& globalKeyWentDown();

  /*! \brief Event signal emitted when a "character" was entered.
   *
   * The application receives key events when no widget currently
   * has focus. Otherwise, key events are handled by the widget in focus,
   * and its ancestors.
   *
   * \sa See WInteractWidget::keyPressed()
   */
  EventSignal<WKeyEvent>& globalKeyPressed();
    
  /*! \brief Event signal emitted when a keyboard key is released.
   *
   * The application receives key events when no widget currently
   * has focus. Otherwise, key events are handled by the widget in focus,
   * and its ancestors.
   *
   * \sa See WInteractWidget::keyWentUp()
   */
  EventSignal<WKeyEvent>& globalKeyWentUp();

  /*! \brief Event signal emitted when enter was pressed.
   *
   * The application receives key events when no widget currently
   * has focus. Otherwise, key events are handled by the widget in focus,
   * and its ancestors.
   *
   * \sa See WInteractWidget::enterPressed()
   */
  EventSignal<>& globalEnterPressed();

  /*! \brief Event signal emitted when escape was pressed.
   *
   * The application receives key events when no widget currently
   * has focus. Otherwise, key events are handled by the widget in focus,
   * and its ancestors.
   *
   * \sa See WInteractWidget::escapePressed()
   */
  EventSignal<>& globalEscapePressed();

  /*
   * Returns whether debug was configured.
   * (should be public API ?)
   */
  bool debug() const;

#ifdef WT_DEBUG_JS
  void loadJavaScript(const char *jsFile);
#endif

  bool javaScriptLoaded(const char *jsFile);
  void setJavaScriptLoaded(const char *jsFile);

  static const char *RESOURCES_URL;

protected:
  /*! \brief Notifies 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, besides the application constructor.
   *
   * You may want to reimplement this method for two reasons:
   *
   * - for having a single point for exception handling: while you may want
   *   to catch recoverable exceptions in a more appropriate place, general
   *   (usually fatal) exceptions may be caught here. You will in probably
   *   also want to catch the same exceptions in the application constructor
   *   in the same way.
   * - you want to manage resource usage during requests. For example, at
   *   the end of request handling, you want to return a database session
   *   back to the pool. Since %notify() is also used for rendering right after
   *   the application is created, this will also clean up resources after
   *   application construction.
   *
   * In either case, you will need to call the base class
   * implementation of %notify(), as otherwise no events will be
   * delivered to your application.
   *
   * The following shows a generic template for reimplementhing this
   * method for both managing request resources and generic exception
   * handling.
   *
   * \if cpp
   * \code
   * MyApplication::notify(const WEvent& event)
   * {
   *    // Grab resources for during request handling
   *    try {
   *      WApplication::notify(event);
   *    } catch (MyException& exception) {
   *      // handle this exception in a central place
   *    }
   *    // Free resources used during request handling
   * }
   * \endcode
   * \elseif java
   * \code
   * void notify(WEvent event) {
   *     // Grab resources for during request handling
   *     try {
   *       super.notify(event);
   *     }  catch (MyException exception) {
   *       // handle this exception in a central place
   *     }
   *     // Free resources used during request handling
   * }
   * \endcode
   * \endif
   *
   * Note that any uncaught exception throw during event handling
   * terminates the session.
   */
  virtual void notify(const WEvent& e);

  /*! \brief Returns whether a widget is exposed in the interface.
   *
   * The default implementation simply returns \c true, unless a modal
   * dialog is active, in which case it returns \c 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 when they are inserted in the
   * widget hierachy.
   */
  virtual bool isExposed(WWidget *w) const;

  /*! \brief Progresses to an Ajax-enabled user interface.
   *
   * This method is called when the progressive bootstrap method is used, and
   * support for AJAX has been detected. The default behavior will propagate
   * the WWidget::enableAjax() method through the widget hierarchy.
   *
   * You may want to reimplement this method if you want to make
   * changes to the user-interface when AJAX is enabled. You should
   * always call the base implementation.
   *
   * \sa WWidget::enableAjax()
   */
  virtual void enableAjax();

private:
  Signal<int> requestTooLarge_;

  /*
   * Struct to handle library loading, which delays subsequent JS calls
   * until the library has effectively been loaded.
   */
  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;
  };

  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_;     // session owning this application
  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_;  // internal style sheet
  WLocalizedStrings     *localizedStrings_;
  WT_LOCALE              locale_;
  std::string            oldInternalPath_, newInternalPath_;
  Signal<std::string>    internalPathChanged_;
  bool                   internalPathIsChanged_;
  int                    serverPush_;
  bool			 shouldTriggerUpdate_;
#ifndef WT_TARGET_JAVA
  boost::pool<boost::default_user_allocator_new_delete> *eventSignalPool_;
#endif // WT_TARGET_JAVA
  std::string            javaScriptClass_;
  AjaxMethod             ajaxMethod_;
  WContainerWidget      *dialogCover_;
  bool                   quited_;
  std::string            onePixelGifUrl_;
  bool                   rshLoaded_;
  WWidget               *exposedOnly_;
  WLoadingIndicator     *loadingIndicator_;
  WWidget               *loadingIndicatorWidget_;
  bool                   connected_;
  std::string            htmlClass_, bodyClass_;
  bool                   bodyHtmlClassChanged_;
  bool                   enableAjax_;

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

  std::string              theme_;
  std::vector<std::string> styleSheets_;
  int                      styleSheetsAdded_;

  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_;
  std::set<const char*> javaScriptLoaded_;
  bool autoJavaScriptChanged_;

  EventSignal<> *showLoadingIndicator_, *hideLoadingIndicator_;

  WContainerWidget *timerRoot() const { return timerRoot_; }
  WContainerWidget *dialogCover(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 resourceMapKey(WResource *resource);
  std::string addExposedResource(WResource *resource, const std::string& path);
  void removeExposedResource(WResource *resource);
  WResource *decodeExposedResource(const std::string& resourceMapKey) const;

  /*
   * Methods for application state handling
   */
  bool loadRsh();
  void changeInternalPath(const std::string& path);

#ifdef WT_WITH_OLD_INTERNALPATH_API
  bool oldInternalPathAPI() const;
#endif // WT_WITH_OLD_INTERNALPATH_API

  /*
   * 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_; }

  void constrainExposed(WWidget *w);
  WWidget *exposeConstraint() const { return exposedOnly_; }

  static bool pathMatches(const std::string& path, const std::string& query);

  /*
   * Methods for audio handling
   */
  SoundManager *getSoundManager();
  SoundManager *soundManager_;

  friend class WebRenderer;
  friend class WebSession;
  friend class WebController;
  friend class EventSignalBase;
  friend class JavaScriptEvent;
  friend class UpdateLockImpl;
  friend class WWidget;
  friend class WMenu;
  friend class WTimer;
  friend class WResource;
  friend class WFileUpload;
  friend class WInteractWidget;
  friend class WServerPushResource;
  friend class WViewWidget;
  friend class WDialog;
  friend class WSound;
  friend class Ext::Dialog;
  friend class Ext::MessageBox;
};

#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

#ifndef WT_TARGET_JAVA
#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 // DOXYGEN_ONLY
extern int WTCONNECTOR_API WRun(int argc, char** argv,
				ApplicationCreator createApplication = 0);

#endif // DOXYGEN_ONLY
#endif // WT_TARGET_JAVA

/*! \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_
