//******************************************************************************
//* Christopher A. Robbins                                                     *
//* Graphics:  Assignment Three                                                *
//* November 5, 2001                                                           *
//******************************************************************************
#ifndef	__TRANSFORMS_H__
#define	__TRANSFORMS_H__

#include <math.h>
#include <gl/glut.h>

// Custom rotate transform using only OpenGL glMatrixMode and glMultMatrix*
void rotate(double angle, double x, double y, double z) {

	angle = angle*(M_PI/180);

	CMat3T<double> p_perp1(1.0, 0.0, 0.0, 0.0,
                           0.0, 1.0, 0.0, 0.0,
						   0.0, 0.0, 1.0, 0.0,
						   0.0, 0.0, 0.0, 0.0);
	p_perp1 = p_perp1 * cos(angle);

	CMat3T<double> p_perp2(x*x, y*x, z*x, 0.0,
		                   x*y, y*y, z*y, 0.0,
						   x*z, y*z, z*z, 0.0, 
						   0.0, 0.0, 0.0, 0.0);
	p_perp2 = p_perp2 * (1.00 - cos(angle));

	CMat3T<double> p_perp = p_perp1 + p_perp2;

	CMat3T<double> p_parallel(0.0,  -z,   y, 0.0,
		                        z, 0.0,  -x, 0.0,
							   -y,   x, 0.0, 0.0,
							  0.0, 0.0, 0.0, 0.0);
	p_parallel = p_parallel * sin(angle);


	CMat3T<double> p_rotate = p_perp + p_parallel;

	p_rotate[15] = 1.0f;

	glMatrixMode(GL_MODELVIEW);
	glMultMatrixd(&p_rotate[0]);



}

// Custom translate transform using only OpenGL glMatrixMode and glMultMatrix*
void translate(double x, double y, double z) {

	double transMatrix[16] = { 1.0, 0.0, 0.0, 0.0,
 	                           0.0, 1.0, 0.0, 0.0,
							   0.0, 0.0, 1.0, 0.0,
							     x,   y,   z, 1.0 };

	glMatrixMode(GL_MODELVIEW);
	glMultMatrixd(transMatrix);

}

// Custom scale transform using only OpenGL glMatrixMode and glMultMatrix*
void scale(double x, double y, double z) {

	double transMatrix[16] = {   x, 0.0, 0.0, 0.0,
 	                           0.0,   y, 0.0, 0.0,
							   0.0, 0.0,   z, 0.0,
							   0.0, 0.0, 1.0, 1.0 };

	glMatrixMode(GL_MODELVIEW);
	glMultMatrixd(transMatrix);

}

// Custom look_at transform using only OpenGL glMatrixMode and glMultMatrix*
void look_at(CVec3T<float> cameraPosition, CVec3T<float>tableCenter) {

   CVec3T<float>  v;
   CVec3T<float>  u;
   CVec3T<float>  e_y(0.0, 1.0, 0.0);

   glMatrixMode(GL_MODELVIEW);

   v = tableCenter - cameraPosition;
   v = v.dir();

   u = e_y - ((e_y.dot(v)) * v);
   u = u.dir();

   double look_at_rotate[16] = {
	   cross(v,u).x(), u.x(), -v.x(), 0.0,
       cross(v,u).y(), u.y(), -v.y(), 0.0, 
	   cross(v,u).z(), u.z(), -v.z(), 0.0,
			    0.0,   0.0,    0.0,   1.0 };
   
   glMultMatrixd(look_at_rotate);

   double look_at_translate[16] = {
	                  1.0,                 0.0,                 0.0, 0.0,
					  0.0,                 1.0,                 0.0, 0.0,
					  0.0,                 0.0,                 1.0, 0.0,
	  -cameraPosition.x(), -cameraPosition.y(), -cameraPosition.z(), 1.0 };

   glMultMatrixd(look_at_translate);

}
#endif /*  __TRANSFORMS_H__ */
