#ifndef SWITCH_H
#define SWITCH_H

#include <QAbstractButton>
#include <QColor>
#include <QPropertyAnimation>
#include <QPoint>

class Switch : public QAbstractButton {
    Q_OBJECT
    Q_PROPERTY(qreal offset READ offset WRITE setOffset NOTIFY offsetChanged)
public:
    explicit Switch(QWidget *parent = nullptr);

    QSize sizeHint() const override;

    qreal offset() const { return m_offset; }
    void setOffset(qreal v);

    QColor onColor() const { return m_on; }
    void setOnColor(const QColor &c) { m_on = c; update(); }

    QColor offColor() const { return m_off; }
    void setOffColor(const QColor &c) { m_off = c; update(); }

    QColor knobColor() const { return m_knob; }
    void setKnobColor(const QColor &c) { m_knob = c; update(); }

signals:
    void offsetChanged(qreal);

protected:
    void paintEvent(QPaintEvent *) override;
    void mousePressEvent(QMouseEvent *e) override;
    void mouseMoveEvent(QMouseEvent *e) override;
    void mouseReleaseEvent(QMouseEvent *e) override;
    void keyPressEvent(QKeyEvent *e) override;
    void checkStateSet() override; // sync offset when checked state changes

    void nextCheckState() override; // to animate on keyboard toggle

private:
    void animateToChecked(bool checked);

    qreal m_offset {0.0}; // 0.0 (off, left) .. 1.0 (on, right)
    bool m_dragging {false};
    QPoint m_pressPos;
    qreal m_pressOffset {0.0};
    bool m_pressChecked {false};
    int m_dragStartThreshold {3}; // px

    int m_width {30};   // total track width
    int m_height {18};  // total track height
    int m_margin {2};   // inner padding

    QColor m_on { QColor(0xB0, 0xE2, 0x37) };       // gradient start; actual paint uses gradient
    QColor m_off { QColor(129, 131, 136, 255) };
    QColor m_knob { QColor(250, 250, 250, 255) };

    QPropertyAnimation m_anim;
};

#endif // SWITCH_H
