#include <cstring>
#include <string>
#include <sstream>
#include <cstdlib>
#include <array>
#include "raycaster.hpp"
#include "32blit.hpp"

using namespace blit;

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

uint8_t __m[160 * 120];

float z_buffer[SCREEN_WIDTH];
float lut_camera_displacement[SCREEN_WIDTH];

const int num_sprites = 5000;
std::vector<sprite> map_sprites(num_sprites);

const int num_stars = 100;
std::vector<star> stars(num_stars);

/* create surfaces */
Surface mask((uint8_t *)__m, PixelFormat::M, Size(screen_width, screen_height));


player player1{ Vec2(0,0), Vec2(0,0), Vec2(0,0), 0 };
int bug_spraying = 0;

uint32_t tick_seed = 0;

float tan_half_fov;

bool flip_doom_guy = false;
Point tile_in_view;
float grafitti_alpha = 0;

void blur(uint8_t passes);

Map map(Rect(0, 0, 16, 16));
MapLayer *map_layer_walls;
MapLayer *map_layer_floor;

enum TileFlags { WALL = 1, NO_GRASS = 2 };

enum TileFacing { NONE = 0, NORTH = 1, SOUTH = 2, EAST = 4, WEST = 8 };

bool visibility_map[MAP_WIDTH * MAP_HEIGHT] = { 0 };

std::vector<uint8_t> map_data_walls = {
	0x01, 0x02, 0x03, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
	0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
	0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
	0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
	0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};

std::vector<uint8_t> map_data_floor = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x01, 0x01, 0x05, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
	0x00, 0x05, 0x03, 0x04, 0x05, 0x01, 0x01, 0x05, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x01, 0x00,
	0x00, 0x04, 0x01, 0x05, 0x01, 0x01, 0x05, 0x01, 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
	0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
	0x00, 0x03, 0x01, 0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x05, 0x01, 0x00, 0x01, 0x02, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x05, 0x00, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
	0x00, 0x01, 0x01, 0x00, 0x05, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x04, 0x05, 0x01, 0x00,
	0x00, 0x05, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x00, 0x05, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
	0x00, 0x01, 0x05, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x05, 0x01, 0x00, 0x01, 0x00,
	0x00, 0x01, 0x03, 0x00, 0x03, 0x01, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
	0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
	0x00, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x05, 0x01, 0x01, 0x01, 0x00,
	0x00, 0x01, 0x01, 0x00, 0x05, 0x01, 0x01, 0x01, 0x00, 0x05, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


void get_random_empty_tile_location(Point &pos) {
	while (1) {
		pos.x = blit::random() % MAP_WIDTH;
		pos.y = blit::random() % MAP_HEIGHT;
		if (map.has_flag(pos, TileFlags::NO_GRASS)) continue;
		return;
	}
}

/* setup */
void init() {
	set_screen_mode(ScreenMode::lores);
	//printf("Init: STARTED\n");
	//engine::render = ::render;
	//engine::update = ::update;
	screen.sprites = SpriteSheet::load(packed_data);

	map.add_layer("walls", map_data_walls);
	map_layer_walls = &map.layers["walls"];
	map_layer_walls->add_flags({ 1, 2, 3, 4, 5 }, TileFlags::WALL);
	map_layer_walls->add_flags({ 1, 2, 3, 4, 5 }, TileFlags::NO_GRASS);

	map.add_layer("floor", map_data_floor);
	map_layer_floor = &map.layers["floor"];
	map_layer_floor->add_flags({ 3, 4, 5 }, TileFlags::NO_GRASS);

	//my_sprites.s.load_from_packed(packed_data);

	player1.direction.y = -1;
	player1.position.x = 3.5;
	player1.position.y = 3.5;

	tan_half_fov = tanf(HALF_FOV);

	for (int x = 0; x < SCREEN_WIDTH; x++) {
		lut_camera_displacement[x] = (float)(2 * x) / (float)(SCREEN_WIDTH) - 1.0f;
	}

	srand(0x32bl);
	//stars.resize((const int)num_stars);
	for (int s = 0; s < num_stars; s++) {
		stars[s].position.x = blit::random() % 360;
		stars[s].position.y = blit::random() % (HORIZON / 2);
		stars[s].brightness = 32 + (blit::random() % 128);
	}

	Point tile;
	Vec2 offset;
	//map_sprites.resize((const int)num_sprites);
	for (int s = 0; s < num_sprites; s++) {
		int texture = blit::random() % 100;
		if (texture == 0) {
			map_sprites[s].texture = 0;
		}
		else if (texture == 1) {
			map_sprites[s].texture = 1;
		}
		else if (texture == 2) {
			map_sprites[s].texture = 2;
		}
		else if (texture == 3) {
			map_sprites[s].texture = 3;
		}
		else {
			map_sprites[s].texture = 4 + (texture % 3);
		}
		get_random_empty_tile_location(tile);
		offset.x = (float)blit::random() / 4294967295.0f;
		offset.y = (float)blit::random() / 4294967295.0f;
		map_sprites[s].position.x = tile.x + offset.x;
		map_sprites[s].position.y = tile.y + offset.y;
		map_sprites[s].color = blit::random() % 3;
	}

	//printf("Init: FINISHED\n");
}

