
#include "lights.h"


Lights::Lights() {

	_lights = new _Light[10];
	_size = 10;
	_num_lights = 0;

	_ambient[0] = _ambient[1] = _ambient[2] = 0;
}

Lights::~Lights() {

	delete [] _lights;
}

Lights& Lights::CopyFrom(const Lights &L) {

	if ((!_lights) || (_size != L._size)) {
		delete [] _lights;
		_lights = new _Light[_size = L._size];
		_num_lights = L._num_lights;
	}

	for (int i=0; i<_num_lights; i++) {
		_lights[i]._direction = L._lights[i]._direction;
		_lights[i]._color[0] = L._lights[i]._color[0];
		_lights[i]._color[1] = L._lights[i]._color[1];
		_lights[i]._color[2] = L._lights[i]._color[2];
	}

	return *this;
}

void Lights::SetAmbientLight(float *color) {

	_ambient[0] = color[0];
	_ambient[1] = color[1];
	_ambient[2] = color[2];
}

void Lights::AddDirectionalLight(const Vec4 &d, float *color) {

	if (_num_lights >= _size) {
		cerr << "Error in Lights::AddDirectionalLight(): "
			 << "cannot add another light" << endl;
		return;
	}

	_lights[_num_lights]._direction = d;
	_lights[_num_lights]._direction.MakeUnit();
	_lights[_num_lights]._color[0] = color[0];
	_lights[_num_lights]._color[1] = color[1];
	_lights[_num_lights]._color[2] = color[2];

	_num_lights++;
}

void Lights::Illuminate(const Vec4 &N, const float *color_in, float *color_out){

	float color_tmp[3];

	color_tmp[0] = _ambient[0];
	color_tmp[1] = _ambient[1];
	color_tmp[2] = _ambient[2];

	for (int i=0; i<_num_lights; i++) {
		float d = N.Dot3(_lights[i]._direction);
		if (d > 0) {
			color_tmp[0] += _lights[i]._color[0] * d;
			color_tmp[1] += _lights[i]._color[1] * d;
			color_tmp[2] += _lights[i]._color[2] * d;
		}
	}

	color_out[0] = color_tmp[0] * color_in[0];
	color_out[1] = color_tmp[1] * color_in[1];
	color_out[2] = color_tmp[2] * color_in[2];

	if (color_out[0] > 1.0) color_out[0] = 1.0;
	if (color_out[1] > 1.0) color_out[1] = 1.0;
	if (color_out[2] > 1.0) color_out[2] = 1.0;
}
