#include "lib_cloud.h"

static CloudObjectLib *lib_CloudObject = NULL;

static CloudObjectLib *CheckLib(LONG offset)
{
	return (CloudObjectLib*)CheckLib(LIB_CLOUD, offset, (C4DLibrary**)&lib_CloudObject);
}

#define CloudCall(b)       CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, b)); \
															if (!lib || !lib->b) return; \
															(((iCloudObject*)this)->*lib->b)

#define CloudCallR(a,b)     CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, b)); \
															if (!lib || !lib->b) return a; \
															return (((iCloudObject*)this)->*lib->b)


CloudObject* CloudObject::Alloc()
{
	CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, Alloc));
	if (!lib || !lib->Alloc) return NULL;
	return lib->Alloc();
}

void CloudObject::Free(CloudObject *&pObj)
{
	CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, Free));
	if (!lib || !lib->Free) return;
	lib->Free(pObj);
}

void CloudObject::SetDrawHook(CloudDrawFn fn)
{
	CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, SetDrawHook));
	if (!lib || !lib->SetDrawHook) return;
	lib->SetDrawHook(fn);
}


void CloudObject::GetSize(Vector& vSize)
{
	CloudCall(GetSize1)(vSize);
}

void CloudObject::GetSize(LONG &x, LONG &y, LONG &z)
{
	CloudCall(GetSize2)(x, y, z);
}

UCHAR* CloudObject::GetDensity()
{
	CloudCallR(NULL, GetDensity)();
}

UCHAR* CloudObject::GetToolData()
{
	CloudCallR(NULL, GetToolData)();
}

Bool CloudObject::AllocToolData()
{
	CloudCallR(FALSE, AllocToolData)();
}

void CloudObject::FreeToolData()
{
	CloudCall(FreeToolData)();
}

VLONG CloudObject::GetDensitySize()
{
	CloudCallR(0, GetDensitySize)();
}

Real CloudObject::GetAltitude(BaseObject* pCloudGroup)
{
	CloudCallR(0.0f, GetAltitude)(pCloudGroup);
}

Bool CloudObject::Resize(LONG x, LONG y, LONG z, Bool bResample)
{
	CloudCallR(FALSE, Resize)(x, y, z, bResample);
}

Bool CloudObject::SmoothBorders(Real rDist, Real rVariance, SplineData* pSpline)
{
	CloudCallR(FALSE, SmoothBorders)(rDist, rVariance, pSpline);
}

Bool CloudObject::SmoothAll(Real rStrength, Real rVariance)
{
	CloudCallR(FALSE, SmoothAll)(rStrength, rVariance);
}

void CloudObject::Clear(UCHAR chDensity)
{
	CloudCall(Clear)(chDensity);
}

void CloudObject::FillPlane(Real rRadius, UCHAR chDensity)
{
	CloudCall(FillPlane)(rRadius, chDensity);
}

void CloudObject::FillSphere(Real rRadius, UCHAR chDensity)
{
	CloudCall(FillSphere)(rRadius, chDensity);
}

Bool CloudObject::IsVisible(Bool bEditor, Bool &bDrawBox, BaseObject *&pSkyObject, BaseObject** ppGroup)
{
	CloudCallR(FALSE, IsVisible)(bEditor, bDrawBox, pSkyObject, ppGroup);
}

Bool CloudObject::IsLocked()
{
	CloudCallR(FALSE, IsLocked)();
}

LONG CloudObject::GetPlaneIndex()
{
	CloudCallR(-1, GetPlaneIndex)();
}

void CloudObject::SetPlaneIndex(LONG lPlane)
{
	CloudCall(SetPlaneIndex)(lPlane);
}

LONG CloudObject::GetPlanePosition()
{
	CloudCallR(-1, GetPlanePosition)();
}

void CloudObject::SetPlanePosition(LONG lPos)
{
	CloudCall(SetPlanePosition)(lPos);
}

void CloudObject::Draw(BaseDraw* pBaseDraw, BaseDrawHelp* pDrawHelp, LONG lGrid, Real rQuality, Bool bDrawPlane)
{
	CloudCall(Draw)(pBaseDraw, pDrawHelp, lGrid, rQuality, bDrawPlane);
}

void* CloudObject::GetPrivateData(CloudDataAllocator fnAlloc, ClodDataDeleter fnFree)
{
	CloudCallR(NULL, GetPrivateData)(fnAlloc, fnFree);
}

BaseObject* FindSkyObject(BaseDocument* pDoc)
{
	CloudObjectLib *lib = CheckLib(LIBOFFSET(CloudObjectLib, FindSkyObject));
	if (!lib || !lib->FindSkyObject) return NULL;
	return lib->FindSkyObject(pDoc);
}

