#include "image.h"

void image::draw(image const& image, vec2i pos) {
	draw(image, pos, image.bounds());
}

void image::draw(image const& image, vec2i pos, recti src_rect) {
	src_rect = recti::intersection(src_rect, image.bounds());
	auto crop = recti::intersection(bounds(), recti(pos, image.bounds().size));
	crop = recti::intersection(crop, recti(crop.pos, src_rect.size));
	auto src_off = crop.pos - pos + src_rect.pos;
	auto start = crop.pos;
	auto end = crop.pos2();
	for(int y = start.y; y <= end.y; ++y) {
		for(int x = start.x; x <= end.x; ++x) {
			auto color = image._data[
				x - start.x + src_off.x + (y - start.y + src_off.y) * image._bounds.size.x
			];
			if(color & 0xff000000)
				_data[x + y * _bounds.size.x] = color;
		}
	}
}

void image::draw(image const& image, vec2i pos, color color) {
	draw(image, pos, color, image.bounds());
}

void image::draw(image const& image, vec2i pos, color color, recti src_rect) {
	color |= 0xff000000;
	src_rect = recti::intersection(src_rect, image.bounds());
	auto crop = recti::intersection(bounds(), recti(pos, image.bounds().size));
	crop = recti::intersection(crop, recti(crop.pos, src_rect.size));
	auto src_off = crop.pos - pos + src_rect.pos;
	auto start = crop.pos;
	auto end = crop.pos2();
	for(int y = start.y; y <= end.y; ++y) {
		for(int x = start.x; x <= end.x; ++x) {
			auto color_src = image._data[
				x - start.x + src_off.x + (y - start.y + src_off.y) * image._bounds.size.x
			];
			if(color_src & 0xff000000)
				_data[x + y * _bounds.size.x] = color;
		}
	}
}


void image::draw_upscaled(image const& image) {
	auto ratio = _bounds.size / image._bounds.size;
	auto scale = std::min(ratio.x, ratio.y);
	switch(scale) {
	case 3:
#pragma omp parallel for
		for(int y = 0; y < image._bounds.size.y; ++y) {
			for(int x = 0; x < image._bounds.size.x; ++x) {
				auto color = image._data[x + y * image._bounds.size.x];
				auto color2 = (color & 0xfefefe) >> 1;
				_data[x * 3 + 0 + (y * 3 + 0) * _bounds.size.x] = color;
				_data[x * 3 + 1 + (y * 3 + 0) * _bounds.size.x] = color;
				_data[x * 3 + 2 + (y * 3 + 0) * _bounds.size.x] = color2;
				_data[x * 3 + 0 + (y * 3 + 1) * _bounds.size.x] = color;
				_data[x * 3 + 1 + (y * 3 + 1) * _bounds.size.x] = color;
				_data[x * 3 + 2 + (y * 3 + 1) * _bounds.size.x] = color2;
				_data[x * 3 + 0 + (y * 3 + 2) * _bounds.size.x] = color2;
				_data[x * 3 + 1 + (y * 3 + 2) * _bounds.size.x] = color2;
				_data[x * 3 + 2 + (y * 3 + 2) * _bounds.size.x] = color2;
			}
		}
		break;
	default:
#pragma omp parallel for
		for(int y = 0; y < image._bounds.size.y; ++y) {
			for(int x = 0; x < image._bounds.size.x; ++x) {
				auto color = image._data[x + y * image._bounds.size.x];
				for(int sy = 0; sy < scale; ++sy) {
					for(int sx = 0; sx < scale; ++sx) {
						_data[(x * scale + sx) + (y * scale + sy) * _bounds.size.x] = color;
					}
				}
			}
		}
	}
}
