#pragma once

#include "resource.h"
#include "node.h"
#include "scalar.h"
#include "chain.h"

class Entity;
class GaugeEntityList;
class GaugeEntityArray;
class Derivation;
class Point3D;

//#######################################################################
// GaugeEntityList
//#######################################################################
class GaugeEntityList :
	public Node
{
public:
	GaugeEntityList();
	~GaugeEntityList();
	Logical
		TestInstance() const;
	void
		Add(Entity *entity);
	void
		Remove(Entity *entity);
	void
		Clear();
	int
		NumberOfItems();
	int
		CopyEntities(
			GaugeEntityList *destination,
			Derivation *derivation_type = NULL
		);
	int
		CopyEntitiesWithinBounds(
			GaugeEntityList *destination,
			Scalar min_x,
			Scalar min_y,
			Scalar min_z,
			Scalar max_x,
			Scalar max_y,
			Scalar max_z,
			Derivation *derivation_type = NULL
		);
	int
		CopyEntitiesWithinBounds(
			GaugeEntityList *destination,
			Point3D *center,
			Scalar radius,
			Derivation *derivation_type = NULL
		);

	ChainOf<Entity*> * const
		GetInstanceList()
			{
				return &instanceList; 
			}
protected:
	ChainOf<Entity*>
		instanceList;
};

//#######################################################################
// GaugeEntityArray
//#######################################################################
class GaugeEntityArray SIGNATURED
{
public:
	GaugeEntityArray();
	~GaugeEntityArray();
	Logical
		TestInstance() const;
	void
		Add(Entity *entity);
	void
		Remove(Entity *entity);
	void
		Clear();
	void
		PrintStatistics();
	int
		CopyEntities(
			GaugeEntityList *destination,
			Derivation *derivation_type = NULL
		);
	int
		CopyEntitiesWithinBounds(
			GaugeEntityList *destination,
			Scalar min_x,
			Scalar min_y,
			Scalar min_z,
			Scalar max_x,
			Scalar max_y,
			Scalar max_z,
			Derivation *derivation_type = NULL
		);
	int
		CopyEntitiesWithinBounds(
			GaugeEntityList *destination,
			Point3D *center,
			Scalar radius,
			Derivation *derivation_type = NULL
		);
	void
		GetBounds(
			Scalar *min_x,
			Scalar *min_y,
			Scalar *min_z,
			Scalar *max_x,
			Scalar *max_y,
			Scalar *max_z
		);

protected:
	enum
	{
		gaugeMapArraySize=64
	};

	int
		ArrayOffset(Scalar n);

	Scalar
		minimumX,
		minimumY,
		minimumZ,
		maximumX,
		maximumY,
		maximumZ;

	GaugeEntityList
		grid[gaugeMapArraySize][gaugeMapArraySize];
};
