// Author: Hector Navarro (hnavarro@ciens.ucv.ve),
//         Juan Carlos De Abreu (jcabreur@gmail.com)

#include "obb.h"
#include "aabb_inl.h"
#include "../Includes/OpenGL.h"

BEGIN_TEG_NAMESPACE();

OBB::OBB() {}

OBB::OBB(const AABB& aabb, const Mat4f& m) {
  // Initialize the obb with the aabb.
  const Vec3f kDirection[3] = { Vec3f(1.0f, 0.0f, 0.0f),
                                Vec3f(0.0f, 1.0f, 0.0f),
                                Vec3f(0.0f, 0.0f, 1.0f) };

  distance_ = aabb.max_vertex() - aabb.min_vertex();
  orientation_ = math::vec3(m * math::vec4(aabb.min_vertex(), 1.0f));
  for (int i = 0; i < 3; ++i) {
    axis_[i] = math::vec3(m * math::vec4(kDirection[i], 0.0f));
    axis_[i].normalize();
  }
  SetVertex();
}

OBB::~OBB() {}

void OBB::SetVertex() {
  // Calculate the scaled axis.
  const Vec3f d1 = axis_[0] * distance_[0];
  const Vec3f d2 = axis_[1] * distance_[1];
  const Vec3f d3 = axis_[2] * distance_[2];

  // Update each vertex.
  vertex_.resize(8);
  vertex_[0] = orientation_;
  vertex_[1] = vertex_[0] + d1;
  vertex_[2] = vertex_[1] + d2;
  vertex_[3] = vertex_[0] + d2;
  vertex_[4] = vertex_[0] + d3;
  vertex_[5] = vertex_[4] + d1;
  vertex_[6] = vertex_[5] + d2;
  vertex_[7] = vertex_[4] + d2;
}

void OBB::Render() const {
  // Display the OBB with the active graphic API.
  glBegin(GL_LINE_LOOP);
    glVertex3f(vertex_[0].x, vertex_[0].y, vertex_[0].z);
    glVertex3f(vertex_[1].x, vertex_[1].y, vertex_[1].z);
    glVertex3f(vertex_[2].x, vertex_[2].y, vertex_[2].z);
    glVertex3f(vertex_[3].x, vertex_[3].y, vertex_[3].z);
  glEnd();
  
  glBegin(GL_LINE_LOOP);
    glVertex3f(vertex_[4].x, vertex_[4].y, vertex_[4].z);
    glVertex3f(vertex_[5].x, vertex_[5].y, vertex_[5].z);
    glVertex3f(vertex_[6].x, vertex_[6].y, vertex_[6].z);
    glVertex3f(vertex_[7].x, vertex_[7].y, vertex_[7].z);
  glEnd();
  
  glBegin(GL_LINES);
    glVertex3f(vertex_[0].x, vertex_[0].y, vertex_[0].z);
    glVertex3f(vertex_[4].x, vertex_[4].y, vertex_[4].z);
    glVertex3f(vertex_[1].x, vertex_[1].y, vertex_[1].z);
    glVertex3f(vertex_[5].x, vertex_[5].y, vertex_[5].z);
    glVertex3f(vertex_[2].x, vertex_[2].y, vertex_[2].z);
    glVertex3f(vertex_[6].x, vertex_[6].y, vertex_[6].z);
    glVertex3f(vertex_[3].x, vertex_[3].y, vertex_[3].z);
    glVertex3f(vertex_[7].x, vertex_[7].y, vertex_[7].z);
  glEnd();
}

END_TEG_NAMESPACE();
