/////////////////////////////////////////////////////////////
// CINEMA 4D SDK                                           //
/////////////////////////////////////////////////////////////
// (c) MAXON Computer GmbH, all rights reserved            //
/////////////////////////////////////////////////////////////

#ifndef __C4DBASECONTAINER_H
#define __C4DBASECONTAINER_H

#ifdef __API_INTERN__
	#include "basecontainer.h"
#else

#include "ge_math.h"
#include "c4d_basetime.h"
#include "c4d_string.h"
#include "c4d_file.h"
#include "c4d_gedata.h"

#ifdef __MAC
	#if defined(__cplusplus) && defined(_MSL_USING_NAMESPACE)
		using namespace std;
	#endif
#elif !defined __PC
	#include <stddef.h>
#endif

class BaseDocument;
class BaseObject;
class BaseMaterial;

class BaseContainer
{
	//#define BcCall(fnc) (this->*C4DOS.Bc->fnc)
	///#define BcCall(fnc, ...) RE_C4DOS.Bc->fnc(this,##__VA_ARGS__) 
	#define BcCall(fnc, ...) C4DOS.Bc->fnc(this,##__VA_ARGS__) 

	private:
		C4D_RESERVE_PRIVATE_TYPE(void*,dummy1);
		C4D_RESERVE_PRIVATE_TYPE(VLONG,dummy2);
		C4D_RESERVE_PRIVATE_TYPE(LONG,dummy3);
		C4D_RESERVE_PRIVATE_TYPE(LONG,dummy4);
		C4D_RESERVE_PRIVATE_TYPE(LONG,dummy5);

public:

		#ifdef	__C4D_NO_NEW_DELETE__
		void* operator new(size_t,const std::nothrow_t&,int line,const CHAR *file) throw();
		void  operator delete(void *del);
		void  operator delete(void *del,int line, const CHAR *file);

		void* operator new(size_t,void *place) { return place; }
		void  operator delete(void*, void*) {}
		#endif

		BaseContainer(void);
		BaseContainer(LONG id);              
		BaseContainer(const BaseContainer &n); 
		~BaseContainer(void);

		const BaseContainer &operator = (const BaseContainer &n);
		BaseContainer *GetClone(COPYFLAGS flags,AliasTrans *trans) const { return BcCall(GetClone, flags,trans); }
		Bool CopyTo(BaseContainer *dst,COPYFLAGS flags,AliasTrans *trans) const { return BcCall(CopyTo, dst,flags,trans); }

		void FlushAll(void) { return BcCall(FlushAll ); }

		LONG GetId() const { return BcCall(GetId ); }
		void SetId(LONG c_id){ BcCall(SetId, c_id); }
		ULONG GetDirty() const { return BcCall(GetDirty ); }

		Bool RemoveData(LONG id) { return BcCall(RemoveData, id); }
		Bool RemoveIndex(LONG i) { return BcCall(RemoveIndex, i); }

		LONG FindIndex(LONG id, GeData **ppData = NULL) const { return BcCall(FindIndex, id,ppData); }
		LONG GetIndexId(LONG index) const { return BcCall(GetIndexId, index); }		
		const GeData* GetDataPointer(LONG id) const { return BcCall(GetDataPointer, id); }
		void GetDataPointers(const LONG* ids, LONG cnt, const GeData** data) const { return BcCall(GetDataPointers, ids, cnt, data); }

		GeData *GetIndexData(LONG index) const { return BcCall(GetIndexData, index); }
		GeData *InsData(LONG id, const GeData &n) { return BcCall(InsData, id,n); }
		GeData *InsDataAfter(LONG id, const GeData &n, GeData *last) { return BcCall(InsDataAfter, id,n,last); }
		GeData *SetData(LONG id, const GeData &n) { return BcCall(SetData, id,n); }
		const GeData &GetData(LONG id) const { return BcCall(GetData, id); }

		Bool operator == (const BaseContainer &d) const;
		Bool operator != (const BaseContainer &d) const;

