#pragma once

#include <vector>
#include <sstream>
#include <random>

#include <glm/glm.hpp>

#include "MeshRenderer.h"

struct Wall
{
	glm::vec2 a, b;
	int portal;
};

struct Sector
{
	unsigned int index;
	unsigned int number_of_walls;

	float floor_height;
	float ceiling_height;

	bool outward_facing;

	glm::vec3 color;

	std::vector<Wall> walls;
};

class LevelMap
{
public:
	LevelMap();
	~LevelMap();

	void Compile(std::string level_map_code);

	void RenderSetup
	(
		Shader *wall_shader, 
		Shader *floor_shader, 
		Shader *ceiling_shader
	);

	void Update
	(
		glm::mat4 projection, 
		glm::mat4 view, 
		glm::vec3 light_position, 
		glm::vec3 light_color, 
		glm::vec3 view_position
	);

	std::vector<MeshRenderer*> GetMeshes();
private:
	std::vector<Sector> sectors;

	std::vector<float> wall_vertices;
	std::vector<float> wall_normals;
	std::vector<float> wall_colors;
	std::vector<unsigned int> wall_indices;
	MeshRenderer wall_renderer;
	Shader wall_shader;

	std::vector<float> floor_vertices;
	std::vector<float> floor_normals;
	std::vector<float> floor_colors;
	std::vector<unsigned int> floor_indices;
	MeshRenderer floor_renderer;
	Shader floor_shader;

	std::vector<float> ceiling_vertices;
	std::vector<float> ceiling_normals;
	std::vector<float> ceiling_colors;
	std::vector<unsigned int> ceiling_indices;
	MeshRenderer ceiling_renderer;
	Shader ceiling_shader;

	Sector ParseSector(std::string& line);
	Wall ParseWall(std::string& line);

	void AddWall(Sector& sector, Wall& wall, unsigned int& wall_index);

	void AddFloor(Sector& sector, std::vector<glm::vec3> vertices);
	void AddCeiling(Sector& sector, std::vector<glm::vec3> vertices);

	void AddVertices(std::vector<glm::vec3> vertices, std::vector<float>& target_vertices);
	void AddNormals(std::vector<glm::vec3> normals, std::vector<float>& target_normals);
	void AddColors(std::vector<glm::vec3> colors, std::vector<float>& target_colors);
	void AddIndices(std::vector<unsigned int> indices, std::vector<unsigned int>& target_indices);
};

