#include "pw/core/image.hpp"

#include <limits>

namespace pw {

image::image(const sizei &s, image::pixel_layout t, void *ptr)
{
    this->create(s,t,ptr);
}

bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
{
	size_t n = bytes_per_pixel(t) * s.area();

    if (ptr != nullptr) {

		auto a = reinterpret_cast<image::data_t*>(ptr);

        _data.assign(a,a + n);
		_size = s;
		_layout = t;

    } else {

		_data.resize(n);
		_size = sizei(0,0);
    }

    return !_data.empty();
}

void image::release(bool release_memory)
{
    _data.clear();

    if (release_memory) _data.shrink_to_fit();
}

uint32_t image::bytes_per_pixel(image::pixel_layout t)
{
    switch (t) {
    case pw::image::RGB8:
		return 3 * sizeof(data_t);
    case pw::image::RGBA8:
		return 4 * sizeof(data_t);
    case pw::image::LUM:
		return 1 * sizeof(data_t);
	case pw::image::DEPTH:
		return 1 * sizeof(float);
    }

    return std::numeric_limits<uint32_t>::max();
}

sizei image::size() const
{
    return _size;
}

image::pixel_layout image::layout() const
{
    return _layout;
}

void image::set_layout(const pixel_layout &layout)
{
    _layout = layout;
}

uint64_t image::change_count() const
{
    return _change_count;
}

void image::set_change_count(const uint64_t &change_count)
{
    _change_count = change_count;
}

}
