#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include "../src/rawimage.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

bool loadXISF(const LibXISF::ByteArray &data, std::shared_ptr<RawImage> &rawImage);
bool loadFITS(const LibXISF::ByteArray &data, std::shared_ptr<RawImage> &rawImage);

int main(int argc, char *argv[])
{
    std::vector<std::string> args;
    for(int i=0; i<argc; i++)
        args.push_back(argv[i]);

    if(args.size() < 3)
        return 1;

    std::string input = args[1];
    std::string output = args[2];

    std::shared_ptr<RawImage> rawImage;

    LibXISF::ByteArray data;
    std::ifstream fr;
    fr.open(input, std::ios_base::in | std::ios_base::binary);
    if(!fr.is_open())
        return 2;

    fr.seekg(0, std::ios_base::end);
    size_t len = fr.tellg();
    fr.seekg(0, std::ios_base::beg);
    data.resize(len);
    fr.read(data.data(), len);
    if(fr.bad())
        return 3;

    if(input.find(".xisf") != std::string::npos)
    {
        if(!loadXISF(data, rawImage))
            return 4;
    }
    else
    {
        if(!loadFITS(data, rawImage))
            return 4;
    }

    if(!rawImage)
        return 5;

    uint32_t thumbSize = 256;

    uint32_t w = rawImage->width();
    uint32_t h = rawImage->height();

    uint32_t cw = thumbSize;
    uint32_t ch = thumbSize;
    if (w > h)
        ch = h * thumbSize / w;
    else
        cw = w * thumbSize / h;

    rawImage->calcStats();
    rawImage->resize(cw, ch);
    if(rawImage->imageStats().m_median[0] < rawImage->norm() * 0.1f)
    {
        MTFParam mtfParams = rawImage->calcMTFParams(true);
        rawImage->applySTF(mtfParams);
    }
    rawImage->convertToType(RawImage::UINT8);

    if(rawImage->channels() == 1)
        stbi_write_png(output.c_str(), cw, ch, 1, rawImage->data(), rawImage->widthBytes());
    else
        stbi_write_png(output.c_str(), cw, ch, 4, rawImage->data(), rawImage->widthBytes());

    return 0;
}
