// Author: Hector Navarro (hnavarro@ciens.ucv.ve)
//         Juan Carlos De Abreu (jcabreur@gmail.com)
//
// This class define a Tree of AABBNode(s).
//
// The method Init need be call after the creation of the object, and the
// method Release need be called before the end of the app otherwise will be
// memory leaks.

#ifndef AABB_TREE_H__
#define AABB_TREE_H__

#include "vector"

#include "../global.h"
#include "../util/string.h"
#include "aabb_node.h"
#include "../Base/Memory/SmartPointer.h"

BEGIN_TEG_NAMESPACE();

class AABBTree {
 public:
  // AABBTree constructor and destructor.
  AABBTree();
  ~AABBTree();

  // Accessor and mutator methods to AABBTree attributes.
  inline const std::vector< SmartPointer<AABBNode> >& roots() const { return roots_; };

  // Methods initialize, build and destroy the AABBTree.
  void Release();
  void Init(const std::vector<Group>& groups);
  void BuildTree(const Group& group, SmartPointer<AABBNode> root, int level);

  // Methods to display the AABBTree, the first render the AABBTree complete
  // and the second render only the nodes that are at some depth.
  void Render() const;
  void Render(int level) const;

  // Methods to load and save to a file the AABBTree.
  bool Load(const std::tstring& path);
  bool Save(const std::tstring& path) const;

  // Methods for statistics, GetWorst() return the maximum number of faces in
  // a node, GetTotal() return the number of faces in the AABBTree, 
  // CountLeaves() return the number of leave nodes in the AABBTree and 
  // GetAverage() return the average of faces by AABBNode.
  int GetWorst() const;
  int GetTotal() const;
  int GetAverage() const;
  int CountLeaves() const;
  int GetWorst(const SmartPointer<AABBNode>& node) const;
  int GetTotal(const SmartPointer<AABBNode>& node) const;
  int CountLeaves(const SmartPointer<AABBNode>& node) const;

 private:
  // AABBTree attribures, maximun number in depth divisions of an AABBNode and
  // the roots for each group of vertex of a geometry.
  const static int kAABBTreeMaxLevel = 10;
  std::vector< SmartPointer<AABBNode> > roots_;
  DISALLOW_COPY_AND_ASSIGN(AABBTree);
};

END_TEG_NAMESPACE();

#endif  // AABB_TREE_H__
