#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>

#include <Eigen/Eigen>

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "FImage.hpp"
#include "pyramids.hpp"

using namespace Eigen;

typedef struct
{
    float x, y, f;
} Spreadlet;

int main(int argc, char *argv[])
{
    // Open spreadlets files and compute a vector of cumulative sums
    std::vector<Spreadlet> spreadlets;
    std::vector<int> cumsum;
    cumsum.push_back(0);
    {
        std::string path = argv[1];
        path += "_sizes.bin";
        FILE *in = fopen(path.c_str(), "rb");
        int size;
        while(fread(&size, sizeof(int), 1, in) == 1)
            cumsum.push_back(size + cumsum.back());
        fclose(in);
        
        path = argv[1];
        path += "_data.bin";
        in = fopen(path.c_str(), "rb");
        spreadlets.resize(cumsum.back());
        fread(&spreadlets[0], sizeof(Spreadlet), cumsum.back(), in);
        fclose(in);
    }
    
    std::cout << "Read " << spreadlets.size() << " spreadlets" << std::endl;
    
    FImage base(312, 512);
    for(Spreadlet &s : spreadlets)
        base(155 + (int)s.y, 153 + (int)s.x) = s.f;
    
    poissonPrepare(base.cols(), base.rows());
    
    FImage integrate = poissonIntegrate(base);
    
    std::cout << integrate.sum() << std::endl;
    float maxval = integrate.maxCoeff();
    std::cout << maxval << std::endl;
    integrate *= 255 / maxval;
    save(integrate, "integrate.png");
    
    return 0;
}
