#ifndef SHSBUTTON_H
#define SHSBUTTON_H

#include <QToolButton>
#include <QFrame>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QDebug>
#include "SH_runtime.h"
#include "shs_widgets_export.h"

QT_BEGIN_NAMESPACE

class SHS_WIDGETS_EXPORT SHSButton: public QToolButton
{
	Q_OBJECT
	Q_ENUMS(State)
	Q_PROPERTY(QColor downColor READ downColor WRITE setDownColor)
	Q_PROPERTY(QColor upColor READ upColor WRITE setUpColor)
	Q_PROPERTY(QColor grayColor READ grayColor WRITE setGrayColor)
	Q_PROPERTY(QColor yesColor READ yesColor WRITE setYesColor)
	Q_PROPERTY(QColor noColor READ noColor WRITE setNoColor)
	Q_PROPERTY(QColor h__currentColor READ currentColor WRITE setCurrentColor DESIGNABLE false)
	Q_PROPERTY(State state READ state WRITE setState)
	Q_PROPERTY(bool buttonVisible READ isButtonVisible WRITE setButtonVisible)
	Q_PROPERTY(bool autoGray READ autoGray WRITE setAutoGray)
	Q_PROPERTY(bool animated READ animated WRITE setAnimated)
	Q_PROPERTY(int animationDuration READ animationDuration WRITE setAnimationDuration)
	Q_PROPERTY(int releaseDuration READ releaseDuration WRITE setReleaseDuration)
	Q_PROPERTY(QEasingCurve::Type animationCurve READ animationCurve WRITE setAnimationCurve)
	Q_PROPERTY(int blinkDelay READ blinkDelay WRITE setBlinkDelay)
	Q_PROPERTY(int clickID READ clickID WRITE setClickID)
	Q_PROPERTY(int yesID READ yesID WRITE setYesID)
	Q_PROPERTY(int noID READ noID WRITE setNoID)
	Q_PROPERTY(QString command READ command WRITE setCommand)
	friend class RPiWindow;

public:
	explicit SHSButton(QWidget * parent = 0);
	SHSButton(int id, const QString & text = QString());
	~SHSButton();
	
	enum State {Gray, Yes, No};
	
	int clickID() const {return id_click;}
	int yesID() const {return id_yes;}
	int noID() const {return id_no;}
	const QString & command() const {return command_;}
	
	QColor downColor() const {return col_down;}
	QColor upColor() const {return col_up;}
	QColor grayColor() const {return col_gray;}
	QColor yesColor() const {return col_yes;}
	QColor noColor() const {return col_no;}
	QColor currentColor() const {return col_cur;}
	State state() const {return state_;}
	bool isButtonVisible() const {return bdebug_ ? visible_ : QToolButton::isVisible();}
	bool autoGray() const {return auto_gray;}
	bool animated() const {return anim;}
	int animationDuration() const {return anim_;}
	int releaseDuration() const {return rele_;}
	QEasingCurve::Type animationCurve() const {return animation.easingCurve().type();}
	int blinkDelay() const {return delay_blink;}
	
	void blink(const QColor & tc);
	
	void buildDebug() {bdebug_ = true; if (dtimer < 0) dtimer = startTimer(1000);}
	
	static void parseCommand(QString all, QString * dev = 0, QString * cmd = 0, QVector<QVariant> * args = 0);

private:
	QSize sizeHint() const;
	QSize minimumSizeHint() const;
	bool eventFilter(QObject * o, QEvent * e);
	void timerEvent(QTimerEvent * e);
	void paintEvent(QPaintEvent * );
	void mousePressEvent(QMouseEvent * e);
    void mouseReleaseEvent(QMouseEvent * e);
	
	void init();
	void drawButton(QPainter & p);
	bool autoConnect();
	void checkConnected();
	void animateColor(const QColor & tc, bool release = false);
	void applyColor() {pal.setColor(QPalette::Button, col_cur); setPalette(pal);}
	void applyState(State s);

	QPalette pal;
	QColor col_down, col_up, col_gray, col_yes, col_no, col_cur, col_dst, col_blink;
	QPropertyAnimation animation;
	QString command_;
	QImage image_conn, image_disconn, image_invisible;
	QWidget * pw;
	State state_;
	int id_click, id_yes, id_no, delay_blink, timer, dtimer, anim_, rele_;
	bool anim, auto_gray, _first, bdebug_, connected_, visible_;
	
private slots:
	void _clicked() {emit clickedID(id_click);}
	void _toggled(bool on) {if (!on && auto_gray) setStateGray(); emit toggledID(id_click, on);}

public slots:
	void enable() {setEnabled(true);}
	void disable() {setStateGray(); setEnabled(false);}
	
