#ifndef MOUSEHANDLER_H
#define MOUSEHANDLER_H

#include <QMouseEvent>
#include "routenetwork.h"

class FlyingLabels;
class ProblemInstance;
class DrawingArea;

enum MouseAnchorType {
    VERTEX, INTERSECTION, POSITION
};
struct MouseAnchor
{
    MouseAnchor() {}
    QPointF position;
    VertexId vertexId;
    MouseAnchorType type;
};

enum MouseModeType {
    DEFAULT_MODE,
    NETWORK_CREATION_MODE,
    ROUTE_CREATION_MODE,
    TRANSLATION_MODE,

    NUMBER_OF_MODES
};

class MouseHandler;

class MouseMode {
public:
    MouseMode(MouseHandler* parent);
    virtual ~MouseMode();

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

    virtual void activate();
    virtual void deactivate();

    virtual void mousePressEvent(QMouseEvent* event, QPointF const& cursor) = 0;
    virtual void mouseMoveEvent(QMouseEvent* event, QPointF const& cursor) = 0;
    virtual void mouseReleaseEvent(QMouseEvent* event, QPointF const& cursor) = 0;

    virtual void draw(DrawingArea* drawing) = 0;

protected:
    void setMode(MouseModeType mode);

    ProblemInstance& problemInstance();
    RouteNetwork& routeNetwork();
    MouseAnchor& currentAnchor();

    virtual void updatePosition(QPointF const& position);
    void makeAnchorIntoVertex(MouseAnchor& anchor);

private:
    MouseHandler* _parent;
};

class MouseHandler
{
public:
    explicit MouseHandler(FlyingLabels& parent);
    ~MouseHandler();

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

    void draw(DrawingArea* drawing);

    void mousePressEvent(QMouseEvent* event, QPointF const& cursor);
    void mouseMoveEvent(QMouseEvent* event, QPointF const& cursor);
    void mouseReleaseEvent(QMouseEvent* event, QPointF const& cursor);

private:
    friend class MouseMode;

    void setMode(MouseModeType mode);

    FlyingLabels& _parent;
    MouseAnchor _currentAnchor;

private:
    MouseMode* _currentMode;
    MouseMode* _modes[NUMBER_OF_MODES];
};

#endif // MOUSEHANDLER_H
