#include "togglegadget.h"
using Xybrid::UI::ToggleGadget;

#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QCursor>

#include <QMenu>

ToggleGadget::ToggleGadget(QGraphicsItem *parent) : Gadget(parent) {
    setAcceptHoverEvents(true);

    font = QFont("Arcon Rounded", 8);
    setFlag(GraphicsItemFlag::ItemClipsToShape, false);
}

QRectF ToggleGadget::boundingRect() const {
    return QRectF(QPointF(0, 0), QSizeF(16, 16));
}

void ToggleGadget::paint(QPainter* p, const QStyleOptionGraphicsItem* opt, QWidget*) {
    auto r = boundingRect();
    //p->fillRect(rect, QColor(255, 0, 0));

    bool hover = opt->state & QStyle::State_MouseOver;

    auto c = color;
    if (!fGet()) c = c.darker();

    QColor outline = QColor(31, 31, 31);

    QRadialGradient fill(r.center(), r.height()/2, QPointF(r.center().x(), r.top()));
    if (pressed) {
        auto c = color.darker(300);
        fill.setFocalPoint(fill.center());
        fill.setColorAt(0.0, c.darker());
        fill.setColorAt(1.0, c);
    } else {
        fill.setColorAt(0.0, c);
        if (hover) fill.setColorAt(0.0, c.lighter(125));
        fill.setColorAt(1.0, c.darker());
    }

    p->setRenderHint(QPainter::RenderHint::Antialiasing);
    p->setBrush(QBrush(fill));
    p->setPen(QPen(QBrush(outline), 2));
    p->drawEllipse(r);

    if (hover) toolTip(text, toolTipPosition, color);
    else toolTip();
}

void ToggleGadget::mousePressEvent(QGraphicsSceneMouseEvent* e) {
    if (e->button() == Qt::LeftButton) {
        pressed = true;
        update();
    }
}
void ToggleGadget::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
    if (e->button() == Qt::LeftButton) {
        if (pressed) {
            fSet(!fGet());
        }
        pressed = false;
        update();
    }
}

void ToggleGadget::hoverEnterEvent(QGraphicsSceneHoverEvent*) { update(); }
void ToggleGadget::hoverLeaveEvent(QGraphicsSceneHoverEvent*) { pressed = false; update(); }

ToggleGadget* ToggleGadget::bind(bool& b) {
    auto p = &b;
    fGet = [p] { return *p; };
    fSet = [p](bool b) { *p = b; };
    return this;
}
