/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          ccalendar.h  -  description
                             -------------------
    begin                : Sun Aug 18 2002
    copyright            : (C) 2002-2005 by Alexey Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 of the License, or (at 
   your option) any later version.

   This library is distributed in the hope that it will be useful, but 
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef __CCALENDAR_H__
#define __CCALENDAR_H__

class Fl_Box;
class Fl_Button;

#include <sptk3/CPopupWindow.h>
#include <sptk3/CControl.h>
#include <sptk3/CDateTime.h>
#include <sptk3/CLayoutClient.h>

/// @addtogroup gui GUI Classes
/// @{

/// @brief Calendar widget
///
/// A calendar class implements one month calendar.
/// The calendar window allows to select the date.
/// You can change a day, a month and a year selected in the widget.
class SP_EXPORT CCalendar : public Fl_Group, public CLayoutClient {
   Fl_Group  *m_headerBox;
   Fl_Group  *m_buttonBox;
   Fl_Box    *m_monthNameBox;
   Fl_Box    *m_dayNameBoxes[7];
   Fl_Button *m_dayButtons[31];
   Fl_Button *m_switchButtons[4];
   CDateTime  m_date;
   std::string m_headerLabel;
   int        m_activeButtonIndex;
   char       m_weekDayLabels[14];

   /// Day button callback class function
   static void cbDayButtonClicked(Fl_Widget *,void *);

   /// Month button callback class function
   static void cbSwitchButtonClicked(Fl_Widget *,void *);

   /// Constructor initializer
   void ctor_init();

protected:   
   /** The reaction function for the clicking on one of the day buttons. Internal. */
   void dayButtonClicked(unsigned long day);

   /** The reaction function for the clicking on one of the month change buttons. Internal. */
   void switchButtonClicked(long monthChange);

public:

   /** SPTK-style constructor
    * @param label const char *, the widget label
    * @param layoutSize int, the size of widget in layout
    * @param layoutAlignment CLayoutAlign, widget align in the layout
    */
   CCalendar(const char * label,int layoutSize=20,CLayoutAlign layoutAlignment=SP_ALIGN_TOP);

   /** FLTK-style constructor
    * @param x int, widget x-coordinate
    * @param y int, widget y-coordinate
    * @param w int, widget width
    * @param h int, widget height
    * @param label int, optional widget label
    */
   CCalendar(int x,int y,int w,int h,const char *label=0L);

   /** Widget resize
    * @param x int, widget x-coordinate
    * @param y int, widget y-coordinate
    * @param w int, widget width
    * @param h int, widget height
    */
   void resize(int x,int y,int w,int h);

   /** Reports the maximum height of the calendar widget */
   int  maxHeight() const;

   /** Resizes widget to the optimal height, considering minHeight */
   void autoHeight(int minHeight);

   /** Sets the calendar date */
   void      date(CDateTime dt);

   /** Reports the calendar date */
   CDateTime date() const;
};

/// @brief Popup Calendar
///
/// Creates a popup window with the calendar widget on it.
/// Allows to select day, month, and year with increment/decrement buttons.
class SP_EXPORT CPopupCalendar : public CPopupWindow {
   friend class CCalendar;
   CCalendar     *m_calendar;    ///< The calendar widget
   Fl_Widget     *m_dateControl; ///< The widget that shows the pop-up calendar
protected:
   int  handle(int);             ///< Internal handle() function for the FLTK widgets
public:
   /** Constructor
    * @param dateControl Fl_Widget, the widget the shows the popup calendar
    */
   CPopupCalendar(Fl_Widget *dateControl);

   /** Attaches the calendar to another widget */
   void      attachTo(Fl_Widget *dateControl) { m_dateControl = dateControl; }

   /** Widget resize
    * @param x int, widget x-coordinate
    * @param y int, widget y-coordinate
    * @param w int, widget width
    * @param h int, widget height
    */
   void      resize(int x,int y,int w,int h);

   /** Function that is used to report that calendar is clicked on and should be hidden. */
   void      clicked() { m_clicked = 1; }

   /** Sets the calendar date */
   void      date(CDateTime dt) { m_calendar->date(dt); }

   /// Reports the calendar date
   /// @returns CDateTime value of the currently selected date
   CDateTime date() const       { return m_calendar->date(); }

   /// Shows the calendar in modal mode. The only difference from standard 
   /// modal mode is that if you click anywhere outside the calendar window and it closes.
   /// @returns true if date was selected
   bool      showModal();
};

/// @}

#endif