// TODO: should be in the vec2 class
Vec2 rotate_point(Vec2 p, Vec2 v) {
	float a = atan2f(v.y, v.x);
	return rotate_vector(p, a);
}

// TODO: should be in the vec2 class
Vec2 rotate_vector(Vec2 v, float a) {
	float c = cosf(a);
	float s = sinf(a);
	float tx = v.x * c - v.y * s;
	float ty = v.x * s + v.y * c;
	return Vec2{ tx, ty };
}

// TODO: should be in the vec2 class
float measure_vector(Vec2 v) {
	return sqrtf((v.x * v.x) + (v.y * v.y));
}

uint32_t elapsed;

void update(uint32_t time) {
	//printf("Update: STARTED\n");
	static uint32_t last_time;
	elapsed = time - last_time;
	last_time = time;
	static Vec2 size(0.2f, 0.2f);
	static Vec2 rmove(0, 0);
	Vec2 move(0, 0);

	int check_tile = 0;

	if (pressed(Button::DPAD_UP)) {
		move.x = 0.02f;
	}
	else if (pressed(Button::DPAD_DOWN)) {
		move.x = -0.02f;
	}
	else if (joystick.y < -0.1f || joystick.y > 0.1f) {
		move.x = -joystick.y * 0.02f;
	}

	/*if (blit::joystick.x != 0) {
		float x = blit::joystick.x / (float)30.0;
		flip_doom_guy = blit::joystick.x > 0;
		player1.direction = rotate_vector(player1.direction, x);
	}

	if (blit::joystick.y != 0) {
		float y = blit::joystick.y / (float)30.0;
		move.x = -y;
	}*/

	rmove.x = move.x * player1.direction.x - move.y * player1.direction.y;
	rmove.y = move.x * player1.direction.y + move.y * player1.direction.x;

	if (rmove.x < 0) {
		int bound = (int)std::floor(player1.position.x + rmove.x - size.x);

		check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y)));
		if (rmove.y > 0) {
			check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y - size.y)));
		}
		else if (rmove.y < 0) {
			check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y + size.y)));
		}
	}
	else if (rmove.x > 0) {
		int bound = (int)std::floor(player1.position.x + rmove.x + size.x);

		check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y)));
		if (rmove.y > 0) {
			check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y - size.y)));
		}
		else if (rmove.y < 0) {
			check_tile = check_tile | map.get_flags(Point(bound, (int32_t)std::floor(player1.position.y + size.y)));
		}
	}

	if ((check_tile & TileFlags::WALL) == 0) {
		player1.position.x += rmove.x;
	}

	check_tile = 0;

	if (rmove.y < 0) {
		int bound = (int)std::floor(player1.position.y + rmove.y - size.y);

		check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x), bound));
		if (rmove.x > 0) {
			check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x - size.x), bound));
		}
		else if (rmove.x < 0) {
			check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x + size.x), bound));
		}
	}
	else if (rmove.y > 0) {
		int bound = (int)std::floor(player1.position.y + rmove.y + size.y);

		check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x), bound));
		if (rmove.x > 0) {
			check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x - size.x), bound));
		}
		else if (rmove.x < 0) {
			check_tile = check_tile | map.get_flags(Point((int32_t)std::floor(player1.position.x + size.x), bound));
		}
	}

	if ((check_tile & TileFlags::WALL) == 0) {
		player1.position.y += rmove.y;
	}

	if (pressed(Button::A)) {
		bug_spraying = 1;
	}
	else
	{
		bug_spraying = 0;
	}

	if (pressed(Button::DPAD_LEFT)) {
		flip_doom_guy = false;
		player1.direction = rotate_vector(player1.direction, -0.02);
	}
	else if (pressed(Button::DPAD_RIGHT)) {
		flip_doom_guy = true;
		player1.direction = rotate_vector(player1.direction, 0.02);
	}
	else if (joystick.x < -0.1f || joystick.x > 0.1f) {
		player1.direction = rotate_vector(player1.direction, joystick.x * 0.02f);
		flip_doom_guy = joystick.x > 0;
	}

	player1.direction.normalize();

	// update the orientation of the player camera plane
	player1.camera = Vec2(-player1.direction.y, player1.direction.x);
	//printf("Update: FINISHED\n");
}

