#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "draw.h"

void draw_disc(int sections)
{
	int i;

	glBegin(GL_POLYGON);
	
	glNormal3f(0, 1, 0);
	for (i=0; i<sections; ++i) {
		float angle = (2 * M_PI * i) / sections;
		glVertex3f(cos(angle), 0.0, sin(angle));
	}

	glEnd();
}

void draw_ring(int sections)
{
	int i;

	glBegin(GL_QUAD_STRIP);
	for(i=0; i<=sections; ++i){
		GLfloat x = cos(2 * M_PI * i / sections);
		GLfloat y = sin(2 * M_PI * i / sections);

		glNormal3f(x, 0, y);
		glVertex3f(x, -0.5, y);
		glVertex3f(x, 0.5, y);
	}
	glEnd();
}

void draw_ring_frill(int sections)
{
	int i;

	glBegin(GL_QUAD_STRIP);
	for(i=0; i<=sections; ++i){
		GLfloat x = cos(2 * M_PI * i / sections);
		GLfloat y = sin(2 * M_PI * i / sections);

		glNormal3f(x, 0, y);
		glVertex3f(x, 0.5, y);
		if (i % 2 == 0)
			glVertex3f(x, -0.5, y);
		else
			glVertex3f(x, -0.4, y);
	}
	glEnd();
}

void draw_cylinder(int sections)
{
	glPushMatrix();

	// draw the top end

	glTranslatef(0.0, -0.5, 0.0);
	draw_disc(sections);

	// draw the bottom end

	glTranslatef(0.0, 1.0, 0.0);
	draw_disc(sections);

	glPopMatrix();

	// draw sides

	draw_ring(sections);
}

static inline void drawsphere_point(GLfloat x, GLfloat y, GLfloat z)
{
	glNormal3f(x, y, z);
	glVertex3f(x, y, z);
}

void draw_partial_sphere(int hsections, int vsections, int total_vsections)
{
	int v, h;

	for (v=0; v<vsections; ++v) {
		float angle1 = (M_PI * v) / total_vsections - M_PI_2;
		float angle2 = (M_PI * (v+1)) / total_vsections - M_PI_2;
		float sinangle1 = sin(angle1), cosangle1 = cos(angle1);
		float sinangle2 = sin(angle2), cosangle2 = cos(angle2);

		glBegin(GL_QUAD_STRIP);

		for (h=0; h<=hsections; ++h) {
			GLfloat hangle = 2 * M_PI * h / hsections;
			GLfloat sinhangle = sin(hangle);
			GLfloat coshangle = cos(hangle);

			drawsphere_point(coshangle * cosangle1,
				   	-sinangle1,
				   	 sinhangle * cosangle1);
			drawsphere_point(coshangle * cosangle2,
				   	-sinangle2,
				   	 sinhangle * cosangle2);

		}

		glEnd();
	}
}

void draw_hemisphere(int hsections, int vsections)
{
	draw_partial_sphere(hsections, vsections/2, vsections);
}

void draw_sphere(int hsections, int vsections)
{
	draw_partial_sphere(hsections, vsections, vsections);
}

