#ifndef CGRIDSELECTOR_H_INCLUDE_GUARD
#define CGRIDSELECTOR_H_INCLUDE_GUARD

// Copyright (C) 2013 mocchi

#include "irrlicht.h"
#include "opennurbs.h"
#include "CONObjSceneNode.h"

class CGridSelector : public irr::IReferenceCounted{
	struct Impl;
	friend struct Impl;
	Impl *pimpl;
public:
	struct QueryResult{
		ON_BoundingBox box;
//		irr::core::aabbox3df box;
		irr::core::array<CONObjSceneNode *> sceneNodes;

		// Constructors
		QueryResult(){}
		QueryResult(const QueryResult &other){
			*this = other;
		}
		QueryResult(const ON_BoundingBox &bx_, irr::core::array<CONObjSceneNode *> &sNs_){
			Set(bx_, sNs_);
		}
		QueryResult &operator =(const QueryResult &other){
			Clear();
			Set(other.box, other.sceneNodes);
			return *this;
		}

		void Set(const ON_BoundingBox &bx_, const irr::core::array<CONObjSceneNode *> &sNs_){
			Clear();
			box = bx_;
			sceneNodes = sNs_;

			for (irr::u32 i = 0; i < sceneNodes.size(); ++i){
				sceneNodes[i]->grab();
			}
		}

		// Destructors
		~QueryResult(){
			Clear();
		}
		void Clear(){
			for (irr::u32 i = 0; i < sceneNodes.size(); ++i){
				sceneNodes[i]->drop();
			}
			sceneNodes.clear();
		}
	};

	CGridSelector();
	void Initialize(irr::f32 unitSize, ON_BoundingBox &bb);
	void Initialize(irr::f32 unitSize, irr::core::aabbox3df &bb);

	virtual ~CGridSelector();

	void growGrid(ON_BoundingBox &bb);

	void getBoundingBox(ON_BoundingBox &bb);

	bool addVertices(CONObjSceneNode *sn, irr::core::vector3df *vertices, irr::u32 num);
	bool addVertices(CONObjSceneNode *sn, irr::video::S3DVertex *vertices, irr::u32 num);
	bool addTriangles(CONObjSceneNode *sn, irr::u32 *indices, irr::video::S3DVertex *vertices, irr::u32 numIndices);

	bool getGridMesh(ON_Mesh &mesh);

	void queryBoxFromThickRay(
		const irr::core::line3df &ray,
		irr::f32 thickness,
		bool rough,
		irr::core::array<QueryResult> &results
	);
};

#endif // CGRIDSELECTOR_H_INCLUDE_GUARD