	void setClickID(int id) {id_click = id; checkConnected();}
	void setYesID(int id) {id_yes = id;}
	void setNoID(int id) {id_no = id;}
	void setButtonVisible(bool yes) {if (bdebug_) {visible_ = yes; update();} else QToolButton::setVisible(yes);}
	void setCommand(const QString & cmd) {command_ = cmd; checkConnected();}
	
	void setDownColor(const QColor & col) {col_down = col;}
	void setUpColor(const QColor & col) {col_up = col;}
	void setGrayColor(const QColor & col) {col_gray = col;}
	void setYesColor(const QColor & col) {col_yes = col;}
	void setNoColor(const QColor & col) {col_no = col;}
	
	
	void setState(State s);
	void setStateGray() {col_dst = col_gray; applyState(Gray); animateColor(col_dst);}
	void setStateYes() {col_dst = col_yes; applyState(Yes); animateColor(col_dst);}
	void setStateNo() {col_dst = col_no; applyState(No); animateColor(col_dst);}
	void setStateYesOrNo(bool yes) {if (yes) setStateYes(); else setStateNo();}
	void setStateYesOrGray(bool yes) {if (yes) setStateYes(); else setStateGray();}
	void setStateNoOrYes(bool no) {if (no) setStateNo(); else setStateYes();}
	void setStateNoOrGray(bool no) {if (no) setStateNo(); else setStateGray();}
	
	void blinkYes() {blink(col_yes);}
	void blinkNo() {blink(col_no);}
	void blinkYesOrNo(bool yes) {blink(yes ? col_yes : col_no);}
	void blinkNoOrYes(bool no) {blink(no ? col_no : col_yes);}
	
	
	void enableID(int yes_id) {if (yes_id == id_yes) enable();}
	void disableID(int yes_id) {if (yes_id == id_yes) disable();}
	
	void setStateID(int yes_id, State s) {if (yes_id == id_yes) setState(s);}
	void setStateGrayID(int yes_id) {if (yes_id == id_yes) setStateGray();}
	void setStateYesID(int yes_id) {if (yes_id == id_yes) setStateYes();}
	void setStateNoID(int no_id) {if (no_id == id_no) setStateNo();}
	void setStateYesOrNoID(int yes_id, bool yes) {if (yes_id == id_yes) setStateYesOrNo(yes);}
	void setStateYesOrGrayID(int yes_id, bool yes) {if (yes_id == id_yes) setStateYesOrGray(yes);}
	void setStateNoOrYesID(int no_id, bool no) {if (no_id == id_no) setStateNoOrYes(no);}
	void setStateNoOrGrayID(int no_id, bool no) {if (no_id == id_no) setStateNoOrGray(no);}
	
	void setStateYesIDOrGray(int yes_id) {setStateYesOrGray(yes_id == id_yes);}
	void setStateYesIDOrNo(int yes_id) {setStateYesOrNo(yes_id == id_yes);}
	void setStateNoIDOrYes(int no_id) {setStateNoOrYes(no_id == id_no);}
	void setStateNoIDOrGray(int no_id) {setStateNoOrGray(no_id == id_no);}
	
	void blinkYesID(int yes_id) {if (yes_id == id_yes) blinkYes();}
	void blinkNoID(int no_id) {if (no_id == id_no) blinkNo();}
	void blinkYesOrNoID(int yes_id, bool yes) {if (yes_id == id_yes) blinkYesOrNo(yes);}
	void blinkNoOrYesID(int no_id, bool no) {if (no_id == id_no) blinkNoOrYes(no);}
	
	
	void setColor(const QColor & col) {col_dst = col; animateColor(col_dst);}
	void setCurrentColor(const QColor & col) {col_cur = col; applyColor();}
	
	void setAutoGray(bool yes) {auto_gray = yes;}
	void setAnimated(bool yes) {anim = yes;}
	void setAnimationDuration(int dur) {anim_ = dur;}
	void setReleaseDuration(int dur) {rele_ = dur;}
	void setAnimationCurve(QEasingCurve::Type curve) {animation.setEasingCurve(QEasingCurve(curve));}
	void setBlinkDelay(int dur) {delay_blink = dur;}
	
	void delayedClick() {QMetaObject::invokeMethod(this, "click", Qt::QueuedConnection);}
	void delayedToggle() {QMetaObject::invokeMethod(this, "toggle", Qt::QueuedConnection);}
	
	void delayedClickID(int yes_id) {if (yes_id == id_yes) delayedClick();}
	void delayedToggleID(int yes_id) {if (yes_id == id_yes) delayedToggle();}
	
signals:
	void clickedID(int id);
	void pressedID(int id);
	void releasedID(int id);
	void toggledID(int id, bool on);
	void stateChanged(State state, State prev_state);
	void stateChangedID(int id, State state, State prev_state);

};

QT_END_NAMESPACE

#endif // SHSBUTTON_H
