/* -*- 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 <viewit/light.hh>
#include <GL/gl.h>
#include <cassert>
#include <iostream>

class TData {
	friend class TLight; 
	C3DFVector pos; 
	int no;
	bool down_state; 
	C2DFVector m_loc;
	TData(const C3DFVector& pos_, int no_);
};

TData::TData(const C3DFVector& pos_, int no_):
	pos(pos_),
	no(no_),
	down_state(false)
{
	// every GL impl. has 8 lights 
	assert(no < 8);
}

TLight::TLight(const C3DFVector& pos, const TColor& color,int no):
	TDrawable(string("Light_") + string(1, char('0'+no))),
	data(new TData(pos,no))
{
	set_color1(color);
	show();
}

TLight::~TLight()
{
	delete data; 
}

void TLight::gl_use() const 
{
	GLenum lightnum = GLenum(GL_LIGHT0 + data->no); 
	glLightfv(lightnum,GL_DIFFUSE,&get_color1().x);
	const GLfloat specular[]= {0.1f,0.1f,0.1f,1.0f};
	glLightfv(lightnum, GL_SPECULAR, specular );

	pre_transformation();
	glLightfv(lightnum,GL_POSITION,&data->pos.x);
	end_transformation();
}

void TLight::on()const
{
	glEnable(GLenum(GL_LIGHT0 + data->no));
}

void TLight::off()const
{
	glDisable(GLenum(GL_LIGHT0 + data->no));
}

void TLight::do_gl_draw(const TCamera& c) const
{
	// light is not visible if not selected
	if (! is_selected())
		return; 
#if 0	
	//draw something
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	pre_transformation();	
	glBegin(GL_LINES); 
	glColor3fv(&get_color1().x);
	glVertex3f(data->pos.x - 2.0f, data->pos.y       , data->pos.z       );
	glVertex3f(data->pos.x + 2.0f, data->pos.y       , data->pos.z       );
	glVertex3f(data->pos.x       , data->pos.y - 2.0f, data->pos.z       );
	glVertex3f(data->pos.x       , data->pos.y + 2.0f, data->pos.z       );
	glVertex3f(data->pos.x       , data->pos.y       , data->pos.z - 2.0f);
	glVertex3f(data->pos.x       , data->pos.y       , data->pos.z + 2.0f);
	glEnd();
	glPopMatrix();
#endif	
}

bool TLight::do_handle_key_event(int key)
{
	switch (key) {
	case 't':
	case 'v':break; 
	
	case 's':if (data->down_state) break; 
		
	default:
		return TDrawable::do_handle_key_event(key);
	}
	return true; 
}

bool TLight::do_handle_mouse_event(int button,int x, int y)
{
	if (button & EV_MOUSE2_DOWN) {
		data->down_state = true; 
	} else if (button & EV_MOUSE_MOVE && data->down_state) {
		add_rotation(C3DFVector(y - data->m_loc.y, 
					x - data->m_loc.x,
					0.0f));
	} else if (button & EV_MOUSE2_UP && data->down_state) {
		data->down_state = false; 
	} else {
		return false; 
	}
	
	data->m_loc.x = x; 
	data->m_loc.y = y; 
	return true; 
}