void render(uint32_t time) {
	//printf("Render: STARTED\n");
	uint32_t ms_start = now();

	// clear the mask
	mask.alpha = 255;
	mask.pen = Pen(0);
	mask.clear();

	// clear the canvas
	screen.alpha = 255;
	screen.mask = nullptr;
	screen.pen = Pen(22, 21, 31);
	screen.clear();

	//printf("Render: SKY\n");
	render_sky();

	//printf("Render: STARS\n");
	render_stars();

	// TODO ???		
	//printf("Render: WORLD\n");
	render_world(time);
	/*
	screen.mask = &m;
	blur(5);
	screen.pen = Pen(0, 0, 0, 140);
	screen.clear();

	screen.mask = nullptr;*/

	//edges();

		blur(1);

	screen.pen = Pen(10, 36, 24);
	screen.mask = nullptr;
	for (int y = 0; y < mask.bounds.h; y++) {
		for (int x = 0; x < mask.bounds.w; x++) {
			uint8_t v = *mask.ptr(x, y);
			screen.alpha = v;
			screen.pixel(Point(x, y));
		}
	}
	screen.alpha = 255;

	// TODO ???	


	//printf("Render: SPRITES\n");
	render_sprites(time);

	// draw bug spray    
	//rect ss_spray_rect(40, 160 - 32, 24, 32);
	int offset = int(sinf((player1.position.x + player1.position.y) * 4) * 3); // bob

	screen.sprite(Rect(5, 16, 3, 4), Point(SCREEN_WIDTH - 48, VIEW_HEIGHT - 30 + offset));


	//screen.blit(&ss, ss_spray_rect, point(SCREEN_WIDTH - 48, VIEW_HEIGHT - 30 + offset));

	// draw the HUD
	screen.pen = Pen(37, 36, 46);
	screen.rectangle(Rect(0, 120 - 24, 160, 24));
	//rect ss_hud_rect(0, 160 - 24, 8, 8);
	for (int x = 0; x < 160 / 8; x++) {
		//screen.blit(&ss, ss_hud_rect, point(x * 8, 120 - 24));
		screen.sprite(340, Point(x * 8, 120 - 24));
	}

	//rect ss_heart_filled_rect(8, 128, 8, 8);
	//rect ss_heart_empty_rect(16, 128, 8, 8);
	for (int x = 0; x < 4; x++) {
		//screen.blit(&ss, x > 1 ? ss_heart_empty_rect : ss_heart_filled_rect, point(32 + x * 10, 120 - 16));
		screen.sprite(x > 1 ? 322 : 321, Point(32 + x * 10, 120 - 16));
	}

	// draw DOOM guy (phil)
	Rect ss_guy_rect(160 - 72, 160 - 32, 24, 32);
	//screen.blit(&ss, ss_guy_rect, point(0, 120 - 32), flip_doom_guy);
	screen.sprite(Rect(11, 16, 3, 4), Point(0, 120 - 32), flip_doom_guy ? SpriteTransform::HORIZONTAL : 0);

	//screen.mask = &m;
	//screen.pen = Pen(255, 0, 0, 255);
	//screen.rectangle(rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
	//screen.blit(&m, rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), point(0, 0));

	uint32_t ms_end = now();

	// draw FPS meter
	screen.mask = nullptr;
	screen.pen = Pen(255, 0, 0);
	for (unsigned int i = 0; i < (ms_end - ms_start); i++) {
		screen.pen = Pen(i * 5, 255 - (i * 5), 0);
		screen.rectangle(Rect(i * 3 + 1, 117, 2, 2));
	}
	//printf("Render: FINISHED\n");
}

