#ifndef RAWIMAGE_H
#define RAWIMAGE_H

#include <vector>
#include <algorithm>
#include <stdint.h>
#include <math.h>
#include <memory.h>
#include <opencv2/imgproc.hpp>
#include <QImage>

class Peak
{
    uint32_t m_v;
    uint32_t m_x,m_y;
public:
    Peak() : m_v(0), m_x(0), m_y(0) {}
    Peak(uint32_t v, uint32_t x, uint32_t y) : m_v(v), m_x(x), m_y(y) {}
    uint32_t v() const { return m_v; }
    uint32_t x() const { return m_x; }
    uint32_t y() const { return m_y; }
    double distance(const Peak &d) const
    {
        uint32_t dx = m_x-d.m_x;
        uint32_t dy = m_y-d.m_y;
        return dx*dx + dy*dy;
    }
    bool operator <(const Peak &d) const
    {
        return m_v > d.m_v;
    }
};

class RawImage
{
protected:
    cv::Mat m_img;
    bool m_stats;
    double m_mean;
    double m_stdDev;
    double m_median;
    double m_min;
    double m_max;
    double m_mad;
public:
    enum ImgType
    {
        UINT8,
        UINT16,
        FLOAT32,
        UINT8C3,
        UINT8C4,
        UINT16C3,
        FLOAT32C3,
        UNKNOWN,
    };
    RawImage();
    RawImage(int w, int h, ImgType type);
    RawImage(cv::Mat &img);
    RawImage(const RawImage &d);
    RawImage(const QImage &img);
    bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad);
    void calcStats();
    void rect(int &x, int &y, int w, int h, std::vector<double> &r) const;
    int findPeaks(double background, double distance, std::vector<Peak> &peaks) const;
    RawImage* medianFilter() const;
    void quarter();
    uint32_t width() const;
    uint32_t height() const;
    uint32_t size() const;
    ImgType type() const;
    uint32_t norm() const;
    void* data();
    const void* data() const;
};

#endif // RAWIMAGE_H
