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

#include <Wt/WCompositeWidget>
#include <Wt/WDate>
#include <Wt/WSignalMapper>
#include <set>

namespace boost {
  namespace gregorian {
    class date;
  }
}

namespace Wt {

class WComboBox;
class WInPlaceEdit;
class WTemplate;

/*! \class WCalendar Wt/WCalendar Wt/WCalendar
 *  \brief A calendar.
 *
 * The calendar provides navigation by month and year, and indicates the
 * current day.
 *
 * You can listen for single click or double click events on a
 * calendar cell using the clicked() and activated() methods.
 *
 * The calendar may be configured to allow selection of single or
 * multiple days using setSelectionMode(), and you may listen for
 * changes in the selection using the selectionChanged()
 * signals. Selection can also be entirely disabled in which case you
 * can implement your own selection handling by listening for cell
 * click events.
 *
 * Cell rendering may be customized by reimplementing renderCell().
 *
 * Internationalization is provided by the internationalization
 * features of the Wt::WDate class.
 *
 * \if cpp
 * Usage example:
 * \code
 * Wt::WDate today = Wt::WDate::currentDate();
 *
 * Wt::WCalendar *calendar = new Wt::WCalendar(this);
 * calendar->browseTo(today.addMonths(1));
 * calendar->select(today.addMonths(1).addDays(3));
 * calendar->selected().connect(this, &MyWidget::daySelected);
 * \endcode
 * \endif
 *
 * Here is a snapshot, taken on 19/01/2010 (shown as
 * today), and 14/01/2010 currently selected.
 * <TABLE border="0" align="center"> <TR> <TD> 
 * \image html WCalendar-default-1.png "WCalendar with default look" 
 * </TD> <TD> 
 * \image html WCalendar-polished-1.png "WCalendar with polished look" 
 * </TD> </TR> </TABLE>
 *
 */
class WT_API WCalendar : public WCompositeWidget
{
public:
  /*! \brief The format of the horizontal header.
   */
  enum HorizontalHeaderFormat { 
    SingleLetterDayNames,  //!< First letter of a day (e.g. 'M' for Monday)
    ShortDayNames,         //!< First 3 letters of a day (e.g. 'Mon' for Monday)
    LongDayNames           //!< Full day name
    // NoHorizontalHeader  //No horizontal header (not yet implemented)
  };

  /*! \brief Creates a new calendar.
   *
   * Constructs a new calendar with English day/month names.  The
   * calendar shows the current day, and has an empty selection.
   */
  WCalendar(WContainerWidget *parent = 0);

  /*! \brief Sets the selection mode.
   *
   * The default selection mode is
   * \link Wt::SingleSelection SingleSelection\endlink.
   */
  void setSelectionMode(SelectionMode mode);

  /*! \brief Browses to the same month in the previous year.
   *
   * Displays the same month in the previous year. This does not
   * affect the selection.
   *
   * This will emit the currentPageChanged() singal.
   */
  void browseToPreviousYear();

  /*! \brief Browses to the previous month.
   *
   * Displays the previous month. This does not affect the selection.
   *
   * This will emit the currentPageChanged() singal.
   */
  void browseToPreviousMonth();

  /*! \brief Browses to the same month in the next year.
   *
   * Displays the same month in the next year. This does not change
   * the current selection.
   *
   * This will emit the currentPageChanged() singal.
   */
  void browseToNextYear();

  /*! \brief Browses to the next month.
   *
   * Displays the next month. This does not change the current selection.
   *
   * This will emit the currentPageChanged() singal.
   */
  void browseToNextMonth();

  /*! \brief Browses to a date.
   *
   * Displays the month which contains the given date. This does not change
   * the current selection.
   *
   * This will emit the currentPageChanged() signal if another month
   * is displayed.
   */
  void browseTo(const WDate& date);

  /*! \brief Returns the current month displayed
   *
   * Returns the month (1-12) that is currently displayed.
   */
  int currentMonth() const { return currentMonth_; }

  /*! \brief Returns the current year displayed
   *
   * Returns the year that is currently displayed.
   */
  int currentYear() const { return currentYear_; }

  /*! \brief Clears the current selection.
   *
   * Clears the current selection. Will result in a selection() that is
   * empty().
   */
  void clearSelection();

  /*! \brief Selects a date.
   *
   * Select one date. Both in single or multiple selection mode, this results
   * in a selection() that contains exactly one date.
   */
  void select(const WDate& date);

  /*! \brief Selects multiple dates.
   *
   * Select multiple dates. In multiple selection mode, this results
   * in a selection() that contains exactly the given dates. In single
   * selection mode, at most one date is set.
   */
  void select(const std::set<WDate>& dates);

  /*! \brief Sets the horizontal header format.
   *
   * The default horizontal header format is WCalendar::ShortDayNames.
   */
  void setHorizontalHeaderFormat(HorizontalH                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    