void render_sky() {
	for (uint16_t column = 0; column < SCREEN_WIDTH; column++) {
		// Moved to a lookup table
		//float camera_displacement = (float)(2 * column) / SCREEN_WIDTH - 1;

		// the current ray direction is the player direction, plus the camera direction multiplied by the displacement
		Vec2 ray(
			player1.direction.x + player1.camera.x * lut_camera_displacement[column],
			player1.direction.y + player1.camera.y * lut_camera_displacement[column]
		);

		ray.normalize();

		// TODO: for the API? 
		// Convert the facing vector to an angle in degrees
		//float r = abs(atan2(ray.x, ray.y) * 180.0 / pi);

		float r = std::atan2(ray.x, ray.y);
		r = (r > 0.0f ? r : (2.0f * pi + r)) * 360.0f / (2.0f * pi);


		Point uv(24 + (int(r * 3.0f) % 16), 160 - 32);

		screen.stretch_blit_vspan(screen.sprites, uv, 32, Point(column, 0), HORIZON); // TODO: blit from spritesheet?

		// Apply radial darkness to simulate directional sunset
		uint8_t fade = std::max(-120, std::min(120, std::abs(int(r) - 120))) + 120;  // calculate a `fog` based on angle
		screen.pen = Pen(12, 33, 52, fade);
		screen.line(Point(column, 0), Point(column, HORIZON));
	}
}

void render_stars() {
	// Get the player's facing angle in degrees from 0 to 359
	float r = std::atan2(player1.direction.x, player1.direction.y);
	r = (r > 0.0f ? r : (2.0f * pi + r)) * 360.0f / (2.0f * pi);

	for (int s = 0; s < num_stars; s++) {
		star *sp = &stars[s];

		// If the stars radial X position is within our field of view
		if ((180 - std::abs(std::abs(r - sp->position.x) - 180)) < 45) {
			// Get the difference between the star and player angle as degrees, signed
			int x = (int)r - sp->position.x + 180;
			x = x - std::floor(float(x) / 360.0f) * 360;
			x -= 180;

			// Convert the degrees to screen columns
			x = 80 + (x / 45.0f) * 80;
			screen.pen = Pen(255, 255, 255, sp->brightness);
			screen.pixel(Point(
				x,
				sp->position.y * 2
			));
		}
	}

	/*std::ostringstream message;
	message << r << ":" << x << "c:" << count;
	screen.pen = Pen(255, 255, 255);
	screen.text(message.str().c_str(), rect(0, HORIZON, 160, 20));*/

}

