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

#include <Wt/Ext/MessageBox>
#include <Wt/Ext/ExtDllDefs.h>

namespace Wt {
  namespace Ext {

/*! \class ProgressDialog Wt/Ext/ProgressDialog Wt/Ext/ProgressDialog
 *  \brief A standard dialog to inform the user of progress during
 *         a time consuming task.
 *
 * A progress bar is shown to show progress from minimum() to
 * maximum(), with the current value within (this range) set using
 * setValue(). When the user cancels the dialog, the dialog is hidden
 * and the canceled() signal is emitted.
 *
 * The progress dialog may be used in two ways.
 *
 * The easiest way is using a code snippet like this:
 * \code
 * Wt::Ext::ProgressDialog progress("Converting contact details...", "Cancel", 0, contacts_.size());
 * progress.setWindowTitle("Import Contacts");
 *
 * for (unsigned i = 0; i < contacts_.size(); ++i) {
 *   progress.setValue(i);
 *
 *   Wt::WApplication::instance()->processEvents();
 *
 *   if (!progress.wasCanceled()) {
 *     convertContactDetails(contacts_[i]);
 *   } else {
 *     Wt::Ext::MessageBox::show("Operation cancelled",
 *	       "You may import your contact details any time later.", Ok);
 *     break;
 *   }
 * }
 * \endcode
 *
 * Using this approach, WApplication::processEvents() is used to
 * synchronize the server and client state. This approach has the
 * drawback that browser interactivity is limited.
 *
 * The more involved approach involves the use of WTimer to update the progress
 * in conjunction with a worker thread to do the actual work.
 *
 * \image html ExtProgressDialog-1.png "Example of a ProgressDialog"
 *
 * \ingroup ext
 */
class WT_EXT_API ProgressDialog : public MessageBox
{
public:
  /*! \brief Create a new progress dialog.
   *
   * Creates a new dialog, with window title 'Progress...', no message,
   * and a Cancel button. The progress range is defined from 0 to 100.
   */
  ProgressDialog(bool i18n = false);

  /*! \brief Create a new progress dialog.
   *
   * Creates a new dialog, with window title 'Progress...', the given
   * message, and a Cancel button. The progress range is defined from
   * <i>minimum</i> to <i>maximum</i>
   */
  ProgressDialog(const WString& text, const WString& cancelButtonText,
		 int minimum, int maximum, bool i18n = false);


  /*! \brief Set the minimum value.
   */
  void setMinimum(int minimum);

  /*! \brief Return the minimum value.
   */
  int minimum() const { return minimum_; }

  /*! \brief Set the maximum value.
   */
  void setMaximum(int maximum);

  /*! \brief Return the maximum value.
   */
  int maximum() const { return maximum_; }

  /*! \brief Define the range.
   */
  void setRange(int minimum, int maximum);

  /*! \brief Cancel the dialog.
   *
   * Sets the state to cancelled, and hides the dialog. Calling this
   * method does not emit the
   * \link ProgressDialog::canceled canceled\endlink signal.
   */
  void cancel();

  /*! \brief Reset the dialog.
   *
   * The value is reset to the minimum(), and the cancelled state is cleared.
   */
  void reset();

  /*! \brief Set the text used for the cancel button.
   */
  void setCancelButtonText(const WString& text);

  /*! \brief Set the current value (in the range from minimum() to maximum()).
   */
  void setValue(int progress);

  /*! \brief Return the current value.
   */
  int value() const { return value_; }

  /*! \brief Return if the progress dialog was cancelled.
   *
   * \sa canceled, cancel()
   */
  bool wasCanceled() const { return wasCanceled_; }

  // TODO: add minimumDuration stuff

  /*! \brief %Signal emitted when the user cancels the dialog.
   *
   * When the user cancels the dialog, the dialog is hidden, and the state is
   * set to being cancelled.
   *
   * \sa wasCanceled()
   */
  Signal<>& canceled() { return canceled_; }

protected:
  virtual std::string buttonText(int buttonIndex) const;

private:
  Signal<> canceled_;
  WString cancelButtonText_;
  int minimum_;
  int maximum_;
  int value_;
  bool wasCanceled_;

  void onButtonClick(StandardButton b);
};

  }
}

#endif // EXT_PROGRESS_DIALOG_H_
