// 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 WSOCKETNOTIFIER_H_
#define WSOCKETNOTIFIER_H_

#include <Wt/WObject>
#include <Wt/WSignal>

namespace Wt {

/*! \class WSocketNotifier Wt/WSocketNotifier Wt/WSocketNotifier
 *  \brief A utility class for asynchronous notification of socket activity.
 *
 * Use a aocket notifier to integrate listening for socket events into
 * the %Wt event loop. In this way, you do not need a separate thread
 * to listen for socket activity. Socket activity is either the
 * availability of data to be read (\link WSocketNotifier::Read Read
 * event\endlink), possibility to write data (\link
 * WSocketNotifier::Write Write event\endlink), or an exception that
 * occurred (\link WSocketNotifier::Exception Exception
 * event\endlink).
 *
 * When an event on a socket is available, the notifier emits the
 * \link WSocketNotifier::activated activated\endlink signal. As in
 * the case of a user interface event (like for example
 * WInteractWidget::clicked), you will typically modify the widget
 * tree in response to the event. But, unless you use a timer (WTimer)
 * or use server-initiated updates (see
 * WApplication::triggerUpdates()), these changes are not propagated to
 * the user interface, until the next user interface event.
 *
 * Like other events, socket notification events are serial (not
 * simultaneous), and there are no thread safety issues (you don't
 * need to call WApplication::getUpdateLock() to get an update lock).
 * 
 * <i>Note: At present, WSocketNotifier works only in conjunction with
 * the wthttpd connector, and not when using the FastCGI connector.</i>
 */
class WSocketNotifier : public WObject
{
public:
  /*! \brief Enumeration that event type.
   */
  enum Type { Read,      //!< Ready to read
	      Write,     //!< Ready to write
	      Exception  //!< Exception
  };

  /*! \brief Create a new socket notifier.
   *
   * Create a new socket listener to listen for events of given <i>type</i>
   * on a socket with file descriptor <i>socket</i>.
   */
  WSocketNotifier(int socket, Type type, WObject *parent = 0);

  /*! \brief Delete a socket notifier.
   */
  ~WSocketNotifier();

  /*! \brief Return the socket.
   */
  int socket() const { return socket_; }

  /*! \brief Return the event type.
   */
  Type type() const { return type_; }

  /*! \brief Enable or disable the notifier.
   *
   * By default, the socket notifier is enabled to receive
   * events. When disabled, no events will be notified (as if the
   * socket notifier didn't exist).
   */
  void setEnabled(bool enabled);

  /*! \brief Return if the notifier is enabled.
   */
  bool isEnabled() const { return enabled_; }

  /*! \brief %Signal indicating an event.
   *
   * The signal is emitted when an event that was waited for is
   * available. The signal argument is socket().
   */
  Signal<int> activated;

private:
  int socket_;
  Type type_;
  bool enabled_;
  bool beingNotified_;
  std::string sessionId_;

  const std::string& sessionId() const { return sessionId_; }
  void notify();

  friend class WebController;
};

}

#endif // WSOCKETNOTIFIER_H_
