//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Scene/MaskGraphicsScene.h
//! @brief     Defines class MaskGraphicsScene.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#ifndef BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSSCENE_H
#define BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSSCENE_H

#include "GUI/View/Setup/Canvas2DMode.h"
#include <QGraphicsScene>
#include <QMap>
#include <memory>

class ColorMap;
class Data2DItem;
class IOverlay;
class LineItem;
class MaskEditorAction;
class MaskGraphicsProxy;
class MaskItem;
class MasksSet;
class OverlayItem;
class PolygonOverlay;

//! Associated with MaskGraphicsViews, holds ColorMap and masks.

class MaskGraphicsScene : public QGraphicsScene {
    Q_OBJECT
public:
    MaskGraphicsScene();
    ~MaskGraphicsScene() override;

    void associateItems(Data2DItem* data_item);
    void updateSize(const QSize& newSize);
    void cancelCurrentDrawing();

    ColorMap* colorMap() { return m_plot.get(); }

signals:
    void itemContextMenuRequest(const QPoint& point);
    void lineItemProcessed();
    void lineItemMoved(LineItem* sender);
    void lineItemDeleted(const LineItem* sender);

public slots:
    void onActivityChanged(Canvas2DMode::Flag mode);

private:
    void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
    void drawForeground(QPainter* painter, const QRectF& rect) override;
    void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;

    void updateOverlays();
    IOverlay* registerOverlay(OverlayItem* item);
    void removeOverlay(OverlayItem* item);
    void addLine(LineItem*);

    void setDrawingInProgress(bool value);

    void makeViewAtMousePosSelected(QGraphicsSceneMouseEvent* event);

    void processRectangleOrEllipseItem(QGraphicsSceneMouseEvent* event);
    void processPolygonItem(QGraphicsSceneMouseEvent* event);
    void processLineItem(QGraphicsSceneMouseEvent* event);
    void processVerticalLineItem(const QPointF& pos);
    void processHorizontalLineItem(const QPointF& pos);
    void processFullframeItem(QGraphicsSceneMouseEvent* event);

    bool isValidMouseClick(QGraphicsSceneMouseEvent* event) const;
    bool isValidForRectangleShapeDrawing(QGraphicsSceneMouseEvent* event) const;
    bool isValidForPolygonDrawing(QGraphicsSceneMouseEvent* event) const;
    bool isValidForLineDrawing(QGraphicsSceneMouseEvent* event) const;
    bool isValidForMaskAllDrawing(QGraphicsSceneMouseEvent* event) const;

    PolygonOverlay* currentPolygon() const;

    std::unique_ptr<ColorMap> m_plot;
    MaskGraphicsProxy* m_proxy = nullptr;
    MasksSet* m_masks = nullptr;
    MasksSet* m_prjns = nullptr;
    QMap<const OverlayItem*, IOverlay*> m_mask2overlay;
    bool m_mouse_is_pressed = false;
    Data2DItem* m_data_item = nullptr;
    MaskItem* m_active_mask = nullptr;
    QPointF m_mouse_position;
    bool m_drawing_in_progress = false;
    bool m_mask_value = true;
    Canvas2DMode::Flag m_mode;
};

#endif // BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSSCENE_H
