/**************************************************
 *
 VGP463 Computer Graphics Programming: Modeling
 Instructor: Laurie Brown Torelli
 Quadtree Class
 *
 **************************************************/
#ifndef OCT_TREE_ONODE_H
#define OCT_TREE_ONODE_H

#include <stack>
#include <list>
#include <vector>
#include <assert.h>

#include "BoundingBox.h"
#include "Vector.h"

//-----------------------------------------------------------------------------
// quadtree Class
//-----------------------------------------------------------------------------
namespace cbk
{
	template< class Type >
	const bool Octree<Type>::oNode::isInTree(void) const
	{
		return (nodes.size() > 0);
	}

	template< class Type >
	Octree<Type>::oNode::oNode(const Type& data, const Vector& location, const BoundingBox& bounding, const float& scale)
		: borders(location + (bounding.getLesser() * scale), location + (bounding.getGreater() * scale))
	{
		this->data = data;
		this->size = size;
		this->location = location;
		this->scale = scale;
	}

	template< class Type >
	const float& Octree<Type>::oNode::getScale(void) const
	{
		return scale;
	}

	template< class Type >
	typename Octree<Type>::oNode& Octree<Type>::oNode::setScale(const float& scale)
	{
		borders.setBoundaries(location + (((borders.getLesser() - location) / this->scale) * scale), location + (((borders.getGreater() - location) / this->scale) * scale));
		this->scale = scale;
		return *this;
	}

	template< class Type >
	const Vector& Octree<Type>::oNode::getSize(void) const
	{
		return size;
	}

	template< class Type >
	typename Octree<Type>::oNode& Octree<Type>::oNode::setSize(const Vector& size)
	{
		this->size = size;
		return *this;
	}

	template< class Type >
	void Octree<Type>::oNode::Remove(Node* node)
	{
		nodes.remove(node);
	}

	template< class Type >
	const Vector& Octree<Type>::oNode::getLocation(void) const
	{
		return location;
	}

	template< class Type >
	typename Octree<Type>::oNode& Octree<Type>::oNode::setLocation(const Vector& location)
	{
		borders.setBoundaries(location + (((borders.getLesser() - this->location) / this->scale) * scale), location + (((borders.getGreater() - this->location) / this->scale) * scale));
		this->location = location;
		return *this;
	}

	template< class Type >
	const Type& Octree<Type>::oNode::getData(void) const
	{
		return data;
	}

	template< class Type >
	void Octree<Type>::oNode::Remove(void)
	{
		std::list<Node*>::const_iterator& end = nodes.end();
		std::list<Node*>::const_iterator& x = nodes.begin();

		while (x != end)
		{
			(*x)->root->Delete(*x);

			end = nodes.end();
			x = nodes.begin();
		}
	}

	template< class Type >
	void Octree<Type>::oNode::drawNode(IDirect3DDevice9* device) const
	{
		borders.draw(device);
	}
}

#endif //OCT_TREE_ONODE_H
