#ifndef _LIB_CLOUD_H_
#define _LIB_CLOUD_H_

#include "c4d_baseobject.h"
#include "customgui_splinecontrol.h"

#define CLOUD_NODE						1011196 
#define CLOUD_GROUP_NODE			1011194
#define SKY_OBJECT						1011146
#define MSG_SKY_INIALIZED			450000094

#define CLOUD_CELL_SIZE_X   150
#define CLOUD_CELL_SIZE_Y   150
#define CLOUD_CELL_SIZE_Z   150

BaseObject* FindSkyObject(BaseDocument* pDoc);

class CloudObject;

#ifndef __API_INTERN__
typedef Bool (*CloudDrawFn)(BaseObject* op, BaseDraw* pDraw, BaseDrawHelp* pDrawHelp, LONG lGrid, Real rQuality, const Vector &vScale, BaseObject* pSun, Bool bDrawPlane);
typedef void* (*CloudDataAllocator)(BaseObject* pCloud);
typedef void (*ClodDataDeleter)(BaseObject* pCloud, void* &pData);
#endif

class CloudObject : public BaseObject
{
private:
	CloudObject();
	~CloudObject();

public:
	static CloudObject* Alloc();
	static void Free(CloudObject *&pObj);
	static void SetDrawHook(CloudDrawFn fn);

	void GetSize(Vector& vSize);
	void GetSize(LONG &x, LONG &y, LONG &z); // the cloud has (x + 1) * (y + 1) * (z + 1) grid points
	UCHAR* GetDensity();
	UCHAR* GetToolData();
	VLONG GetDensitySize();

	Bool AllocToolData();
	void FreeToolData();

	Real GetAltitude(BaseObject* pCloudGroup);

	Bool Resize(LONG x, LONG y, LONG z, Bool bResample);
	Bool SmoothBorders(Real rDist, Real rVariance, SplineData* pSpline);
	Bool SmoothAll(Real rStrength, Real rVariance);
	void Clear(UCHAR chDensity);
	void FillPlane(Real rRadius, UCHAR chDensity);
	void FillSphere(Real rRadius, UCHAR chDensity);
	Bool IsVisible(Bool bEditor, Bool &bDrawBox, BaseObject *&pSkyObject, BaseObject** ppGroup = NULL);
	Bool IsLocked();
	void Draw(BaseDraw* pBaseDraw, BaseDrawHelp* pDrawHelp, LONG lGrid, Real rQuality, Bool bDrawPlane);

	LONG GetPlaneIndex();
	void SetPlaneIndex(LONG lPlane);
	LONG GetPlanePosition();
	void SetPlanePosition(LONG lPos);

	void* GetPrivateData(CloudDataAllocator fnAlloc, ClodDataDeleter fnFree);
};

#define LIB_CLOUD		450000111
class iCloudObject;

struct CloudObjectLib : public C4DLibrary
{
	CloudObject*	(*Alloc)();
	void					(*Free)(CloudObject *&pObj);
	void					(*SetDrawHook)(CloudDrawFn fn);

	void					(*GetSize1)(iCloudObject *this_ptr, Vector& vSize);
	void					(*GetSize2)(iCloudObject *this_ptr, LONG &x, LONG &y, LONG &z);
	UCHAR*				(*GetDensity)(iCloudObject *this_ptr);
	UCHAR*				(*GetToolData)(iCloudObject *this_ptr);
	Bool					(*AllocToolData)(iCloudObject *this_ptr);
	void					(*FreeToolData)(iCloudObject *this_ptr);
	VLONG					(*GetDensitySize)(iCloudObject *this_ptr);

	Real					(*GetAltitude)(iCloudObject *this_ptr, BaseObject* pCloudGroup);

	Bool					(*Resize)(iCloudObject *this_ptr, LONG x, LONG y, LONG z, Bool bResample);
	Bool					(*SmoothBorders)(iCloudObject *this_ptr, Real rDist, Real rVariance, SplineData* pSpline);
	Bool					(*SmoothAll)(iCloudObject *this_ptr, Real rStrength, Real rVariance);
	void					(*Clear)(iCloudObject *this_ptr, UCHAR chDensity);
	void					(*FillPlane)(iCloudObject *this_ptr, Real rRadius, UCHAR chDensity);
	void					(*FillSphere)(iCloudObject *this_ptr, Real rRadius, UCHAR chDensity);
	Bool					(*IsVisible)(iCloudObject *this_ptr, Bool bEditor, Bool &bDrawBox, BaseObject *&pSkyObject, BaseObject** ppGroup);
	Bool					(*IsLocked)(iCloudObject *this_ptr);
	LONG					(*GetPlaneIndex)(iCloudObject *this_ptr);
	void					(*SetPlaneIndex)(iCloudObject *this_ptr, LONG lPlane);
	LONG					(*GetPlanePosition)(iCloudObject *this_ptr);
	void					(*SetPlanePosition)(iCloudObject *this_ptr, LONG lPos);
	void					(*Draw)(iCloudObject *this_ptr, BaseDraw* pBaseDraw, BaseDrawHelp* pDrawHelp, LONG lGrid, Real rQuality, Bool bDrawPlane);

	BaseObject*		(*FindSkyObject)(BaseDocument* pDoc);
	void*					(*GetPrivateData)(iCloudObject *this_ptr, CloudDataAllocator fnAlloc, ClodDataDeleter fnFree);
};

#endif // _LIB_CLOUD_H_
