#pragma once
#ifndef RTRCUBEMAP_H
#define RTRCUBEMAP_H
#define STB_IMAGE_IMPLEMENTATION

//////////////
// INCLUDES //
//////////////
#include <glad/glad.h>
#include <GLFW/glfw3.h> // GLFW must be included after GLAD!

#include "rtrTextureLoadingFlipped.h" //rtrTexture
#include "stb_image.h"
#include "rtrSetupGLFWandGLAD.h" //rtrGLFWGLAD::
#include "rtrShader.h" //rtrShader::
#include "rtrVAO.h"
#include "DrawableObject.h"

class CubeMap : public DrawableObject
{

	public:
		rtrShader::Shader Shader;
		unsigned int VAO;
		unsigned int TextureId;
		float strength = 1.0f;

		// Constructors
		CubeMap(std::string path) :
			Shader(rtrShader::Shader("shaders\\skyBox.vert", "shaders\\skyBox.frag")),
			VAO(0),
			TextureId(0)
		{
			// vertices for a cube
			float verticesSkyBox[] =
			{
				// positions          
				-1.0f,  1.0f, -1.0f,
				-1.0f, -1.0f, -1.0f,
				 1.0f, -1.0f, -1.0f,
				 1.0f, -1.0f, -1.0f,
				 1.0f,  1.0f, -1.0f,
				-1.0f,  1.0f, -1.0f,

				-1.0f, -1.0f,  1.0f,
				-1.0f, -1.0f, -1.0f,
				-1.0f,  1.0f, -1.0f,
				-1.0f,  1.0f, -1.0f,
				-1.0f,  1.0f,  1.0f,
				-1.0f, -1.0f,  1.0f,

				 1.0f, -1.0f, -1.0f,
				 1.0f, -1.0f,  1.0f,
				 1.0f,  1.0f,  1.0f,
				 1.0f,  1.0f,  1.0f,
				 1.0f,  1.0f, -1.0f,
				 1.0f, -1.0f, -1.0f,

				-1.0f, -1.0f,  1.0f,
				-1.0f,  1.0f,  1.0f,
				 1.0f,  1.0f,  1.0f,
				 1.0f,  1.0f,  1.0f,
				 1.0f, -1.0f,  1.0f,
				-1.0f, -1.0f,  1.0f,

				-1.0f,  1.0f, -1.0f,
				 1.0f,  1.0f, -1.0f,
				 1.0f,  1.0f,  1.0f,
				 1.0f,  1.0f,  1.0f,
				-1.0f,  1.0f,  1.0f,
				-1.0f,  1.0f, -1.0f,

				-1.0f, -1.0f, -1.0f,
				-1.0f, -1.0f,  1.0f,
				 1.0f, -1.0f, -1.0f,
				 1.0f, -1.0f, -1.0f,
				-1.0f, -1.0f,  1.0f,
				 1.0f, -1.0f,  1.0f
			};

			// Skybox VAO_Body 
			unsigned int VBO;
			unsigned int dimensionsOfAttributesSkyBox[] = { 3 };
			rtrVAO::createVAOwithoutEBO(VAO, VBO, verticesSkyBox, 36, 1, dimensionsOfAttributesSkyBox);

			// Cube Map Textures
			std::vector<std::string> cubeMapPaths({ path + "right.jpg", path + "left.jpg", path + "top.jpg", path + "bottom.jpg", path + "front.jpg", path + "back.jpg" });
			TextureId = rtrTexture::loadCubeMapFromFile(cubeMapPaths);

			// Configure Skybox Shader
			Shader.use();
			Shader.setInt("textureUnitCubeMap", 0);
		}

		void UpdateViewAndProjectionMatrices(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
		{
			Shader.use();
			glm::mat4 viewMatrixSkyBox = glm::mat4(glm::mat3(viewMatrix));
			Shader.setMat4F("viewMatrix", viewMatrixSkyBox);
			Shader.setMat4F("projectionMatrix", projectionMatrix);
			Shader.setFloat("strength", strength);
		}

		void Draw()
		{
			Shader.use();
			glDepthFunc(GL_LEQUAL);
			glBindVertexArray(VAO);
			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_CUBE_MAP, TextureId);
			glDrawArrays(GL_TRIANGLES, 0, 36);
			glDepthFunc(GL_LESS);
		}
};
#endif