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

#include "aabb_node.h"
#include "../Model/Group.h"

BEGIN_TEG_NAMESPACE();

AABBNode::AABBNode() : left_(NULL), right_(NULL), number_of_faces_(0) {}

AABBNode::AABBNode(const Group& group) : left_(NULL), right_(NULL) {
  // Set the value of the Bounding Box.
  bounding_box_ = AABB(group);

  // Update the number of faces and the faces inside the bounding box.
  number_of_faces_ = static_cast<int>(group.faceList.size());
  faces_.resize(number_of_faces_);
  for (int i = 0; i < number_of_faces_; ++i) faces_[i] = i;
}

AABBNode::AABBNode(const Group& group, const std::vector<int>& faces)
    : left_(NULL), right_(NULL) {
  // Set the value of the Bounding Box.
  bounding_box_ = AABB(group, faces);

  // Update the number of faces and the faces inside the bounding box.
  number_of_faces_ = static_cast<int>(faces.size());
  faces_ = faces;
}

AABBNode::~AABBNode() { 
  left_ = NULL; right_ = NULL;
}

// Method to display the bounding box.
void AABBNode::Render() const { 
  //if (nFaces)
    bounding_box_.Render();
  if (left_) left_->Render();
  if (right_) right_->Render();
}

// Method to display the bounding box.
void AABBNode::Render(int level, int current) const {
  if (level == current) bounding_box_.Render();
  if (left_ && current < level) left_->Render(level, current + 1);
  if (right_ && current < level) right_->Render(level, current + 1);
}

bool AABBNode::Load(FILE* f) {
  // Load the data of the bounding box
  bounding_box_.Load(f);

  // Load each data branch of the tree.
  int k_bytes_read;
  _TCHAR buffer[10];
  memset(buffer, 0, sizeof(buffer));
  
  k_bytes_read = fread(buffer, sizeof(_TCHAR), 1, f);
  assert(k_bytes_read == 1);
  if (strcmp(buffer, _T("\1")) == 0) {
    left_ = new AABBNode();
    if (!left_->Load(f)) return false;
  } else if (strcmp(buffer, _T("\0")) == 0) {
    left_ = NULL;
  } else {
    return false;
  }
  k_bytes_read = fread(buffer, sizeof(_TCHAR), 1, f);
  assert(k_bytes_read == 1);
  if (strcmp(buffer, _T("\1")) == 0) {
    right_ = new AABBNode();
    if (!right_->Load(f)) return false;
  } else if (strcmp(buffer, _T("\0")) == 0) {
    right_ = NULL;
  } else {
    return false;
  }
  return true;
}

bool AABBNode::Save(FILE* f) const {
  // Save the data of the boundingBox.
  bounding_box_.Save(f);
	
  // Save each data branch of the AABBNode.
  if (left_) {
    fwrite(_T("\1"), sizeof(_TCHAR), 1, f);
    left_->Save(f);
  } else {
    fwrite(_T("\0"), sizeof(_TCHAR), 1, f);
  }
  if (right_) {
    fwrite(_T("\1"), sizeof(_TCHAR), 1, f);
    right_->Save(f);
  } else {
    fwrite(_T("\0"), sizeof(_TCHAR), 1, f);
  }
  return true;
}

END_TEG_NAMESPACE();
