//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Img3D/View/Canvas.h
//! @brief     Defines class Canvas.
//!
//! @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_IMG3D_VIEW_CANVAS_H
#define BORNAGAIN_IMG3D_VIEW_CANVAS_H

#include "Img3D/Type/FloatVector3D.h"
#include <QHash>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLWidget>

namespace Img3D {

class BodyPlotter;
class Camera;
class Geometry;
class Model;
class PlottableBody;
class Shader;

class Canvas : public QOpenGLWidget, protected QOpenGLFunctions {
    Q_OBJECT
public:
    Canvas();
    ~Canvas() override;

    // active things, owned elsewhere, may be nullptr
    void setCamera(Camera*);
    void setShader(Shader*);
    void setModel(Model*);

    // Toolbar Actions
    void defaultView();
    void sideView();
    void topView();

    const Camera* camera() const { return m_camera.get(); }

private:
    void switchCamera(bool full);

    void initializeGL() override;
    void resizeGL(int, int) override;

    //! Reimplements QOpenGLWidget::paintGL().
    //! This virtual function is called whenever the widget needs to be painted.
    void paintGL() override;

    enum { btnNONE, btnTURN, btnZOOM } mouseButton;
    void mousePressEvent(QMouseEvent*) override;
    void mouseMoveEvent(QMouseEvent*) override;
    void mouseReleaseEvent(QMouseEvent*) override;
    void wheelEvent(QWheelEvent*) override;

    void releaseBuffer(Geometry const*);
    void releaseBuffers();

    bool isInitialized() const;

    void drawBody(const PlottableBody& object);

    QRect viewport;
    float aspectRatio;
    int currentZoomLevel; // current configuration of mousewheel w.r.t to default (0) configuration

    QHash<Geometry const*, BodyPlotter*> m_buffers;

    QPoint m_last_mouse_coords; // latest mouse event's screen coordinates (x,y)
    QMatrix4x4 matModel, matProj;

    std::unique_ptr<Camera> m_camera;
    std::unique_ptr<Shader> m_shader;
    const Model* m_model;

    bool m_is_initializedGL;
};

} // namespace Img3D

#endif // BORNAGAIN_IMG3D_VIEW_CANVAS_H
