#include <raylib.h>
#include <raymath.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "faces.h"
#include "chunk.h"
#include "vector.h" 
#include "stb_perlin.h"

Mesh gen_mesh(int* chunk) {
	Mesh mesh = { 0 };
	mesh.vertices = malloc(0);
	mesh.vertexCount = 0;
        mesh.texcoords = malloc(0);

	for (int i = 0; i < WIDTH * WIDTH * HEIGHT; i++) {
                int block_id = chunk[i];
		if(block_id == 0) continue;
		vector3 pos = index_to_coord(i);

		if(get_block_at(chunk, (vector3){ pos.x, pos.y - 1, pos.z }) == 0)
			add_face(&mesh, bottom, bottom_tex,     block_id, pos);

		if(get_block_at(chunk, (vector3){ pos.x, pos.y + 1, pos.z }) == 0)
			add_face(&mesh, top,    top_tex,        block_id, pos);

		if(get_block_at(chunk, (vector3){ pos.x - 1, pos.y, pos.z }) == 0)
			add_face(&mesh, left,   left_tex,       block_id, pos);

		if(get_block_at(chunk, (vector3){ pos.x + 1, pos.y, pos.z }) == 0)
			add_face(&mesh, right,  right_tex,      block_id, pos);

		if(get_block_at(chunk, (vector3){ pos.x, pos.y, pos.z - 1 }) == 0)
			add_face(&mesh, back,   back_tex,       block_id, pos);

		if(get_block_at(chunk, (vector3){ pos.x, pos.y, pos.z + 1 }) == 0)
			add_face(&mesh, front,  front_tex,      block_id, pos);
	}

	UploadMesh(&mesh, false);

	printf("mesh generated, %d verts, %d tris\n", mesh.vertexCount, mesh.triangleCount);

	return mesh;
}

int main() {
        for(float x = 0.0f; x < WIDTH; x++) {
                for(float z = 0.0f; z < WIDTH; z++) {
                        printf("%f, %f: %f\n", x, z, stb_perlin_noise3(x, z, z, 0, 0, 0));
                }
        }

	InitWindow(800, 600, "samcraft");

	//SetTargetFPS(60);

	int* chunk = malloc(WIDTH * WIDTH * HEIGHT * sizeof(int));
	for(int i = 0; i < WIDTH * WIDTH * HEIGHT; i++) {
		chunk[i] = 0;
	}
        for(int x = 0; x < WIDTH; x++) {
                for(int z = 0; z < WIDTH; z++) {
                        for(int y = 0; y < (10 + stb_perlin_fbm_noise3(x / 40.0f, x / 40.0f, z / 40.0f, 2.0f, 0.5f, 6) * 10.0f); y++) {
                                chunk[coord_to_index((vector3){ x, y, z })] = GetRandomValue(1, 2);
                        }
                }
        }

	Mesh chunk_mesh = gen_mesh(chunk);
	Material mat = LoadMaterialDefault();
	Matrix matrix = MatrixIdentity();

        Texture atlas = LoadTexture("atlas.png");
        mat.maps[MATERIAL_MAP_DIFFUSE].texture = atlas;

	Camera camera = { 0 };
	camera.position = (Vector3){ 10.0f, 10.0f, 10.0f };
	camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
	camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
	camera.projection = CAMERA_PERSPECTIVE;
	camera.fovy = 70.0f;

	while (!WindowShouldClose()) {
		UpdateCamera(&camera, CAMERA_FREE);

		DisableCursor();

		BeginDrawing();
		{
			ClearBackground(BLACK);

			BeginMode3D(camera);
			{
				DrawMesh(chunk_mesh, mat, matrix);
				DrawGrid(10, 10);
			}
			EndMode3D();

                        DrawFPS(10, 10);
		}
		EndDrawing();
	}

	CloseWindow();

	return 0;
}
