#include "game.h"
#include "door.h"

void door::add_door(glm::vec3 location){
	locations.push_back(location);
	states.push_back(0);
	open_angles.push_back(0.0f);
}

ssize_t door::collision_index(glm::vec3 position, float distance){
	for(size_t i = 0; i < locations.size(); i++){
		glm::vec3 l = locations[i]; // This'll get optimized out
		if(states[i] == 0){
			if(	size.x/2.0f + distance > abs(l.x-position.x) && 
					size.y/2.0f + distance > abs(l.y-position.y) && 
					size.z/2.0f + distance > abs(l.z-position.z)){
				return i;	
			}
		} else if(states[i] == 3){
			if(	size.z/2.0f + distance > abs(l.x-(position.x - (size.x / 2.0f))) && 
					size.y/2.0f + distance > abs(l.y-position.y) && 
					size.x/2.0f + distance > abs(l.z-position.z + (size.x / 2.0f))){
				return i;	
			}
		}
	}
	return -1;
}

bool door::is_on_idx(glm::vec3 position, size_t index, float height){
	if(states[index] != 0)
		return false;
	return (0.0f < (position.y - locations[index].y) && 
			1.0f > (position.y - height) - (locations[index].y + size.y/2) &&
			size.x/2 > fabs(position.x - locations[index].x) && 
			size.z/2 > fabs(position.z - locations[index].z));
}

void door::activate(size_t index){
	if(states[index] == 3)
		close(index);
	if(states[index] == 0)
		open(index);
}

void door::open(size_t index){
	states[index] = 2;
}

void door::close(size_t index) {
	states[index] = 1;
}

void door::move(int elapsed_time){
	for(size_t i = 0; i < locations.size(); i++){
		if(states[i] == 0 || states[i] == 3) // If all the way open or closed, do nothing
			return;
		if(states[i] == 1) { // closing
			if(open_angles[i] < 0.01f){
				open_angles[i] = 0.0f;
				states[i] = 0; // closed
			} else 
				open_angles[i] -= elapsed_time * (M_PI/2) / 2000000;
		}
		if(states[i] == 2) { // opening
			if(open_angles[i] > M_PI/2){
				open_angles[i] = M_PI/2;
				states[i] = 3; // closed
			} else 
				open_angles[i] += elapsed_time * (M_PI/2) / 2000000;
		}
	}
}

std::vector<glm::mat4> door::create_models() {
	std::vector<glm::mat4> models;
	data_mutex.lock();
	models.reserve(locations.size());
	for(size_t i = 0; i < locations.size(); i++){
		auto l = locations[i];
		glm::mat4 new_model = glm::mat4(1.0f);
		new_model = translate(new_model, l);
		// Rotation:  Is it open or closed?
		// A problem:  Hinges are usually on the edge of doors!
		// Minor caveat:  doors can be hinged on either side, and only open one way
		new_model = glm::translate(new_model, glm::vec3(5, 0, 1));
		new_model = glm::rotate(new_model, open_angles[i], glm::vec3(0, 1, 0));
		new_model = glm::translate(new_model, glm::vec3(-5, 0, -1));
		models.push_back(new_model);
	}
	data_mutex.unlock();
	return models;
}

