/*
 * This file is part of the xTuple ERP: PostBooks Edition, a free and
 * open source Enterprise Resource Planning software suite,
 * Copyright (c) 1999-2009 by OpenMFG LLC, d/b/a xTuple.
 * It is licensed to you under the Common Public Attribution License
 * version 1.0, the full text of which (including xTuple-specific Exhibits)
 * is available at www.xtuple.com/CPAL.  By using this software, you agree
 * to be bound by its terms.
 */


#ifndef datecluster_h
#define datecluster_h

#include <QDateTime>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

#include "xdatawidgetmapper.h"
#include "xlineedit.h"

class ParameterList;
class QFocusEvent;
class XSqlQuery;

class XDateEdit : public XLineEdit
{
  Q_OBJECT
  Q_ENUMS   (Defaults)
  Q_PROPERTY(QDate    date            READ date        WRITE setDate)
  Q_PROPERTY(Defaults defaultDate     READ defaultDate WRITE setDefaultDate)
  Q_PROPERTY(QDate    currentDefault  READ currentDefault)
  Q_PROPERTY(QString  fieldName       READ fieldName   WRITE setFieldName)

  public:
    XDateEdit(QWidget *parent = 0, const char * = 0);
    virtual ~XDateEdit();
    
    enum Defaults     { Empty, Current, None };

    virtual bool      isNull();
    virtual bool      isValid();
    virtual Defaults  defaultDate()                             { return _default;};
    virtual QDate     currentDefault();
    virtual QDate     date();
    virtual QString   fieldName()   const                       { return _fieldName;        };
    virtual void      clear();
    inline  void      setAllowNullDate(bool pAllowNull)         { _allowNull  = pAllowNull;  };
    inline  void      setNullString(const QString &pNullString) { _nullString = pNullString;};
    inline  void      setNullDate(const QDate &pNullDate)       { _nullDate   = pNullDate;    };

  public slots:
    virtual void setDataWidgetMap(XDataWidgetMapper* m);
    virtual void setFieldName(QString p) { _fieldName = p; };

    void setNull();
    void setDate(const QDate &, bool = false);
    void setDefaultDate(Defaults p)                             { _default = p; };
    void parseDate();
    void showCalendar();

  signals:
    void newDate(const QDate &);

  private:
    bool fixMonthEnd(int *, int, int);
    
    bool          _allowNull;
    enum Defaults _default;
    QDate         _currentDate;
    QDate         _nullDate;
    QString       _fieldName;
    QString       _nullString;

};

class XTUPLEWIDGETS_EXPORT DLineEdit : public QWidget
{
  Q_OBJECT
  Q_ENUMS(XDateEdit::Defaults)
  Q_PROPERTY(QDate                 date            READ date        WRITE setDate)
  Q_PROPERTY(XDateEdit::Defaults   defaultDate     READ defaultDate WRITE setDefaultDate)
  Q_PROPERTY(QString               fieldName       READ fieldName   WRITE setFieldName)

  public:
    DLineEdit(QWidget *parent = 0, const char * = 0);
    
    inline void                 setAllowNullDate(bool p)            { _lineedit.setAllowNullDate(p); };
    inline void                 setNullString(const QString &p)     { _lineedit.setNullString(p); };
    inline void                 setNullDate(const QDate &p)         { _lineedit.setNullDate(p); };

    virtual bool                isNull()                            { return _lineedit.isNull(); };
    virtual bool                isValid()                           { return _lineedit.isValid(); };
    virtual XDateEdit::Defaults defaultDate()                       { return _lineedit.defaultDate(); };
    virtual QDate               date()                              { return _lineedit.date(); };
    virtual QString             fieldName() const                   { return _lineedit.fieldName(); };
    virtual void                clear()                             { _lineedit.clear(); };
      
  public slots:
    virtual void setDataWidgetMap(XDataWidgetMapper* m)             { _lineedit.setDataWidgetMap(m); };
    virtual void setDefaultDate(XDateEdit::Defaults p)              { _lineedit.setDefaultDate(p); };
    virtual void setEnabled(const bool);
    virtual void setFieldName(QString p)                            { _lineedit.setFieldName(p); };

    void setDate(const QDate &p, bool b = false)                    { _lineedit.setDate(p, b); };
    void setNull()                                                  { _lineedit.setNull(); };
    void showCalendar()                                             { _lineedit.showCalendar(); };

  signals:
    void newDate(const QDate &);

  private:
    QPushButton _calbutton;
    XDateEdit   _lineedit;
};


class XTUPLEWIDGETS_EXPORT DateCluster : public QWidget
{
  Q_OBJECT
  Q_PROPERTY(QDate startDate READ startDate WRITE setStartDate)
  Q_PROPERTY(QDate endDate   READ endDate   WRITE setEndDate)

  public:
    DateCluster(QWidget *, const char * = 0);

    void setStartNull(const QString &, const QDate &, bool);
    void setEndNull(const QString &, const QDate &, bool);

    void appendValue(ParameterList &);
    void bindValue(XSqlQuery &);
    
    inline QDate startDate() { return _startDate->date(); };
    inline QDate endDate()   { return _endDate->date();   };

    inline void  setStartDate(const QDate &pDate) { _startDate->setDate(pDate); };
    inline void  setEndDate(const QDate &pDate)   { _endDate->setDate(pDate);   };

    inline bool  allValid() { return ((_startDate->isValid()) && (_endDate->isValid())); };

    void setStartCaption(const QString &);
    void setEndCaption(const QString &);

  signals:
    void updated();

  protected:
    DLineEdit *_startDate;
    DLineEdit *_endDate;

  private:
    QLabel    *_startDateLit;
    QLabel    *_endDateLit;
    QString   _fieldNameStart;
    QString   _fieldNameEnd;
};

#endif