		Bool 									GetBool			(LONG id, Bool preset=FALSE) const { return BcCall(GetBool, id,preset); }
		LONG									GetLong			(LONG id, LONG preset=0) const { return BcCall(GetLong, id,preset); }
		ULONG									GetULong		(LONG id, ULONG preset=0) const { return BcCall(GetULong, id,preset); }
		LLONG									GetLLong		(LONG id, LLONG preset=0) const { return BcCall(GetLLong, id,preset); }
		LULONG								GetLULong		(LONG id, LULONG preset=0) const { return BcCall(GetLULong, id,preset); }
		Real									GetReal			(LONG id, Real preset=0.0) const { return BcCall(GetReal, id,preset); }
		void*									GetVoid			(LONG id, void *preset=NULL) const { return BcCall(GetVoid, id,preset); }
		Vector								GetVector		(LONG id, const Vector &preset=Vector()) const { return BcCall(GetVector, id,preset); }
		Matrix								GetMatrix		(LONG id, const Matrix &preset=Matrix()) const { return BcCall(GetMatrix, id,preset); }
		String								GetString		(LONG id, const String   &preset=String()) const { return BcCall(GetString, id,preset); }
		Filename							GetFilename	(LONG id, const Filename &preset=Filename()) const { return BcCall(GetFilename, id,preset); }
		BaseTime							GetTime			(LONG id, const BaseTime &preset=BaseTime()) const { return BcCall(GetTime, id,preset); }
		BaseContainer					GetContainer(LONG id) const { return BcCall(GetContainer, id); }
		BaseContainer*				GetContainerInstance(LONG id) const { return BcCall(GetContainerInstance, id); }
		BaseList2D*						GetLink					(LONG id, const BaseDocument *doc, LONG instanceof=0) const { return BcCall(GetLink, id,doc,instanceof); }
		BaseObject*						GetObjectLink		(LONG id, const BaseDocument *doc) const;
		BaseMaterial*					GetMaterialLink	(LONG id, const BaseDocument *doc) const;
		BaseLink*							GetBaseLink (LONG id) const;
		const CustomDataType*	GetCustomDataType	(LONG id,LONG datatype) const;
		
		LONG									GetType(LONG id) const;

		void SetBool				(LONG id, Bool b) { return BcCall(SetBool, id,b); }
		void SetLong				(LONG id, LONG l) { return BcCall(SetLong, id,l); }
		void SetULong				(LONG id, ULONG l) { return BcCall(SetULong, id,l); }
		void SetLLong				(LONG id, LLONG l) { return BcCall(SetLLong, id,l); }
		void SetLULong			(LONG id, LULONG l) { return BcCall(SetLULong, id,l); }
		void SetReal				(LONG id, Real r) { return BcCall(SetReal, id,r); }
		void SetVoid				(LONG id, void *v) { return BcCall(SetVoid, id,v); }
		void SetVector			(LONG id, const Vector &v) { return BcCall(SetVector, id,v); }
		void SetMatrix			(LONG id, const Matrix &m) { return BcCall(SetMatrix, id,m); }
		void SetString			(LONG id, const String &s) { return BcCall(SetString, id,s); }
		void SetFilename		(LONG id, const Filename &f) { return BcCall(SetFilename, id,f); }
		void SetTime				(LONG id, const BaseTime &b) { return BcCall(SetTime, id,b); }
		void SetContainer		(LONG id, const BaseContainer &s) { return BcCall(SetContainer, id,s); }
		void SetLink				(LONG id, C4DAtomGoal *link) { return BcCall(SetLink, id,link); }

		void MergeContainer(const BaseContainer &src);

		Bool GetParameter(const DescID &id, GeData &t_data) const { return BcCall(GetParameter, id,t_data); }
		Bool SetParameter(const DescID &id, const GeData &t_data) { return BcCall(SetParameter, id,t_data); }

		void Sort() { BcCall(Sort ); };
};

#endif

#endif
