#include "customgui_matpreview.h"

static CustomGuiMatPreviewLib *lib_MatPreview = NULL;


static CustomGuiMatPreviewLib *CheckLib(LONG offset)
{
	return (CustomGuiMatPreviewLib*)CheckLib(CUSTOMGUI_MATPREVIEW, offset, (C4DLibrary**)&lib_MatPreview);
}

#define MatPreviewCall(b) 			CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
															        if (!lib || !lib->b) return; \
															        (((iMatPreviewData*)this)->*lib->b)

#define MatPreviewCallR(a,b) 		CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
															        if (!lib || !lib->b) return a; \
															        return (((iMatPreviewData*)this)->*lib->b)

#define MatPreviewGuiCall(b) 		CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
															        if (!lib || !lib->b) return; \
															        (((iMatPreviewCustomGui*)this)->*lib->b)

#define MatPreviewGuiCallR(a,b) CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
															      if (!lib || !lib->b) return a; \
															      return (((iMatPreviewCustomGui*)this)->*lib->b)

#define MatPreviewCallFn(b)     CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
                                    if (!lib || !lib->b) return; \
                                    lib->b

#define MatPreviewCallFnR(a, b) CustomGuiMatPreviewLib *lib = CheckLib(LIBOFFSET(CustomGuiMatPreviewLib, b)); \
                                    if (!lib || !lib->b) return a; \
                                    return lib->b

Bool MaterialPreviewData::Init(BaseChannel *pChannel, LONG lCount)
{
  MatPreviewCallR(FALSE, InitChannel)(pChannel, lCount);
}

Bool MaterialPreviewData::Init(PluginShader* pShader, LONG lCount)
{
  MatPreviewCallR(FALSE, InitShader)(pShader, lCount);
}

Bool MaterialPreviewData::Init(BaseMaterial* pMaterial, LONG lCount)
{
  MatPreviewCallR(FALSE, InitMaterial)(pMaterial, lCount);
}

Bool MaterialPreviewData::Init(BaseBitmap* pImage, LONG lCount)
{
  MatPreviewCallR(FALSE, InitBitmap)(pImage, lCount);
}

Bool MaterialPreviewData::Init(RenderPreviewImageCallback fn, void* pUserData, LONG lUserID, LONG lCount)
{
  MatPreviewCallR(FALSE, InitFunction)(fn, pUserData, lUserID, lCount);
}

void MaterialPreviewData::AnimatePreview(Bool bAnimate)
{
  MatPreviewCall(AnimatePreview)(bAnimate);
}

Bool MaterialPreviewData::PreviewIsAnimated()
{
  MatPreviewCallR(FALSE, PreviewIsAnimated)();
}

void MaterialPreviewData::SetPreviewType(MatPreviewType t)
{
  MatPreviewCall(SetPreviewType)(t);
}

MatPreviewType MaterialPreviewData::GetPreviewType()
{
  MatPreviewCallR(MatPreviewFlat2D, GetPreviewType)();
}

void MaterialPreviewData::SetPreviewSize(MatPreviewSize s)
{
  MatPreviewCall(SetPreviewSize)(s);
}

MatPreviewSize MaterialPreviewData::GetPreviewSize()
{
  MatPreviewCallR(MatPreviewSizeDefault, GetPreviewSize)();
}

void MaterialPreviewData::SetObjectMatrix(const Matrix &m)
{
  MatPreviewCall(SetObjectMatrix)(m);
}

Bool MaterialPreviewData::GetObjectMatrix(Matrix &m)
{
  MatPreviewCallR(FALSE, GetObjectMatrix)(m);
}

void MaterialPreviewData::SetUserPreviewSceneName(const String &strName)
{
  MatPreviewCall(SetUserPreviewSceneName)(strName);
}

String MaterialPreviewData::GetUserPreviewSceneName()
{
  MatPreviewCallR(String(), GetUserPreviewSceneName)();
}

void MaterialPreviewData::ClearObjectMatrix()
{
  MatPreviewCall(ClearObjectMatrix)();
}

