#include <math.h>
#include <stdio.h>
#include <time.h>
#include "../../common/objects.h"
#include "../../common/structs.h"
#include "../../common/vector.h"
#include "../../common/misc.h"
#include "../../common/debug.h"
//#include "../render/vector.c"
#include "plane.h"



#include <pthread.h>
extern pthread_mutex_t mutexor;



extern scene_data* main_scene;

double intersect_rectangle(point* origin, vector* projection, object* obj,
	point* old_intersection)
{
	double normDproj;
	double normDobj;
	double distance;
	vector obj_vector;
	point intersection;
	
	vector trans_intersect;
	vector boundary_vector;
	double boundary_length;
	double boundary_proj;

	normDproj = dot_product(&obj->norm, projection);

	if(normDproj == 0) //parallel check
		return 0;

	//if(normDproj > 0) //cull backfaces
	//	return 0;
	sub_vectors(&obj_vector, &obj->pos, origin);

	normDobj = dot_product(&obj->norm, &obj_vector);
	
	
	
//pthread_mutex_lock (&mutexor);
	distance = normDobj / normDproj;
//pthread_mutex_unlock (&mutexor);


	if(distance < 0 )
		return 0;

	//check if point is within bounds
	multiply_vector(&intersection, projection, distance);
	add_vectors(&intersection, origin, &intersection);

	copy_vector(&obj->pos, &trans_intersect);
	invert_vector(&trans_intersect);
	add_vectors(&trans_intersect, &trans_intersect, &intersection);
	
	boundary_length = obj->radius;
	multiply_vector(&boundary_vector, &obj->up, boundary_length);

	//boundary_proj = dot_product(intersection, &boundary_vector);
	boundary_proj = dot_product(&trans_intersect, &boundary_vector);
	boundary_proj = boundary_proj / boundary_length;

//	copy_vector(&boundary_vector, &main_scene->models[3]->pos);
	
	if(boundary_proj > boundary_length)
	{
		return 0;
		obj->diff.r = 0;
		obj->diff.g = 255;
		obj->diff.b = 0;
		return distance;
	}
	
	if(boundary_proj < -boundary_length)
	{
		return 0;
		obj->diff.r = 0;
		obj->diff.g = 0;
		obj->diff.b = 255;
		return distance;
	}


	boundary_length = obj->radius;

	multiply_vector(&boundary_vector, &obj->rot, boundary_length);
	boundary_proj = dot_product(&trans_intersect, &boundary_vector);
	boundary_proj = boundary_proj / boundary_length;

	if(boundary_proj > boundary_length)
	{
		return 0;
		obj->diff.r = 255;
		obj->diff.g = 0;
		obj->diff.b = 0;
		return distance;
	}

	if(boundary_proj < -boundary_length)
	{
		return 0;
		obj->diff.r = 255;
		obj->diff.g = 255;
		obj->diff.b = 0;
		return distance;
	}
		
//	obj->diff.r = 255;
//	obj->diff.g = 255;
//	obj->diff.b = 255;


	return distance;
}

/*****************************************************
 Calculates the normal vector at a point, on an object
 *****************************************************/
vector* normal_rectangle(point* q, object* objectHit, vector* n)
{
	n->x = objectHit->norm.x;
	n->y = objectHit->norm.y;
	n->z = objectHit->norm.z;
	return n;
}

model *rectangle_polygon(object *obj)
{
	model *m;
	
	m = (model*)malloc(sizeof(model));
	m->points = (vector*)malloc(4 * sizeof(vector));
	m->triangles = (triangle*)malloc(2 * sizeof(triangle));
	
	add_vectors(&m->points[0], &obj->up, &obj->rot);
	multiply_vector(&m->points[2], &m->points[0], -obj->radius);
	multiply_vector(&m->points[0], &m->points[0], obj->radius);

	copy_vector(&obj->rot, &m->points[1]);
	invert_vector(&m->points[1]);
	add_vectors(&m->points[1], &obj->up, &m->points[1]);
	multiply_vector(&m->points[3], &m->points[1], -obj->radius);
	multiply_vector(&m->points[1], &m->points[1], obj->radius);
	
	m->triangles[0].vertices[0] = &m->points[0];
	m->triangles[0].vertices[1] = &m->points[1];
	m->triangles[0].vertices[2] = &m->points[2];

	m->triangles[1].vertices[0] = &m->points[0];
	m->triangles[1].vertices[1] = &m->points[2];
	m->triangles[1].vertices[2] = &m->points[3];

	m->num_triangles = 2;
	m->num_points = 4;

	return m;
}

void rectangle_initialize(object *obj)
{
	cross_product(&obj->norm, &obj->up, &obj->rot);
	normalize(&obj->rot);
	cross_product(&obj->rot, &obj->norm, &obj->up);
	normalize(&obj->up);
	
	obj->polygon = rectangle_polygon(obj);
}
