#include "camera.h"
#include <math.h>
#include <string.h>
#include "openglstate.h"
#include <GL/glew.h>
#include "m3derror.h"
#include <iostream>
#include "matrix.h"

//RCOO == ROW_COLUMN_ORDER_OFFSET
#define RCOO(row, column, total_rows) row+column*total_rows

namespace M3D
{

Camera::Camera()
{}


Camera::~Camera()
{}


void Camera::set_rotation ( const Rotation & rotation )
{
	_rotation_ = rotation;
}

void Camera::set_location ( const Coords & location )
{
	_location_ = location;
}
void Camera::set_camera_params ( CameraParams& params )
{
	_camera_params_ = params;
}

void Camera::set_camera(OpenGLState *state)
{
	_projection_matrix_.identity();
	_projection_matrix_.translate( _location_.x_pos, _location_.y_pos, _location_.z_pos);
	if(_rotation_.y_angle != 0) _projection_matrix_.rotate( _rotation_.y_angle, 0, 1, 0 );
	if(_rotation_.x_angle != 0) _projection_matrix_.rotate( _rotation_.x_angle, 1, 0, 0 );
	if(_rotation_.z_angle != 0) _projection_matrix_.rotate( _rotation_.z_angle, 0, 0, 1 );
	_projection_matrix_.projection( _camera_params_ );
	glDepthRange(_camera_params_.z_near, _camera_params_.z_far);
	
	int programID = state->get_current_program();
	GLint location = glGetUniformLocation ( programID, "ProjectionMatrix" );
	if(location != -1)glUniformMatrix4fv ( location, 1, GL_FALSE, _projection_matrix_.get_matrix4x4());
	float cam_dir[3];
	cam_dir[0] = cos(_rotation_.y_angle) * cos (_rotation_.x_angle);
	cam_dir[1] = cos(_rotation_.y_angle) * sin (_rotation_.x_angle);
	cam_dir[2] = sin(_rotation_.y_angle);
	location = glGetUniformLocation ( programID, "CameraDirection" );
	if(location !=-1)glUniform3fv ( location, 1, (float*)&_location_);
}
}

