#ifndef DRAWINGAREA_H
#define DRAWINGAREA_H

#include <QWidget>
#include <QImage>
#include <QMouseEvent>
#include <QPointF>
#include <QFont>

class FlyingLabels;
class LabelModel;

class DrawingArea : public QWidget
{
Q_OBJECT
public:
    explicit DrawingArea(QWidget* parent = nullptr);

    DrawingArea(DrawingArea const&) = delete;
    DrawingArea& operator=(DrawingArea const&) = delete;

    void startDrawing();

    void drawImage(QRectF const& rect, QImage const& image);

    void drawExistingVertex(QPointF const& position);
    void drawNewVertex(QPointF const& position);
    void drawVertex(QPointF const& position, bool preExisting);
    void drawPoint(QPointF const& position, bool hasFreeLabel);

    void drawVertexSelection(QPointF const& position);

    void drawExistingEdge(QPointF const& start, QPointF const& end);
    void drawNewEdge(QPointF const& start, QPointF const& end);
    void drawEdge(QPointF const& start, QPointF const& end, bool preExisting);

    void drawExistingRouteAnchor(QPointF const& position);
    void drawNewRouteAnchor(QPointF const& position);
    void drawRouteAnchor(QPointF const& position, bool preExisting);

    void drawExistingRouteArrow(QPointF const& start, QPointF const& end);
    void drawNewRouteArrow(QPointF const& start, QPointF const& end);
    void drawRouteArrow(QPointF const& start, QPointF const& end, bool preExisting);

    void drawMissingRoute(QPointF const& start, QPointF const& end);

    void drawLabelBBox(QPointF const& labelCenter, qreal labelFreeness);
    void drawLabelText(QPointF const& labelCenter, QString const& text);
    void drawLabelCenter(QPointF const& labelCenter);
    void drawLabelCandidateSegment(QPointF const& start, QPointF const& end);

    void endDrawing();

    void zoomIn(QPointF const& center, qreal steps);
    void zoomOut(QPointF const& center, qreal steps);
    void resetZoom();

    QPointF const& translation() const;
    void addTranslation(QPointF const& v);
    void resetTranslation();

    void resetZoomAndTranslation() { resetZoom(); resetTranslation(); }

protected:
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);
    void leaveEvent(QEvent* event);
    void wheelEvent(QWheelEvent* event);

    void paintEvent(QPaintEvent* event);
    void resizeEvent(QResizeEvent* event);

private:
    void applyTransformation(QPainter& painter) const;
    QPointF transform(QPointF const& pos) const;
    QPointF untransform(QPointF const& pos) const;
    void performZoomIn(QPointF const& untransformedCenter, QPointF const& transformedCenter, qreal steps);

    FlyingLabels* mainWindow() const;
    LabelModel const& labelModel() const;
    QFont labelFont() const;

private:
    QImage _image;
    QPointF _viewUpperLeft;
    qreal _zoomFactor, _zoomSteps;
    bool _currentlyDrawing;
};

#endif // DRAWINGAREA_H
