#include <math.h>
#include <stdlib.h>
#include <stdio.h>

#include "demo_meshes.h"
#include "math_vector3D.h"
#include "math_coord.h"
#include "math_defs.h"

void VectorToPoint(vector3D *v, point3D *p)
{
	p->x = v->x;
	p->y = v->y;
	p->z = v->z;
}

void GenFlowerMesh(mesh3D_gen *msh, float radius, float par2, float par3)
{
	int npts_x = msh->npls_x;
	int npts_y = msh->npls_y + 1;
	int npts_size = npts_x * npts_y;

	msh->points = (point3D*)malloc(npts_size * sizeof(point3D));
	msh->vx_normals = (vector3D*)malloc(npts_size * sizeof(vector3D));

	vector3D pos;

	float dphi = 180.0f / (float)(npts_y - 1);
	float dtheta = 360.0f / (float)npts_x;

	int i = 0;
	float phi = 0.0f;
	for (int y=0; y<npts_y; y++)
	{
		float theta = 0.0f;
		for (int x=0; x<npts_x; x++)
		{
			float r = radius + sin(theta/par2) + sin(phi/par3);

			GetSphericalCoords(theta, phi, r, pos);
			VectorToPoint(&pos, &msh->points[i]);

			vector3D tang_u, tang_v;
			tang_u.x = -(1+pos.y * pos.y); tang_u.y = pos.x * pos.y; tang_u.z = pos.x;
			tang_v.x = pos.x * pos.y; tang_v.y = -(1+pos.x * pos.x); tang_v.z = pos.y;
			V3D_Normalize(&tang_u);
			V3D_Normalize(&tang_v);

			float dif = 1.0f;
			float rx0 = radius + sin((theta-dif)/par2) + sin(phi/par3);
			float rx1 = radius + sin((theta+dif)/par2) + sin(phi/par3);
			float ry0 = radius + sin(theta/par2) + sin((phi+dif)/par3);
			float ry1 = radius + sin(theta/par2) + sin((phi-dif)/par3);
			float dx = rx1 - rx0;
			float dy = ry1 - ry0;

			V3D_Normalize(&pos);

			vector3D test;
			test.x = tang_u.x * dx;
			test.y = tang_v.x * dy;
			test.z = tang_u.z * tang_v.z;

			//V3D_Copy(&pos, &msh->vx_normals[i]);
			V3D_Copy(&test, &msh->vx_normals[i]);

			theta += dtheta;
			i++;
		}
		phi += dphi;
	}

	i = 0;
	for (int y=0; y<msh->npls_y; y++)
	{
		for (int x=0; x<msh->npls_x; x++)
		{
			msh->quads[i].p4 = x + (y + 1) * npts_x;
			msh->quads[i].p3 = (x + 1) % npts_x + (y + 1) * npts_x;
			msh->quads[i].p2 = (x + 1) % npts_x + y * npts_x;
			msh->quads[i].p1 = x + y * npts_x;
			i++;
		}
	}
}

mesh3D_gen *GenMesh(int quads_width, int quads_height, int way, float par1, float par2, float par3)
{
	mesh3D_gen *mesh_gen = (mesh3D_gen*)malloc(sizeof(mesh3D_gen));

	mesh_gen->npls_x = quads_width;
	mesh_gen->npls_y = quads_height;
	int npls_size = mesh_gen->npls_x * mesh_gen->npls_y;

	mesh_gen->quads = (quad2D*)malloc(npls_size * sizeof(quad2D));

	switch(way)
	{
		case GEN_FLOWER_MESH:
			GenFlowerMesh(mesh_gen, par1, par2, par3);
		break;
	}

	return mesh_gen;
}