#include "Mix/Private/Scene/Common/TerrainNode.h"
#include "Mix/Private/Scene/Common/TerrainMesh.h"

namespace Mix{ namespace Scene{ namespace Common{

TerrainNode::TerrainNode( void ) :
m_pMesh( NULL ),
m_ParentIndex( -1 )
{
}

TerrainNode::~TerrainNode( void )
{
	MIX_RELEASE( m_pMesh );
}

void TerrainNode::SetBounds( const Float32* aabb )
{
	MIX_ASSERT( aabb != NULL );

	m_DefaultBounds.min.x = aabb[0];
	m_DefaultBounds.min.y = aabb[1];
	m_DefaultBounds.min.z = aabb[2];
	m_DefaultBounds.max.x = aabb[3];
	m_DefaultBounds.max.y = aabb[4];
	m_DefaultBounds.max.z = aabb[5];

	m_Bounds = m_DefaultBounds;
	m_Bounds.ComputePoints();
}

void TerrainNode::SetBounds( const Mix::Geometry::AABB& aabb )
{
	m_DefaultBounds = aabb;

	m_Bounds = m_DefaultBounds;
	m_Bounds.ComputePoints();
}

void TerrainNode::UpdateBounds( const Mix::Vector3& worldPos )
{
	m_Bounds.min = m_DefaultBounds.min + worldPos;
	m_Bounds.max = m_DefaultBounds.max + worldPos;
	m_Bounds.ComputePoints();
}

const Mix::Geometry::AABB& TerrainNode::GetBounds( void ) const
{
	return m_Bounds;
}

const Mix::Geometry::AABB& TerrainNode::GetDefaultBounds( void ) const
{
	return m_DefaultBounds;
}

void TerrainNode::SetMesh( Mix::Scene::Common::TerrainMesh* pMesh )
{
	MIX_ASSERT( m_pMesh == NULL );

	MIX_ADD_REF( pMesh );
	m_pMesh = pMesh;
}

Mix::Scene::Common::TerrainMesh* TerrainNode::GetMeshPtr( void ) const
{
	return m_pMesh;
}

void TerrainNode::SetParent( IntT parentIndex, TerrainNode* pParent )
{
	if( pParent == NULL )
	{
		return;
	}

	m_ParentIndex = parentIndex;
	pParent->m_ChildList.push_back( this );
}

IntT TerrainNode::GetParentIndex( void ) const
{
	return m_ParentIndex;
}

void TerrainNode::ReserveChildList( UIntT count )
{
	MIX_ASSERT( m_ChildList.size() == 0 );

	m_ChildList.reserve( count );
}

UIntT TerrainNode::GetChildCount( void ) const
{
	return m_ChildList.size();
}

TerrainNode* TerrainNode::GetChildPtr( UIntT index ) const
{
	MIX_ASSERT( m_ChildList.size() > index );

	return m_ChildList[index];
}

}}}
