#include "c4d_memory.h"
#include "c4d_baselist.h"
#include "c4d_nodeplugin.h"

#define BlCall(fnc) (this->*C4DOS.Bl->fnc)

VariableChanged::VariableChanged(void)
{
	old_cnt=new_cnt=0;
	map=NULL;
	safety=TRUE;
}

void GeListHead::Insert(GeListNode *bn, GeListNode *parent, GeListNode *prev) 
{ 
	if (!bn) return;
	
	if (prev)
		bn->InsertAfter(prev);
	else if (parent)
		bn->InsertUnder(parent);
	else
		bn->InsertUnder(this);
}

LayerObject     *BaseList2D::GetLayerObject(BaseDocument *doc)                       { return BlCall(GetLayerObject)(doc); }
Bool             BaseList2D::SetLayerObject(LayerObject *layer)                      { return BlCall(SetLayerObject)(layer); }
const LayerData *BaseList2D::GetLayerData  (BaseDocument *doc,  Bool rawdata)        { return BlCall(GetLayerData  )(doc,rawdata); }
Bool             BaseList2D::SetLayerData  (BaseDocument *doc, const LayerData &data){ return BlCall(SetLayerData  )(doc,data); }


Bool          GeListNode::GetNBit       (LONG bit) const				 { return AtCall(GetNBit       )(bit); }
Bool          GeListNode::ChangeNBit    (LONG bit, LONG bitmode) { return AtCall(ChangeNBit    )(bit,bitmode); }
GeListHead*   BaseList2D::GetCTrackRoot (void)                   { return BlCall(GetCTrackRoot )(); }
CTrack*	      BaseList2D::GetFirstCTrack(void)                   { return BlCall(GetFirstCTrack)(); }
CTrack*	      BaseList2D::FindCTrack    (const DescID &id)       { return BlCall(FindCTrack    )(id); }
const String &BaseList2D::GetTypeName   (void)                   { return BlCall(GetTypeName   )(); }
BaseList2D   *BaseList2D::GetMain       (void) const             { return AtCall(GetMain)(); }
void  	      BaseList2D::InsertTrackSorted(CTrack *track)       {        BlCall(InsertTrackSorted)(track); }

void BaseList2D::ToggleBit(LONG mask)
{
	LONG bitfield = C4DOS.Bl->GetAllBits(this);

	if (bitfield & mask) 
		bitfield = bitfield & ~mask; 
	else 
		bitfield = bitfield | mask; 

	C4DOS.Bl->SetAllBits(this,bitfield);
}

LONG GeListNode::GetInfo(void)
{
	return C4DOS.Bo->GetInfo(this);
}

void GeListNode::SetCustomData(GeListNode *node)
{
	C4DOS.Bl->SetCustomData(this,node);
}

GeListNode*	GeListNode::GetCustomData(void)
{
	return C4DOS.Bl->GetCustomData(this);
}

LONG BaseList2D::GetColor(void) 
{
	return C4DOS.Bl->GetColor(this);	
}

void BaseList2D::SetColor(LONG c)
{
	C4DOS.Bl->SetColor(this,c);	
}

Bool C4DAtom::Read(HyperFile *hf, LONG id, LONG level)
{
	return C4DOS.Bl->Read(this,hf,id,level);
}

Bool C4DAtom::Write(HyperFile *hf)
{
	return C4DOS.Bl->Write(this,hf);
}

Bool C4DAtom::ReadObject(HyperFile *hf, Bool readheader)
{
	return C4DOS.Bl->ReadObject(this,hf,readheader);
}

Bool C4DAtom::WriteObject(HyperFile *hf)
{
	return C4DOS.Bl->WriteObject(this,hf);
}

Bool C4DAtom::GetDescription(Description *description,LONG flags)
{
	return AtCall(GetDescription)(*description,flags);
}

Bool C4DAtom::GetParameter(const DescID &id,GeData &data,LONG flags)
{
	return AtCall(GetParameter)(id,data,flags);
}

Bool C4DAtom::SetParameter(const DescID &id,const GeData &data,LONG flags)
{
	return AtCall(SetParameter)(id,data,flags);
}

Bool C4DAtom::GetEnabling(const DescID &id,GeData &t_data,LONG flags,const BaseContainer *itemdesc)
{
	return AtCall(GetEnabling)(id,t_data,flags,itemdesc);
}

Bool BaseList2D::SetAnimatedParameter(const DescID &id,const GeData &t_data1,const GeData &t_data2,Real mix,LONG flags,CTrack *track)
{
	return AtCall(SetAnimatedParameter)(id,t_data1,t_data2,mix,flags,track);
}

Bool BaseList2D::GetAnimatedParameter(const DescID &id,GeData &t_data1,GeData &t_data2,Real &mix,LONG flags)
{
	return AtCall(GetAnimatedParameter)(id,t_data1,t_data2,mix,flags);
}

DynamicDescription *C4DAtom::GetDynamicDescription()
{
	return AtCall(GetDynamicDescription)();
}

GeListHead *AllocListHead(void)
{
	return C4DOS.Bl->AllocListHead();
}

GeListNode *AllocListNode(LONG id)
{
	return C4DOS.Bl->AllocListNode(0,&id,1);
}

GeListNode *AllocSmallListNode(LONG id)
{
	return C4DOS.Bl->AllocListNode(PLUGINFLAG_SMALLNODE,&id,1);
}

GeListNode *AllocMultiNode(LONG *id_array, LONG id_cnt)
{
	return C4DOS.Bl->AllocListNode(0,id_array,id_cnt);
}

BaseLink *BaseLink::Alloc(void)
{
	return C4DOS.Ln->Alloc();
}

void BaseLink::Free(BaseLink *&link)
{
	if (link) C4DOS.Ln->Free(link);
	link=NULL;
}

AliasTrans *AliasTrans::Alloc(void)
{
	return C4DOS.Ln->TrnAlloc();
}

void AliasTrans::Free(AliasTrans *&trn)
{
	if (trn) C4DOS.Ln->TrnFree(trn);
	trn=NULL;
}

GeListHead *GeListHead::Alloc(void)
{
	return C4DOS.Bl->AllocListHead();
}

void GeListHead::Free(GeListHead *&head)
{
	if (head) C4DOS.Bl->Free(head);
	head=NULL;
}

Bool BaseList2D::Edit(void)
{
	return C4DOS.Bo->Edit(this);
}

void BaseList2D::GetIcon(IconData *dat)
{
	C4DOS.Bo->GetIcon(this,dat);
}

void HandleShaderMessage(GeListNode *node, PluginShader *ps, LONG type, void *data)
{
	C4DOS.Ba->HandleShaderMessage(node,ps,type,data);
}

void HandleInitialChannel(GeListNode *node, LONG id, LONG type, void *data)
{
	if (type!=MSG_INITIALCHANNEL) return;

	BaseList2D *shd = (BaseList2D*)data;
	if (!shd) return;
	
	shd->InsertUnder(node);
	((BaseList2D*)node)->GetDataInstance()->SetLink(id,shd);
}


void BaseList2D::ClearKeyframeSelection()
{
	BlCall(ClearKeyframeSelection)();
}

Bool BaseList2D::FindKeyframeSelection(const DescID &id)
{
	return BlCall(FindKeyframeSelection)(id);
}

Bool BaseList2D::SetKeyframeSelection(const DescID &id,Bool selection)
{
	return BlCall(SetKeyframeSelection)(id,selection);
}

Bool BaseList2D::KeyframeSelectionContent()
{
	return BlCall(KeyframeSelectionContent)();
}