void render_world(uint32_t time) {
	//TileFacing tfacing = TileFacing::NONE;
	//TileFacing last_tfacing = TileFacing::NONE;
	float perpendicular_wall_distance, wall_x;
	Point map_location_g((int32_t)std::floor(player1.position.x), (int32_t)std::floor(player1.position.y));
	Point map_location;
	Point last_map_location(-1, -1);
		int last_side = -1;

	float last_wall_distance = 0;

	//printf("render_world: populate visibility map\n");
	for (int y = 0; y < MAP_HEIGHT; y++) {
		for (int x = 0; x < MAP_WIDTH; x++) {
			visibility_map[x + y * MAP_WIDTH] = false;
		}
	}
	visibility_map[map_location_g.x + map_location_g.y * MAP_WIDTH] = true;

	//printf("render_world: start column scanning\n");
	for (uint16_t column = 0; column < SCREEN_WIDTH; column++) { // trace SCREEN_WIDTH rays from left to right
		// calculate the amount we need to scale the plane_x/y camera displacement
		// this gives us a step along the camera displacement that corresponds to the current ray
		map_location = map_location_g;

		// Moved to lookup table
		//camera_displacement = (float)(2 * column) / SCREEN_WIDTH - 1;

		// the current ray direction is the player direction, plus the camera direction multiplied by the displacement
		Vec2 ray(
			player1.direction.x + player1.camera.x * lut_camera_displacement[column],
			player1.direction.y + player1.camera.y * lut_camera_displacement[column]
		);

		Vec2 delta_dist(
			std::abs(1.0f / ray.x),
			std::abs(1.0f / ray.y)
		);

		Vec2 side_dist(0, 0);
		int8_t step_x, step_y;

		if (ray.x < 0) {
			step_x = -1;
			side_dist.x = (player1.position.x - map_location.x) * delta_dist.x;
		}
		else
		{
			step_x = 1;
			side_dist.x = (map_location.x + 1.0f - player1.position.x) * delta_dist.x;
		}

		if (ray.y < 0) {
			step_y = -1;
			side_dist.y = (player1.position.y - map_location.y) * delta_dist.y;
		}
		else
		{
			step_y = 1;
			side_dist.y = (map_location.y + 1.0f - player1.position.y) * delta_dist.y;
		}

		bool hit = false;

		//printf("render_world: cast ray for column %d\n", column);
		int side = 0;
		for (int s = 0; s < MAX_RAY_STEPS; s++) {

			if (side_dist.x < side_dist.y) {
				side_dist.x += delta_dist.x;
				map_location.x += step_x;
				side = 0;
			}
			else
			{
				side_dist.y += delta_dist.y;
				map_location.y += step_y;
				side = 1;
			}

			//printf("render_world: update visibility map %d:%d\n", map_location.x, map_location.y);
			if (map_location.x + map_location.y * MAP_WIDTH < MAP_WIDTH * MAP_HEIGHT) {
				visibility_map[map_location.x + map_location.y * MAP_WIDTH] = true;
			}
			//printf("render_world: update visibility map %d:%d: DONE!\n", map_location.x, map_location.y);

				//tile = get_map_tile(map_location);

				//if (column == 80) {
				//	tile_in_view = map_location;
				//}
				/*if (tile & MAP_TILE_SOLID) {
					break;
				}*/
			if (map.has_flag(map_location, TileFlags::WALL)) {
				hit = true;
				break;
			}
		}

		if (hit) {
			//printf("render_world: resolving hit %d:%d\n", map_location.x, map_location.y);
			uint8_t texture_wall = map_layer_walls->tile_at(map_location) - 1;// tile & 0x0f;

			if (side == 0) {
				perpendicular_wall_distance = ((float)map_location.x - player1.position.x + (1 - step_x) / 2.0f) / ray.x;
				wall_x = player1.position.y + perpendicular_wall_distance * ray.y;
				/*if (ray.x > 0) {
					tfacing = TileFacing::WEST;
				}
				else
				{
					tfacing = TileFacing::EAST;
				}*/
			}
			else {
				perpendicular_wall_distance = ((float)map_location.y - player1.position.y + (1 - step_y) / 2.0f) / ray.y;
				wall_x = player1.position.x + perpendicular_wall_distance * ray.x;
				/*if (ray.y > 0) {
					tfacing = TileFacing::NORTH;
				}
				else
				{
					tfacing = TileFacing::SOUTH;
				}*/
			}

			wall_x -= std::floor(wall_x);

			// While the perpendicular wall distance prevents fish-eye effect, generally we want
			// lighting and distance based overlay effects to use the "real" wall distance
			// otherwise the player can see further out of the corner of their eye
			// real_wall_distance = perpendicular_wall_distance / cos(atan2(player1.direction.x, player1.direction.y)) - atan2(ray.x, ray.y);

			int wall_half_height = (int)((float)HORIZON / perpendicular_wall_distance);
			int start_y = HORIZON - wall_half_height;
			int end_y = HORIZON + wall_half_height;

			//printf("render_world: updating z_buffer\n");
			z_buffer[column] = perpendicular_wall_distance;

			//mask.pen = int(alpha);
			mask.pen = 200;

			float line_distance = std::abs(perpendicular_wall_distance - last_wall_distance);

			int width = wall_half_height / 8.0f;

			if (column > 0 && (side != last_side) && line_distance < 0.5f && !(map_location.x == last_map_location.x && map_location.y == last_map_location.y)) {

				for (int c = column - width; c < column + width; c++) {
					int alpha = (std::abs(column - c) * 160) / width;
					mask.pen = 160 - alpha;
					mask.line(Point(c, start_y), Point(c, end_y));
				};
				/*mask.rectangle(rect(
					point(column - width, start_y),
					point(column + width, end_y)
				));*/
				//mask.line(point(column-1, start_y), point(column-1, end_y));
				//mask.line(point(column, start_y), point(column, end_y));
				//mask.line(point(column+1, start_y), point(column+1, end_y));
			}
			else {
				for (int r = end_y - width; r < end_y + width; r++) {
					int alpha = (std::abs(end_y - r) * 160) / width;
					mask.pen = 160 - alpha;
					mask.pixel(Point(column, r));
					/*mask.rectangle(rect(
						point(column, end_y - width - width + 2),
						point(column + 1, end_y + 2)
					));*/
				}
			}

			//last_tfacing = tfacing;
			last_side = side;
			last_wall_distance = perpendicular_wall_distance;
			last_map_location = map_location;

			/* draw the walls */

		//printf("render_world: drawing vertical wall slice\n");
			// TODO: add mipmap support? automatic based on scale?          

			// texture_wall
			//
			//  0 = mossy stone
			//  1 = crumbled brick
			//  2 = good brick
			//  3 = spoopy door
			//  4 = good brick support
			uint16_t texture_offset_x = texture_wall * 32;
			Point uv = Point(uint16_t(wall_x * 32.0f) + texture_offset_x, 0);

			//if ((time >> 2) % 160 == column) {

			screen.stretch_blit_vspan(screen.sprites, uv, 32, Point(column, start_y), end_y - start_y); // TODO Blit from Spritesheet


			//}
			/*int8_t fade = (int)(wall_distance * 255.0f);  // calculate a `fog` based on distance
			if (side == 1) {
				fade *= 0.9f;
			}*/

			/*if (side == 1) {
				alpha *= 0.9f;
			}*/

			//printf("render_world: distance shading\n");
			float wall_distance = perpendicular_wall_distance / MAX_RAY_STEPS;
			float alpha = wall_distance * 255.0f;
			screen.pen = Pen(0, 0, 0, int(alpha));
			screen.line(Point(column, start_y), Point(column, end_y));


			/*mask.pen = Pen(255);
			mask.line(point(column, start_y), point(column, end_y));
			*/





			Vec2 floor_wall(map_location.x, map_location.y);

			if (side == 0 && ray.x > 0) {
				floor_wall.y += wall_x;
			}
			else if (side == 0 && ray.x < 0) {
				floor_wall.x += 1.0f;
				floor_wall.y += wall_x;
			}
			else if (side == 1 && ray.y > 0) {
				floor_wall.x += wall_x;
			}
			else {
				floor_wall.x += wall_x;
				floor_wall.y += 1.0f;
			}

			//printf("render_world: drawing floor\n");
				// Draw the floor
			for (int y = end_y + 1; y < VIEW_HEIGHT + 1; y++) {
				float distance = (float)VIEW_HEIGHT / (2.0f * y - VIEW_HEIGHT);
				float weight = distance / perpendicular_wall_distance;

				Vec2 current_floor(
					weight * floor_wall.x + (1.0f - weight) * player1.position.x,
					weight * floor_wall.y + (1.0f - weight) * player1.position.y
				);

				// Get the tile-relative x/y texture coordinates
				Point tile_uv(
					(current_floor.x - std::floor(current_floor.x)) * 32,
					(current_floor.y - std::floor(current_floor.y)) * 32
				);

				uint8_t floor_texture = map_layer_floor->tile_at(Point(int(current_floor.x), int(current_floor.y))) - 1;
				//uint8_t floor_texture = get_map_tile(point(int(current_floor.x), int(current_floor.y))) & 0x0f;

				Point floor_texture_sprite(
					32 * floor_texture,
					32
				);
				// Get the distance from the player to the point on the floor
				// and use this to create a distance shadowing effect
				// dist = current_floor - player1.position;
				// p_distance = dist.length();

				int fragment_x = floor_texture_sprite.x + tile_uv.x;
				int fragment_y = floor_texture_sprite.y + tile_uv.y;


				uint8_t fragment_c_idx = *screen.sprites->ptr(fragment_x, fragment_y);
				//if (time >> 2 % 360 == column) {
				screen.pen = screen.sprites->palette[fragment_c_idx];
				screen.pixel(Point(column, y - 1));
				//}

				float floor_distance = distance / MAX_RAY_STEPS;

				screen.pen = Pen(0, 0, 0, int(floor_distance * 255.0f));
				screen.pixel(Point(column, y - 1));
			}
		}
	}
}

