#ifndef DEBOUNDINGVOLUMES_HPP
#define DEBOUNDINGVOLUMES_HPP

#include "deGlobalTypes.hpp"
#include "deScene.hpp"

#define DEBV_API DESCENE_API

/// Base class for general bounding volume implementations
//class IdeBoundingVolume : virtual public IdeRefCountBase
DE3D_INTERFACE(IdeBoundingVolume, IdeRefCountBase)
{
protected:
	virtual ~IdeBoundingVolume() {};

public:
	enum BVType_t
	{
		BVType_Unknown,
		BVType_Sphere,
		BVType_AABB,
		BVType_OBB,
		BVType_Cylinder,
		BVType_Cone,
		BVType_Capsule,
		BVType_Hull,
		BVType_Count,
		BVType_32Bit
	};

	virtual BVType_t GetBVType() = 0;
	virtual void* GetBVInterface(BVType_t iface) = 0;
	virtual deBoolean TestIntersection(IdeBoundingVolume* other) = 0;
	virtual deBoolean TestLineIntersect(const deVec3d& begin, const deVec3d& end) = 0;
	virtual deBoolean TestSphereIntersect(const deVec3d& center, deDouble radius) = 0;
	virtual deBoolean TestAABBIntersect(const deVec3d& pos, const deAABB& box) = 0;

	virtual void GetPosition(deVec3d& pos) = 0;
	virtual void SetPosition(const deVec3d& pos) = 0;
};

/// an abstract bounding sphere implementation
//class IdeBV_Sphere : virtual public IdeBoundingVolume
DE3D_INTERFACE(IdeBV_Sphere, IdeBoundingVolume)
{
protected:
	virtual ~IdeBV_Sphere() {};

public:
	virtual void SetRadius(deDouble Radius) = 0;
	virtual deDouble GetRadius() = 0;
};

/// an abstract axis-aligned bounding box implementation
//class IdeBV_AABB : virtual public IdeBoundingVolume
DE3D_INTERFACE(IdeBV_AABB, IdeBoundingVolume)
{
protected:
	virtual ~IdeBV_AABB() {};
	
public:
	virtual void SetBBox(const deAABB& BBox) = 0;
	virtual void GetBBox(deAABB& BBox) = 0;
};


/// Create a bounding volume of the specified type
DEBV_API IdeBoundingVolume * IdeBoundingVolume_Create(IdeBoundingVolume::BVType_t bvtype);

#endif