//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// rotation.h
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2001 Vincent LE PRINCE
// This file is part of the TRUEVISION Package

//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
//*******************************************************************************************
#ifndef ROTATION_H
#define ROTATION_H
using namespace std;
#include <math.h>
#include "GL/gl.h"
#include "GL/glu.h"
//#include "gtkgl/gtkglarea.h"
#include <iostream>
#include <fstream>

//**************************************************
// Classe Rotation
//**************************************************
class Rotation {
	private:
		double quatern[4];
		GLfloat rotmatrix[4][4];
		double euler[3];

		int renorm_count;
		bool euler_utd;
		double trackball_size;

		void add_quats( double q[4] );
		void normalize();
		void rebuild_matrix();
		void axis_to_quat( double a[3], double phi, double *q );
		
	public:
		Rotation() { trackball_size = 0.8; reset(); }
		void reset();
		
		void set( double a, double b, double c, double d ) { quatern[0]=a;  quatern[1]=b; quatern[2]=c; quatern[3]=d; rebuild_matrix(); }
		void set( const double *v ) { for ( register int i = 0 ; i < 3 ; i++ ) quatern[i]=v[i]; rebuild_matrix(); }
		void set_from_euler( double phi, double theta, double etha );
		void set_from_euler( double *a ) { set_from_euler( a[0], a[1], a[2] ); }
		void get_as_euler( double *a );

		void add( double x, double y, double z, double a );
		void add( double *axis, double angle );
		void rotate_vector( double *v, double x, double y, double z );
		void rotate_vector( float *v, double x, double y, double z );
		void rotate_z( double *v );
		void rotate_vector_inverse( float *v, double x, double y, double z );
		
		void trackball( double p1x, double p1y, double p2x, double p2y );
		void gl_rotate() { glMultMatrixf( &rotmatrix[0][0] ); }
		
		void save( ofstream & file );
		void load( ifstream & file );
		
		// Debug
		void print_quats() { cout << "\nquats -> "; for ( int i = 0 ; i < 4 ; i++ ) cout << quatern[i] << ", "; cout.flush(); }
};

#endif
