// Author: Hector Navarro (hnavarro@ciens.ucv.ve)
//         Juan Carlos De Abreu (jcabreur@gmail.com)
//
// This class define a Node of AABB in an AABBTree.

#ifndef AABB_NODE_H__
#define AABB_NODE_H__

#include "vector"

#include "../global.h"
#include "aabb.h"
#include "../Base/Memory/SmartPointer.h"

BEGIN_TEG_NAMESPACE();

class AABBNode : public IMMObject {
 public:
  // AABBNode constructors and destructor.
  AABBNode();
  AABBNode(const Group& group);
  AABBNode(const Group& group, const std::vector<int>& faces);
  ~AABBNode();

  // Accessor and mutator methods to AABBNode attributes.
  int number_of_faces() const;
  const AABB& bounding_box() const;
  const std::vector<int>& faces() const;
  const SmartPointer<AABBNode>& left() const;
  const SmartPointer<AABBNode>& right() const;
  void set_number_of_faces(int number_of_faces);
  void set_left(const SmartPointer<AABBNode>& left);
  void set_right(const SmartPointer<AABBNode>& right);

  // Method to delete all the faces index.
  void ClearAllFaces();

  // Method to know if the AABBNode is a leaf node.
  inline bool IsLeaf() { return number_of_faces_ == 0; }

  // Methods to display an AABBNode and it's AABBNode childs.
  void Render() const;
  void Render(int level, int current = 0) const;

  // Methods to save and load to a file the AABBNode.
  bool Load(FILE* f);
  bool Save(FILE* f) const;
  AUTO_SIZE();

 private:
  // AABBNode attributes, number of faces inside of a bounding box of a
  // geometry, index of each face inside the bounding box, bounding box that
  // define the AABBNode and pointers to the left and right child AABBNodes.
  int number_of_faces_;
  std::vector<int> faces_;
  AABB bounding_box_;
  SmartPointer<AABBNode> left_, right_;
  DISALLOW_COPY_AND_ASSIGN(AABBNode);
};

END_TEG_NAMESPACE();

#endif  // AABB_NODE_H__