void render_sprites(uint32_t time) {

	float inverse_det = 1.0f / (player1.camera.x * player1.direction.y - player1.direction.x * player1.camera.y);

	// Calculate distance from player to each sprite
	for (int i = 0; i < num_sprites; i++) {
		Vec2 sprite_distance(
			map_sprites[i].position.x - player1.position.x,
			map_sprites[i].position.y - player1.position.y
		);
		map_sprites[i].distance = (sprite_distance.x * sprite_distance.x) + (sprite_distance.y * sprite_distance.y);
	}

	// sort the sprites by distance
	std::sort(map_sprites.begin(), map_sprites.end());

	for (int i = 0; i < num_sprites; i++) {
		sprite *psprite = &map_sprites[i];

		Pen cols_a[]{
			Pen(0x15, 0x98, 0x5d, 200),
			Pen(0x35, 0xA8, 0x3d, 200),
			Pen(0x45, 0x88, 0x2d, 200)
		};

		Pen cols_b[]{
			Pen(0x00, 0x7f, 0x43, 200),
			Pen(0x20, 0x6f, 0x33, 200),
			Pen(0x30, 0x8f, 0x23, 200)
		};

		screen.sprites->palette[11] = cols_a[psprite->color];
		screen.sprites->palette[12] = cols_b[psprite->color];


		if (visibility_map[int(psprite->position.x) + int(psprite->position.y) * MAP_WIDTH] == 0) {
			continue;
		}

		// Give the larger sprites a better view distance
		float max_distance = (psprite->texture == 0 || psprite->texture == 1) ? 64.0 : 16.0;

		float distance = std::min(max_distance, psprite->distance) / max_distance;
		if (distance == 1.0f) {
			continue;
		}

		// Get the player-relative position of the sprite
		Vec2 relative_position = psprite->position - player1.position;

		Vec2 screen_transform(
			inverse_det * (player1.direction.y * relative_position.x - player1.direction.x * relative_position.y),
			inverse_det * (-player1.camera.y * relative_position.x + player1.camera.x * relative_position.y)
		);

		if (screen_transform.y < 0) {
			continue;
		}


		// TODO:: palette change
		//int color_offset = spr.color * 4;

		Rect sprite_bounds[7] = {
			Rect(0, 64, 28, 64),   // Full-grown tree
			Rect(28, 74, 28, 54),  // Mature tree
			Rect(56, 94, 28, 34),  // Tall shrub
			Rect(56, 70, 28, 24),  // Short shrub
			Rect(48, 65, 8, 8),    // Tall grass
			Rect(38, 66, 9, 7),    // Mid grass
			Rect(30, 68, 7, 5)     // Smol grass
		};

		Rect bounds = sprite_bounds[psprite->texture];

		int sprite_height = std::abs(int(bounds.h * SPRITE_SCALE / screen_transform.y));
		int sprite_width = ((float)bounds.w / (float)bounds.h) * sprite_height;

		int sprite_top_y = ((VIEW_HEIGHT - bounds.h) * SPRITE_SCALE) / screen_transform.y;

		// Get the screen-space position of the sprites base on the floor
		Vec2 screen_pos(
			int((SCREEN_WIDTH / 2) * (1 + screen_transform.x / screen_transform.y)),
			HORIZON + (HORIZON / screen_transform.y)
		);

		/* DEBUG: Plot the sprite's base with a red dot
		screen.alpha = 255 - int(255 * distance);
		screen.pen = Pen(255, 0, 0);
		screen.pixel(point(screen_pos.x, screen_pos.y));
		*/

		// offset screen coordinate with sprite bounds
		screen_pos -= Vec2(sprite_width / 2, sprite_height);

		//screen.stretch_blit(&my_sprites, bounds, rect(screen_pos.x, screen_pos.y, sprite_width, sprite_height));

		for (int x = std::max((uint16_t)0, uint16_t(screen_pos.x)); x < std::min(SCREEN_WIDTH, uint16_t(screen_pos.x + sprite_width)); x++) {
			if (screen_transform.y > z_buffer[x]) continue;

			//if ((time >> 2) % 160 != x) { continue; }

			Vec2 uv(
				bounds.x + ((float(x - screen_pos.x) / float(sprite_width)) * bounds.w),
				bounds.y
			);

			screen.stretch_blit_vspan(screen.sprites, uv, bounds.h, Point(x, screen_pos.y), sprite_height); // TODO: blit from spritesheet?
		}
		screen.sprites->palette[11] = Pen(0x15, 0x98, 0x5d, 200);
		screen.sprites->palette[12] = Pen(0x00, 0x7f, 0x43, 200);
	}
}

