#ifndef IMAGESCROLLAREAGL_H
#define IMAGESCROLLAREAGL_H

#include <memory>
#include <QObject>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_2_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject>
#include <QScrollBar>
#include "rawimage.h"

typedef enum
{
    Linear,
    Log,
    Sqrt,
    Power,
    Asinh,
}StretchFunc;

class ImageWidget : public QOpenGLWidget
{
    Q_OBJECT
    QOpenGLFunctions *f;
    std::unique_ptr<QOpenGLShaderProgram> m_program;
    std::unique_ptr<QOpenGLBuffer> m_buffer;
    std::unique_ptr<QOpenGLTexture> m_image;
    std::unique_ptr<QOpenGLVertexArrayObject> m_vao;
    std::unique_ptr<QOpenGLPixelTransferOptions> m_transferOptions;
    int m_width, m_height;
    int m_imgWidth, m_imgHeight;
    float m_low;
    float m_mid;
    float m_high;
    float m_range;
    float m_dx, m_dy;
    float m_scale;
    bool m_blockRepaint;
    bool m_bwImg;
    bool m_invert;
    bool m_superpixel;
public:
    explicit ImageWidget(QWidget *parent = nullptr);
    ~ImageWidget();
    void setImage(const RawImage *image);
    void setImage(const QPixmap &pixmap);
    void setScale(float scale);
    void blockRepaint(bool block);
public slots:
    void setMTFParams(float low, float mid, float high);
    void setOffset(int dx, int dy);
    void superPixel(bool enable);
    void invert(bool enable);
    QImage renderToImage();
protected:
    void paintGL();
    void resizeGL(int w, int h);
    void initializeGL();
};

class ImageScrollAreaGL : public QWidget
{
    Q_OBJECT
    QScrollBar *m_verticalScrollBar;
    QScrollBar *m_horizontalScrollBar;
    ImageWidget *m_imageWidget;
    int m_imgWidth, m_imgHeight;
    QPoint m_lastPos;
    float m_scale;
    bool m_bestFit;
public:
    explicit ImageScrollAreaGL(QWidget *parent = nullptr);
    ~ImageScrollAreaGL();
    void setImage(RawImage *image);
    void setImage(const QPixmap &pixmap);
    ImageWidget* imageWidget();
protected:
    void updateScrollbars(bool zoom = false);
    void resizeEvent(QResizeEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
    void zoom(float delta);
public slots:
    void zoomIn();
    void zoomOut();
    void bestFit();
    void oneToOne();
protected slots:
    void scrollEvent();
};

#endif // IMAGESCROLLAREAGL_H
