#include <string.h>
#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(screen_mode::hires);
	//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 = tan(HALF_FOV);

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

	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 = atan2(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 = cos(a);
	float s = sin(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 sqrt((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 = floor(player1.position.x + rmove.x - size.x);

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

		check_tile = check_tile | map.get_flags(Point(bound, floor(player1.position.y)));
		if (rmove.y > 0) {
			check_tile = check_tile | map.get_flags(Point(bound, floor(player1.position.y - size.y)));
		}
		else if (rmove.y < 0) {
			check_tile = check_tile | map.get_flags(Point(bound, 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 = floor(player1.position.y + rmove.y - size.y);

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

		check_tile = check_tile | map.get_flags(Point(floor(player1.position.x), bound));
		if (rmove.x > 0) {
			check_tile = check_tile | map.get_flags(Point(floor(player1.position.x - size.x), bound));
		}
		else if (rmove.x < 0) {
			check_tile = check_tile | map.get_flags(Point(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(RGBA(0));
	mask.clear();

	// clear the canvas
	screen.alpha = 255;
	screen.mask = nullptr;
	screen.pen(RGBA(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(rgba(0, 0, 0, 140));
	screen.clear();

	screen.mask = nullptr;*/

	//edges();

		blur(1);

	screen.pen(RGBA(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(sin((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(RGBA(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(rgba(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(RGBA(255, 0, 0));
	for (unsigned int i = 0; i < (ms_end - ms_start); i++) {
		screen.pen(RGBA(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 / M_PI);

		float r = atan2f(ray.x, ray.y);
		r = (r > 0.0f ? r : (2.0f * float(M_PI) + r)) * 360.0f / (2.0f * float(M_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, abs(int(r) - 120))) + 120;  // calculate a `fog` based on angle
		screen.pen(RGBA(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 = atan2f(player1.direction.x, player1.direction.y);
	r = (r > 0.0f ? r : (2.0f * float(M_PI) + r)) * 360.0f / (2.0f * float(M_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 - abs(abs(r - sp->position.x) - 180)) < 45) {
			// Get the difference between the star and player angle as degrees, signed
			int x = r - sp->position.x + 180;
			x = x - floor(float(x) / 360.0f) * 360;
			x -= 180;

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

	/*std::ostringstream message;
	message << r << ":" << x << "c:" << count;
	screen.pen(rgba(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)floor(player1.position.x), (int32_t)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(
			(float)abs(1.0f / ray.x),
			(float)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 -= 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 = 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 = (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 = (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(uint8_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(RGBA(0, 0, 0, int(alpha)));
			screen.line(Point(column, start_y), Point(column, end_y));


			/*mask.pen(rgba(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 - floor(current_floor.x)) * 32,
					(current_floor.y - 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);

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

				float floor_distance = distance / MAX_RAY_STEPS;

				screen.pen(RGBA(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];

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

		RGBA cols_b[]{
			RGBA(0x00, 0x7f, 0x43, 200),
			RGBA(0x20, 0x6f, 0x33, 200),
			RGBA(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 = 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(rgba(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(0, int(screen_pos.x)); x < std::min(SCREEN_WIDTH, int(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] = RGBA(0x15, 0x98, 0x5d, 200);
		screen.sprites->palette[12] = RGBA(0x00, 0x7f, 0x43, 200);
	}
}

void update_player_camera_plane(void) {
	//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 = abs(*(p + 1) - *p);
			uint8_t v2 = 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 = abs(*(p - 1) - *p);
			uint8_t v2 = 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;
			}
		}
	}
}
