/* -*- mia-c++ -*-
 *
 * This file is part of viewitgui - a library and program for the
 * visualization of 3D data sets. 
 *
 * Copyright (c) Leipzig, Madrid 1999-2013 Mirco Hellmann, Gert Wollny
 *
 * viewitgui 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 3 of the License, or
 * (at your option) any later version.
 *
 * viewitgui 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 viewitgui; if not, see <http://www.gnu.org/licenses/>.
 */


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

#include <viewit/sphere.hh>

CSphereDescr::CSphereDescr(const C3DFVector& loc, float radius, const TColor& color):
	m_loc(loc), 
	m_radius(radius),
	m_color(color)
{
}
	
	
void CSphereDescr::gl_prep()const
{
	glTranslatef(m_loc.x, m_loc.y, m_loc.z);
	glScalef(m_radius, m_radius, m_radius);
	//	glMaterialfv(GL_FRONT,GL_AMBIENT,&m_color.x);
	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,&m_color.x);
	glColor3f(m_color.x, m_color.y, m_color.z); 
}


TSphereList::TSphereList(const string& name):
	TDrawable(name),
	m_GLSphereDrawList(0)
{
	light_on();
	toggle_draw_shiny();
}

void TSphereList::add_sphere(const CSphereDescr& sphere)
{
	m_list.push_back(sphere);
}


void TSphereList::gl_attach()
{
	m_GLSphereDrawList = glGenLists(1);
	m_qobj = gluNewQuadric();
	gluQuadricNormals(m_qobj,(GLenum) GLU_SMOOTH);
	gluQuadricDrawStyle(m_qobj,(GLenum) GLU_FILL);
	gluQuadricOrientation(m_qobj,(GLenum) GLU_OUTSIDE );
	
	glNewList(m_GLSphereDrawList,GL_COMPILE);
	gluSphere(m_qobj, 1.0, 20, 20 );
	glEndList();
	GLenum err = glGetError(); 
	if (err != GL_NO_ERROR) {
		cverr() << "TSphereList::do_gl_draw:" << gluErrorString(err) << "\n"; 
	}
	
}
	

void TSphereList::gl_detach()
{
	glDeleteLists(m_GLSphereDrawList,1);
	gluDeleteQuadric(m_qobj);
}

void TSphereList::do_gl_draw(const TCamera& c)const
{
	SphereList::const_iterator i = m_list.begin();
	SphereList::const_iterator e = m_list.end();

	glEnable(GL_NORMALIZE);
	glMatrixMode(GL_MODELVIEW);
	while (i != e) {
		glPushMatrix();
		(*i).gl_prep();
		glCallList(m_GLSphereDrawList);
		glPopMatrix();
		++i;
	}
	glDisable(GL_NORMALIZE);
	
	GLenum err = glGetError(); 
	if (err != GL_NO_ERROR) {
		cverr() << "TSphereList::do_gl_draw:" << gluErrorString(err) << "\n"; 
	}
}

bool TSphereList::do_handle_key_event(int key)
{
	switch (key) {
	case 'g':toggle_draw_shiny(); break;
	case 'l':toggle_lightmodel();break; // light on both sides or not
	case 'i':toggle_light();break; 
	case 'k':toggle_culling_enable();break; 
	case 'f':
		if (do_cull_front())
			cull_back();
		else
			cull_front();
	default:
		return TDrawable::do_handle_key_event(key);
	}
	return true; 
}
