#pragma once
#include <QQuickPaintedItem>
#include <QImage>
#include <QPointF>
#include <QRect>
#include <QColor>
#include <QMutex>

// Drawing surface. Renders strokes via QPainter into an offscreen QImage that is
// blitted as a texture (QSGPainterNode) — the only stroke-rendering path the
// device's *software* epaper scene-graph backend actually draws (it silently
// drops custom QSGGeometryNodes). The trade-off is the e-ink's grayscale
// two-pass ("dashed→fill") refresh for texture updates; eliminating that needs a
// framebuffer-direct pen path (see doc).
class InkCanvas : public QQuickPaintedItem {
    Q_OBJECT
public:
    explicit InkCanvas(QQuickItem *parent = nullptr);

    void paint(QPainter *painter) override;

public slots:
    void strokeStart(QPointF p);
    void strokeMove(QPointF p, qreal pressure, bool eraser);
    void strokeEnd();
    void clearPage();

    // Experiment harness: clear + draw a fixed recognizable test pattern.
    void drawTestStroke();
    QRect testRectQ() const;

    void setInkColor(const QColor &c) { m_inkColor = c; }
    void setBaseWidth(qreal w) { m_baseWidth = w; }

protected:
    void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;

private:
    void ensureBuffer(const QSize &size);
    void queueRefresh(const QRect &r); // accumulate a region needing a solid swap
    void scheduleFlush();              // coalesce; fire flushRefresh once, soon
    void flushRefresh();               // GUI thread: explicit solid swapBuffers

    QImage m_buffer;
    QPointF m_last;
    bool m_drawing = false;
    QColor m_inkColor = Qt::black;
    qreal m_baseWidth = 8.0;

    QRect m_pending;               // region awaiting an explicit solid refresh
    bool m_flushScheduled = false;
};