Real MaterialPreviewData::GetWorldSize()
{
  MatPreviewCallR(1.0, GetWorldSize)();
}

void MaterialPreviewData::SetWorldSize(Real r)
{
  MatPreviewCall(SetWorldSize)(r);
}

Real MaterialPreviewData::GetPreviewStartTime()
{
  MatPreviewCallR(0.0, GetPreviewStartTime)();
}

void MaterialPreviewData::SetPreviewStartTime(Real r)
{
  MatPreviewCall(SetPreviewStartTime)(r);
}

void MaterialPreviewData::GetEnvironment(Vector &col, Real &strength)
{
  MatPreviewCall(GetEnvironment)(col, strength);
}

void MaterialPreviewData::SetEnvironment(const Vector &col, const Real &strength)
{
  MatPreviewCall(SetEnvironment)(col, strength);
}

LONG MaterialPreviewData::GetDirtyCount()
{
  MatPreviewCallR(-1, GetDirtyCount)();
}

Bool MaterialPreviewData::GetRegion(Real &l, Real &t, Real &r, Real &b)
{
	MatPreviewCallR(FALSE, GetRegion)(l, t, r, b);
}

void MaterialPreviewData::SetRegion(Bool bActive, Real l, Real t, Real r, Real b)
{
	MatPreviewCall(SetRegion)(bActive, l, t, r, b);
}

Bool SetDParameterPreview(BaseContainer* pContainer, const GeData* pData, LONG &lFlags, LONG lID)
{
  MatPreviewCallFnR(FALSE, MatPreview_SetDParameterPreview)(pContainer, pData, lFlags, lID);
}

Bool GetDParameterPreview(BaseContainer* pContainer, GeData* pData, LONG &lFlags, LONG lID, LONG lCount, BaseMaterial* pMaterial)
{
  MatPreviewCallFnR(FALSE, MatPreview_GetDParameterPreviewMat)(pContainer, pData, lFlags, lID, lCount, pMaterial);
}

Bool GetDParameterPreview(BaseContainer* pContainer, GeData* pData, LONG &lFlags, LONG lID, LONG lCount, PluginShader* pShader)
{
	MatPreviewCallFnR(FALSE, MatPreview_GetDParameterPreviewShd)(pContainer, pData, lFlags, lID, lCount, pShader);
}

LONG RenderMaterialPreview(const Filename &docpath, BaseMaterial* pMatClone, BaseMaterial* pOrigMat, BaseThread* pThread, BaseBitmap* pDest, BaseDocument *pOriginalDoc, Real rCurrentTime, LONG lFlags)
{
	MatPreviewCallFnR(/*RAY_NOMEM*/1, MatPreview_RenderMaterialPreview)(docpath, pMatClone, pOrigMat, pThread, pDest, pOriginalDoc, rCurrentTime, lFlags);
}

LONG RenderShaderPreview(const Filename &docpath, PluginShader* pShaderClone, PluginShader* pOrigShader, BaseThread* pThread, BaseBitmap* pDest, BaseDocument *pOriginalDoc, Real rCurrentTime, LONG lFlags)
{
	MatPreviewCallFnR(/*RAY_NOMEM*/1, MatPreview_RenderShaderPreview)(docpath, pShaderClone, pOrigShader, pThread, pDest, pOriginalDoc, rCurrentTime, lFlags);
}

BaseContainer GetPreviewScenes(Bool bIncludeFlat2D, Bool bIncludeDefault, LONG lObjectID)
{
  MatPreviewCallFnR(BaseContainer(), MatPreview_GetPreviewScenes)(bIncludeFlat2D, bIncludeDefault, lObjectID);
}

Bool HandlePreviewSceneMessage(LONG lID, MatPreviewType &t, String &strScene)
{
  MatPreviewCallFnR(FALSE, MatPreview_HandlePreviewSceneMessage)(lID, t, strScene);
}

Bool AddUserPreviewScene(const Filename &fn, LONG lID, String* pstrName)
{
  MatPreviewCallFnR(FALSE, MatPreview_AddUserPreviewScene)(fn, lID, pstrName);
}
