
#include <string>
#include <memory>
#include <cstdlib>
#include <array>

#include "tunnel.hpp"
#include "assets.hpp"

using namespace blit;

const uint16_t screen_width = 160;
const uint16_t screen_height = 120;

Surface *ss_ship = Surface::load(packed_data_ship);

/* setup */
void init() {
	screen.alpha = 255;
	screen.mask = nullptr;
	screen.pen = Pen(0, 0, 0, 0);
	screen.clear();

	screen.sprites = Surface::load(packed_data);
}

void tunnel_test(uint32_t time_ms) {
	Point mipmap_offset[5] = {
		Point(0, 0),
		Point(128, 0),
		Point(128, 64),
		Point(128, 96),
		Point(128, 112)
	};
	uint8_t mipmap_size[5] = {
		128,
		64,
		32,
		16,
		8
	};

	float x = time_ms / 1000.0;
	
	float y = 1.0;

	for (int scanline = 0; scanline < screen.bounds.w; scanline++) {

		float z = 3.0; // Distance from our imaginary wall plane
		z += sinf((time_ms + scanline) / 1000.0f);
		y = sinf((time_ms + scanline) / 200.0f);

		int offset = scanline;

		int wall_height = screen.bounds.h / z;
		int wall_offset_top = (screen.bounds.h - wall_height) / 2;
		float wall_offset = y * (wall_height / 4.0f);

		wall_offset_top -= wall_offset;

		int mipmap_index = 0;
		if (wall_height <= 8) {
			mipmap_index = 4;
		}
		if (wall_height <= 16) {
			mipmap_index = 3;
		}
		if (wall_height <= 32) {
			mipmap_index = 2;
		}
		if (wall_height <= 64) {
			mipmap_index = 1;
		}
			
		Point texture_origin = mipmap_offset[mipmap_index];
		uint8_t texture_size = mipmap_size[mipmap_index];

		for (int wall_y = 0; wall_y < wall_height; wall_y++) {
			Vec2 uv(
				(float(scanline) / wall_height) + x,
				(float(wall_y) / wall_height)
			);

			uv.x -= floorf(uv.x);
			uv.y -= floorf(uv.y);


			uint8_t *fragment_c = screen.sprites->ptr(Point(
				texture_origin.x + (uv.x * texture_size),
				texture_origin.y + (uv.y * texture_size)
			));

			screen.pen = screen.sprites->palette[*fragment_c];
			screen.alpha = 255;
			screen.pixel(Point(
				scanline,
				wall_offset_top + wall_y
			));
		}

		for (int ceil_y = 0; ceil_y < wall_offset_top; ceil_y++) {

			float distance = (float)screen.bounds.h / (2.0f * (screen.bounds.h - ceil_y - wall_offset) - screen.bounds.h);
			float weight = distance / z;

			float t_size = float(screen.bounds.h) / distance;

			int mipmap_index = 0;
			if (t_size <= 8) {
				mipmap_index = 4;
			}
			if (t_size <= 16) {
				mipmap_index = 3;
			}
			if (t_size <= 32) {
				mipmap_index = 2;
			}
			if (t_size <= 64) {
				mipmap_index = 1;
			}

			Point texture_origin = mipmap_offset[mipmap_index];
			uint8_t texture_size = mipmap_size[mipmap_index];


			Vec2 uv(
				(float(scanline) / wall_height) + x,
				0.5
			);

			uv.x = uv.x * weight;
			uv.x += x * (1.0f - weight);

			uv.y = uv.y * weight;
			uv.y += z * (1.0f - weight);

			uv.x -= floorf(uv.x);
			uv.y -= floorf(uv.y);

			uint8_t *fragment_c = screen.sprites->ptr(Point(
				texture_origin.x + (uv.x * texture_size),
				texture_origin.y + (uv.y * texture_size)
			));

			screen.pen = screen.sprites->palette[*fragment_c];
			screen.alpha = 200;
			screen.pixel(Point(scanline, ceil_y));
		}

		for (int floor_y = wall_offset_top + wall_height; floor_y < screen.bounds.h; floor_y++) {

			float distance = (float)screen.bounds.h / (2.0f * (floor_y + wall_offset) - screen.bounds.h);
			float weight = distance / z;

			float t_size = float(screen.bounds.h) / distance;

			int mipmap_index = 0;
			if (t_size <= 8) {
				mipmap_index = 4;
			}
			if (t_size <= 16) {
				mipmap_index = 3;
			}
			if (t_size <= 32) {
				mipmap_index = 2;
			}
			if (t_size <= 64) {
				mipmap_index = 1;
			}

			Point texture_origin = mipmap_offset[mipmap_index];
			uint8_t texture_size = mipmap_size[mipmap_index];


			Vec2 uv(
				(float(scanline) / wall_height) + x,
				0.1f
			);

			uv.x = uv.x * weight;
			uv.x += x * (1.0f - weight);

			uv.y = uv.y * weight;
			uv.y += z * (1.0f - weight);

			uv.x -= floorf(uv.x);
			uv.y -= floorf(uv.y);

			uint8_t *fragment_c = screen.sprites->ptr(Point(
				texture_origin.x + (uv.x * texture_size),
				texture_origin.y + (uv.y * texture_size)
			));

			screen.pen = screen.sprites->palette[*fragment_c];
			screen.alpha = 200;
			screen.pixel(Point(scanline, floor_y));

		}
	}

}

