#include <glerminal.h>

#include <cmath>

namespace
{
	enum : unsigned char
	{
		empty,
		player,
		floor,
		wall
	};

	constexpr unsigned int WALL_LAYERS = LAYER_COUNT - 1;

	void init()
	{
		glerminal_load_sprites_file("resources/rogue.png");

		for (int i = 0; i < GRID_WIDTH + 2; i++)
		{
			for (int j = 0; j < GRID_HEIGHT + 2; j++)
			{
				for (int k = 0; k < WALL_LAYERS; k++)
				{
					const unsigned char v = (k + 1) * (256 / WALL_LAYERS) - 1;
					const unsigned int c = (0xFF << 24) | (v << 16) | (v << 8) | v;

					if (i == 1 || j == 1 || i == GRID_WIDTH || j == GRID_HEIGHT)
					{
						glerminal_set(i, j, k, floor);
					}
					else
					{
						glerminal_set(i, j, k, wall);
					}

					glerminal_color(i, j, k, c);
					glerminal_scale(i, j, k, (k / static_cast<float>(WALL_LAYERS)) + 1);
				}
			}
		}
	}

	void mainloop(double dt)
	{
		static double time = 0;
		time += dt;

		const float cx = GRID_WIDTH / 2.0f * cosf(time / 2) + GRID_WIDTH / 2.0f + 0.5f;
		const float cy = GRID_HEIGHT / 2.0f * sinf(time / 2) + GRID_HEIGHT / 2.0f + 0.5f;

		for (int i = 0; i < GRID_WIDTH + 2; i++)
		{
			for (int j = 0; j < GRID_HEIGHT + 2; j++)
			{
				for (int k = 0; k < WALL_LAYERS; k++)
				{
					const float dx = (i - cx);
					const float dy = (j - cy);
					const float dist = sqrtf(dx * dx + dy * dy);
					const float angle = atan2f(dy, dx);

					const float ox = dist * k / WALL_LAYERS * cosf(angle);
					const float oy = dist * k / WALL_LAYERS * sinf(angle);

					glerminal_offset(i, j, k, ox * 2, oy * 2);
				}

				glerminal_set(i, j, WALL_LAYERS, empty);
			}
		}

		glerminal_set(cx, cy, WALL_LAYERS, player);

		glerminal_flush();
	}
}

int main(int argc, char** argv)
{
	glerminal_run({init, mainloop});
}