/* Copyright (C) 2007  Mikko Sysikaski <mikko.sysikaski@gmail.com>
 * This program is free software distributed under GNU General Public License
 * version 3 or (at your option) any later version.
 * No warranty of any kind is provided. See the accompanying file COPYING for details.
 */

#include "drawutils.h"
#include <math.h>
#include <GL/gl.h>

#ifdef M_PI
#define PI M_PI
#else
#define PI 3.14159265358979323846
#endif

namespace drawutils {

	inline void normalize(float v[3])
	{
		float x = 1.0f/sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
		v[0] *= x;
		v[1] *= x;
		v[2] *= x;
	}

	inline void split(const float* a, const float* b, const float* c, int depth)
	{
		if (depth == 0) {
			glNormal3fv(a);
			glVertex3fv(a);
			glNormal3fv(b);
			glVertex3fv(b);
			glNormal3fv(c);
			glVertex3fv(c);
			return;
		}
		depth--;
#define MIDDLE(x, y) {(x[0]+y[0])/2, (x[1]+y[1])/2, (x[2]+y[2])/2}
		float ab[] = MIDDLE(a,b);
		float bc[] = MIDDLE(b,c);
		float ca[] = MIDDLE(c,a);
#undef MIDDLE
		normalize(ab);
		normalize(bc);
		normalize(ca);
	
		split(a, ab, ca, depth);
		split(b, bc, ab, depth);
		split(c, ca, bc, depth);
		split(ab, bc, ca, depth);
	}

	void renderBall(int levels)
	{
	// copypasta from http://mathworld.wolfram.com/Tetrahedron.html
	// aka. don't fucking ask
		float tmp = -sqrt(6)/12;
		float a[] = {sqrt(3)/3, 0, tmp};
		float b[] = {-sqrt(3)/6, -0.5f, tmp};
		float c[] = {-sqrt(3)/6, 0.5f, tmp};
		float d[] = {0, 0, sqrt(6)/3+tmp};
		normalize(a);
		normalize(b);
		normalize(c);
		normalize(d);
	
		glBegin(GL_TRIANGLES);
		split(a, b, c, levels);
		split(b, d, c, levels);
		split(d, a, c, levels);
		split(a, d, b, levels);
		glEnd();
	}

	void renderSphere(int edges, float rad)
	{
		float ooe = 1.0f/edges;
		glBegin(GL_POLYGON);
		for(int i=0; i<edges; ++i)
			glVertex3f(sin(i*2.0f*PI*ooe)*rad, 0, cos(i*2.0f*PI*ooe)*rad);
		glEnd();
	}
	
}	// end namespace drawutils