void update_player_camera_plane() {
	//vec2 plane(-player1.direction.y, player1.direction.x);

	//plane = rotate_vector(plane, M_PI_H);
	//float magnitude = plane.length() / tan_half_fov;
	//player1.camera.x = plane.x / magnitude;
	//player1.camera.y = plane.y / magnitude;

	//plane.rotate(float(M_PI_H));
	//plane.rotate90cw();
	//plane.normalize();

	// If the player's camera plane is 90 degrees to their facing direction,
	// then since math.cos(PI / 2) =~ 0 and math.sin(PI / 2) =~ 1.0
	// a 90 degree rotation is just (-y, x)
}

void edges() {
	uint8_t *p = (uint8_t *)mask.data + 160;
	for (uint16_t y = 1; y < 119; y++) {
		p++;

		for (uint16_t x = 1; x < 159; x++) {
			uint8_t v1 = std::abs(*(p + 1) - *p);
			uint8_t v2 = std::abs(*(p + 160) - *p);
			uint8_t d = v1 > v2 ? v1 : v2;
			*p++ = d < 3 ? 0 : 255;
		}

		p++;
	}

	p = (uint8_t *)mask.data + (120 * 160) - 1 - 160;
	for (uint16_t y = 1; y < 119; y++) {
		p--;

		for (uint16_t x = 1; x < 159; x++) {
			uint8_t v1 = std::abs(*(p - 1) - *p);
			uint8_t v2 = std::abs(*(p - 160) - *p);
			uint8_t d = v1 > v2 ? v1 : v2;
			*p-- = d < 3 ? 0 : 255;
		}

		p--;
	}
}

void blur(uint8_t passes) {
	uint8_t last;

	for (uint8_t pass = 0; pass < passes; pass++) {
		uint8_t *p = (uint8_t *)mask.data;
		for (uint16_t y = 0; y < 120; y++) {
			last = *p;
			p++;

			for (uint16_t x = 1; x < 159; x++) {
				*p = (*(p + 1) + last + *p + *p) >> 2;
				last = *p;
				p++;
			}

			p++;
		}
	}

	// vertical      
	for (uint8_t pass = 0; pass < passes; pass++) {
		for (uint16_t x = 0; x < 160; x++) {
			uint8_t *p = (uint8_t *)mask.data + x;

			last = *p;
			p += 160;

			for (uint16_t y = 1; y < 119; y++) {
				*p = (*(p + 160) + last + *p + *p) >> 2;
				last = *p;
				p += 160;
			}
		}
	}
}
