#include "pw/io/image_io.hpp"

#include <pw/core/debug.hpp>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION
 #include "stb_image_write.h"

#include <future>

namespace pw {

struct image_io::impl
{

    image read_impl(const std::string& uri,uint32_t flags)
    {
        int x{ 0 }, y{ 0 }, n{ 0 };
        const auto data = stbi_load(uri.c_str(), &x, &y, &n, 4);

        if (data) {

			image r;

            r.create(size(x,y),image::pixel_layout::RGBA8,reinterpret_cast<image::data_t*>(data));

			stbi_image_free(data);

            return r;
		} else {

			debug::e() << stbi_failure_reason();
		}

        return image();
    }

    bool write(const std::string& uri, const image& img, uint32_t flags)
    {
        auto res = stbi_write_png(uri.c_str(),img.size().width,img.size().height,
                       image::components(img.layout()),
                       img.data(),
                       img.size().width * image::components(img.layout()));

        return 0 == res;
    }

};


image_io &image_io::get()
{
    static image_io instance;
    return instance;
}

image image_io::read(const std::string &uri, uint32_t flags)
{
    return _impl->read_impl(uri,flags);
}

bool image_io::write(const std::string &uri, const image& img, uint32_t flags)
{
    return _impl->write(uri,img,flags);
}

//
//
//

image_io::image_io()
{
    _impl = make_unique<impl>();
}

image_io::~image_io()
{
}

}