void tunnel_test1(uint8_t time_ms) {

	int max_stripe_height = (screen.bounds.h / 3);
	int min_stripe_height = 40;

	for (int scanline = 0; scanline < screen.bounds.w; scanline++) {
		screen.alpha = 255;
		int offset = scanline * 2;
		//float time_offset = (time_ms + offset) / 100.0f;
		float x = (sinf(float(time_ms + offset) / 1000.0f) + 1.0f) / 2.0f;
		float y = (sinf(float(time_ms + offset + 1000) / 2000.0f) + 1.0f) / 2.0f;

		float stripe_height = min_stripe_height + max_stripe_height * y;
		float stripe_offset_top = (screen.bounds.h / 4) * x;

		float t_scale = float(min_stripe_height + max_stripe_height) / stripe_height;

		/*screen.pen = rgba(255, 200, 200);
		screen.line(
			point(scanline, stripe_offset_top),
			point(scanline, stripe_offset_top + stripe_height)
		);*/

		Vec2 c(((scanline * t_scale) + (time_ms / 5.0f)), 0);

		screen.stretch_blit_vspan(screen.sprites, Point(int(c.x) % 128, int(c.y) % 128), 128, Point(scanline, stripe_offset_top), stripe_height);


		for (int f = 0; f < screen.bounds.h - stripe_height - stripe_offset_top - 1; f++) {
			float distance = (float)(screen.bounds.h - stripe_height - stripe_offset_top - 1) / f;

			c.y = distance * stripe_height;
			/*while (c.y < 0) {
				c.y = 127 - c.y;
			}
			while (c.y > 127) {
				c.y -= 127;
			}*/

			c.x -= (scanline - (screen.bounds.w / 2)) / 200.0f;
			/*while (c.x < 0) {
				c.x = 127 - c.x;
			}
			while (c.x > 127) {
				c.x -= 127;
			}*/


			uint8_t *fragment_c = screen.sprites->ptr(int(c.x) % 128, int(c.y) % 128);

			screen.pen = screen.sprites->palette[*fragment_c];
			screen.alpha = 200;
			screen.pixel(Point(scanline, (stripe_offset_top + stripe_height) + f - 1));
		}
	}

}

void render(uint32_t time_ms) {
	uint32_t ms_start = now();

	screen.pen = Pen(0, 0, 0, 255);
	screen.clear();

	tunnel_test(time_ms);

	screen.alpha = 255;

	int x = 20 + (sinf(time_ms / 1000.0f) * 10.0f);
	int y = 40 + (sinf(time_ms / 1500.0f) * 30.0f);

	screen.blit(ss_ship, Rect(0, 0, 64, 32), Point(x, y));

	uint32_t ms_end = now();
	screen.mask = nullptr;
	screen.pen = Pen(255, 0, 0);
	for (uint32_t i = 0; i < (ms_end - ms_start); i++) {
		screen.pen = Pen(i * 5, 255 - (i * 5), 0);
		screen.rectangle(Rect(i * 3 + 1, screen.bounds.h - 3, 2, 2));
	}
}

void update(uint32_t time) {

}
