#include "static_geometry.h"

// ----------------------------------------------------------------------------------------------------------------------------

vec3 vCubeVertices[36] = 
{
	vec3( 0.5f, -0.5f,  0.5f), vec3( 0.5f, -0.5f, -0.5f), vec3( 0.5f,  0.5f, -0.5f), vec3( 0.5f,  0.5f, -0.5f), vec3( 0.5f,  0.5f,  0.5f), vec3( 0.5f, -0.5f,  0.5f),
	vec3(-0.5f, -0.5f, -0.5f), vec3(-0.5f, -0.5f,  0.5f), vec3(-0.5f,  0.5f,  0.5f), vec3(-0.5f,  0.5f,  0.5f), vec3(-0.5f,  0.5f, -0.5f), vec3(-0.5f, -0.5f, -0.5f),
	vec3(-0.5f,  0.5f,  0.5f), vec3( 0.5f,  0.5f,  0.5f), vec3( 0.5f,  0.5f, -0.5f), vec3( 0.5f,  0.5f, -0.5f), vec3(-0.5f,  0.5f, -0.5f), vec3(-0.5f,  0.5f,  0.5f),
	vec3(-0.5f, -0.5f, -0.5f), vec3( 0.5f, -0.5f, -0.5f), vec3( 0.5f, -0.5f,  0.5f), vec3( 0.5f, -0.5f,  0.5f), vec3(-0.5f, -0.5f,  0.5f), vec3(-0.5f, -0.5f, -0.5f),
	vec3(-0.5f, -0.5f,  0.5f), vec3( 0.5f, -0.5f,  0.5f), vec3( 0.5f,  0.5f,  0.5f), vec3( 0.5f,  0.5f,  0.5f), vec3(-0.5f,  0.5f,  0.5f), vec3(-0.5f, -0.5f,  0.5f),
	vec3( 0.5f, -0.5f, -0.5f), vec3(-0.5f, -0.5f, -0.5f), vec3(-0.5f,  0.5f, -0.5f), vec3(-0.5f,  0.5f, -0.5f), vec3( 0.5f,  0.5f, -0.5f), vec3( 0.5f, -0.5f, -0.5f)
};

vec2 vCubeTexCoords[6] =
{
	vec2(0.0f, 0.0f),
	vec2(1.0f, 0.0f),
	vec2(1.0f, 1.0f),
	vec2(1.0f, 1.0f),
	vec2(0.0f, 1.0f),
	vec2(0.0f, 0.0f)
};

vec3 vCubeNormals[6] =
{
	vec3( 1.0f,  0.0f,  0.0f),
	vec3(-1.0f,  0.0f,  0.0f),
	vec3( 0.0f,  1.0f,  0.0f),
	vec3( 0.0f, -1.0f,  0.0f),
	vec3( 0.0f,  0.0f,  1.0f),
	vec3( 0.0f,  0.0f, -1.0f)
};

vec3 vGround[6] = 
{
	vec3(-0.5f, 0.0f,  0.5f),
	vec3( 0.5f, 0.0f,  0.5f),
	vec3( 0.5f, 0.0f, -0.5f),
	vec3( 0.5f, 0.0f, -0.5f),
	vec3(-0.5f, 0.0f, -0.5f),
	vec3(-0.5f, 0.0f,  0.5f)
};

// ----------------------------------------------------------------------------------------------------------------------------

int generateTorus(CBuffer &Buffer, float Radius, float TubeRadius, int SubDivAround, int SubDivTube, mat4x4 &Model)
{
	int VerticesCount = 0;

	vec2 *TexCoords = new vec2[4];
	vec3 *Normals = new vec3[4];
	vec3 *Vertices = new vec3[4];

	int Indices[] = {0, 1, 2, 2, 3, 0};

	float AddAngleAround = PI2 / (float)SubDivAround;
	float AddAngleTube = PI2 / (float)SubDivTube;

	float CurAngleAround = 0.0f;
	int StepsAround = 0;

	while(StepsAround < SubDivAround)
	{
		float NextAngleAround = CurAngleAround + AddAngleAround;

		vec3 Dir1(sin(CurAngleAround), cos(CurAngleAround), 0.0f);
		vec3 Dir2(sin(NextAngleAround), cos(NextAngleAround), 0.0f);

		float CurAngleTube = 0.0f;
		int StepsTube = 0;

		while(StepsTube < SubDivTube)
		{
			float SineTube = sin(CurAngleTube);
			float CosineTube = cos(CurAngleTube);

			float NextAngleTube = CurAngleTube + AddAngleTube;

			float NextSineTube = sin(NextAngleTube);
			float NextCosineTube = cos(NextAngleTube);

			vec3 Mid1 = Dir1 * (Radius - TubeRadius / 2.0f), Mid2 = Dir2 * (Radius - TubeRadius / 2.0f);

			TexCoords[0] = vec2(CurAngleAround / PI2, NextAngleTube / PI2);
			TexCoords[1] = vec2(CurAngleAround / PI2, CurAngleTube / PI2);
			TexCoords[2] = vec2(NextAngleAround / PI2, CurAngleTube / PI2);
			TexCoords[3] = vec2(NextAngleAround / PI2, NextAngleTube / PI2);

			Normals[0] = vec3(0.0f, 0.0f, -NextSineTube) + Dir1 * NextCosineTube;
			Normals[1] = vec3(0.0f, 0.0f, -SineTube) + Dir1 * CosineTube;
			Normals[2] = vec3(0.0f, 0.0f, -SineTube) + Dir2 * CosineTube;
			Normals[3] = vec3(0.0f, 0.0f, -NextSineTube) + Dir2 * NextCosineTube;

			Vertices[0] = Mid1 + vec3(0.0f, 0.0f, -NextSineTube * TubeRadius) + Dir1 * NextCosineTube * TubeRadius;
			Vertices[1] = Mid1 + vec3(0.0f, 0.0f, -SineTube * TubeRadius) + Dir1 * CosineTube * TubeRadius;
			Vertices[2] = Mid2 + vec3(0.0f, 0.0f, -SineTube * TubeRadius) + Dir2 * CosineTube * TubeRadius;
			Vertices[3] = Mid2 + vec3(0.0f, 0.0f, -NextSineTube * TubeRadius) + Dir2 * NextCosineTube * TubeRadius;

			for(int i = 0; i < 6; i++)
			{
				int Index = Indices[i];

				Buffer.AddData(&TexCoords[Index], sizeof(vec2));
				Buffer.AddData(&(Model * vec4(Normals[Index], 0.0f)), sizeof(vec3));
				Buffer.AddData(&(Model * vec4(Vertices[Index], 1.0f)), sizeof(vec3));

				VerticesCount++;
			}

			CurAngleTube += AddAngleTube;
			StepsTube++;
		}

		CurAngleAround += AddAngleAround;
		StepsAround++;
	}

	delete [] TexCoords;
	delete [] Normals;
	delete [] Vertices;

	return VerticesCount;
}
