#ifndef ADS_WIDGETS_H_
#define ADS_WIDGETS_H_

#include "ads_data.h"

#include <QObject>
#include <QWidget>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QToolButton>
#include <QAction>
#include <QSlider>

class AdsWidgetBase: public QObject
{
  //Q_OBJECT

public:
  AdsWidgetBase(QWidget* w=0);

  void attachTo(AdsLogicData&, bool subwidget=true);

  void setWidget(QWidget* w);

  QWidget* widget() { return dW;}

  virtual void invalidateWidget(const QString&);

protected:
  virtual QWidget* onAttachTo();

  QWidget* dW;

  AdsLogicData* d;

};


class AdsWidgetIntRef: public AdsWidgetBase //public QWidget
{
  Q_OBJECT

public:
  AdsWidgetIntRef(QSpinBox&);

public slots:
  void usrUpdated(int);
  void onUpdated();

  virtual void invalidateWidget(const QString&);

private:
  virtual QWidget* onAttachTo();

  QSpinBox& sb;
};

class AdsWidgetInt: public AdsWidgetIntRef
{
  Q_OBJECT

public:
  AdsWidgetInt();

private:
  QSpinBox theSB;
};

class AdsWidgetIntSliderRef: public AdsWidgetBase
{
  Q_OBJECT

public:
  AdsWidgetIntSliderRef(QSlider&);

  virtual void invalidateWidget(const QString&);

public slots:
  void usrUpdated(int);
  void onUpdated();

private:
  virtual QWidget* onAttachTo();

  QSlider& sb;
};

class AdsWidgetBoolRef: public AdsWidgetBase
{
  Q_OBJECT

public:
  AdsWidgetBoolRef(QCheckBox&);

  virtual void invalidateWidget(const QString &);

public slots:
  void usrUpdated(bool);
  void onUpdated();

private:
  virtual QWidget* onAttachTo();

  QCheckBox& cb;
};

class AdsWidgetEnumRef: public AdsWidgetBase
{
  Q_OBJECT

public:
  AdsWidgetEnumRef(QComboBox&);

  virtual void invalidateWidget(const QString&);

public slots:
  void usrUpdated(int);
  void onUpdated();

private:
  virtual QWidget* onAttachTo();

  QComboBox& cb;
};


class AdsWidgetEnum: public AdsWidgetEnumRef
{
  Q_OBJECT

public:
  AdsWidgetEnum();

private:
  QComboBox theCB;
};

class AdsWidgetRealRef: public AdsWidgetBase
{
  Q_OBJECT

public:
  AdsWidgetRealRef(QDoubleSpinBox&);

  virtual void invalidateWidget(const QString&);

public slots:
  void usrUpdated(double);
  void onUpdated();

private:
  virtual QWidget* onAttachTo();

  QDoubleSpinBox& sb;
};

class AdsWidgetReal: public AdsWidgetRealRef
{
  Q_OBJECT

public:
  AdsWidgetReal();

private:
  QDoubleSpinBox theSB;
};


class AdsWidgetActionRef: public QObject
{
  Q_OBJECT

public:
  AdsWidgetActionRef(QAction&, AdsDataAction* ads=0);

  void attachTo(AdsDataAction* a);

public slots:
  void onAdsActionTriggered(bool);
  void onAdsActionToggled(bool);
  void onAdsActionTriggered();

protected:
  QAction& act;
  AdsDataAction* adsAct;
};

class AdsWidgetPushButtonRef: public AdsWidgetBase
{
  Q_OBJECT

public:
  AdsWidgetPushButtonRef(QAbstractButton& r);

  void setClickAdsAction(AdsDataAction* a);

  QWidget* onAttachTo();

  QAbstractButton& button() { return pb;}

protected slots:
  void onAdsClicked();
  void onAdsToggled(bool);
  void onUpdated();

protected:
    QAbstractButton& pb;
    AdsDataAction* actClicked;
};

class AdsWidgetPushButton: public QToolButton
{
  Q_OBJECT

public:
  typedef void (*callback_t)(AdsWidgetPushButton&);

  AdsWidgetPushButton();
  virtual ~AdsWidgetPushButton();

  void attachTo(AdsLogicData&, AdsDataAction* a);
  void attachTo(AdsLogicData&, int value);

  void setPushAction(AdsDataAction* a);

protected slots:
  void buttonPushed();

protected:
  AdsLogicData* d;
  AdsDataAction* actPush;
  bool actPushDestroy;

  virtual void onPushed();
};



class AdsWidgetsManager
{
public:
  static void installForm(QObject* f);

  static void mapAction(AdsDataAction& ads_action, QAction& q_act, bool add_as_shortcut=true);
};

#endif /*WDS_WIDGETS_H_*/
