#include "PixelBuffer.hpp"

// PixelBuffer
// -----------

Color PixelBuffer::trap = _t;

Color PixelBuffer::peek(PixelPoint const& pos) const
{
	if(pos.x < 0 || pos.x >= w() || pos.y < 0 || pos.y >= h()) {
		return _t;
	}
	return peekUnchecked(pos);
}

PixelIterator PixelBuffer::begin() const
{
	return { *this, { 0, 0 } };
}

PixelIterator PixelBuffer::end() const
{
	return { *this, { 0, height } };
}
// -----------

// DynamicPixelBuffer
// ------------------

DynamicPixelBuffer::DynamicPixelBuffer(int w, int h)
	: PixelBuffer(w, h), buffer(w * h, _t)
{
}

Color DynamicPixelBuffer::peekUnchecked(PixelPoint const &pos) const
{
	return buffer[(pos.y * w()) + pos.x];
};

Color& DynamicPixelBuffer::at(PixelPoint const& pos)
{
	if(pos.x < 0 || pos.x >= w() || pos.y < 0 || pos.y >= h()) {
		trap = _t;
		return trap;
	}
	return buffer[(pos.y * w()) + pos.x];
}

void DynamicPixelBuffer::clear(Color ch)
{
	std::fill(buffer.begin(), buffer.end(), ch);
}

void DynamicPixelBuffer::blit_topleft(
	PixelPoint const &topleft, PixelBuffer const &other
)
{
	for(auto const &it : other) {
		if(it.peek() != _t) {
			at(topleft + it.pos()) = it.peek();
		}
	}
}

void DynamicPixelBuffer::blit_centered(
	PixelPoint const &center, PixelBuffer const &other
)
{
	blit_topleft(
		{ (center.x - (other.w() / 2)), (center.y - (other.h() / 2)) }, other
	);
}
// ------------------