// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)

#include "MMObject.h"
#include "../LogManagement.h"

BEGIN_TEG_NAMESPACE();

// a 'static initialiser' is needed in one of the source
// files to give the std::list a definitive presence
std::list<IMMObject *> IMMObject::liveObjects;
std::list<IMMObject *> IMMObject::deadObjects;

// define a quick macro to make things easier on derived classes
//#define AUTO_SIZE unsigned long size(){return sizeof(*this);}

// 
IMMObject::IMMObject() : refCount(0) {
	// 
	liveObjects.push_back(this);
}

// 
IMMObject::~IMMObject() {
	// Add an empty virtual destructor to make sure that
	// the destructors in derived classes work properly.
}

// 
void IMMObject::AddRef() {
	++refCount;
}

// 
void IMMObject::Release() {
	// 
	--refCount;

	// 
	if (refCount <= 0) {
		liveObjects.remove(this);
		deadObjects.push_back(this);
	}
}

int IMMObject::getRefCount(void) {
  return refCount;
}

// 
void IMMObject::CollectGarbage() {
	// 
	std::list<IMMObject *>::iterator it = deadObjects.begin();
	std::list<IMMObject *>::iterator end = deadObjects.end();

	// 
	for (; it != end; ++it) delete (*it);

	// 
	deadObjects.clear();
}

// 
void IMMObject::CollectRemainingObjects() {
	// 
	CollectGarbage();

	// 
	std::list<IMMObject*>::iterator it = liveObjects.begin();
	const std::list<IMMObject*>::iterator end = liveObjects.end();

	if (it != end) PRINT_LOG(TYPE_WARNING, "Warning: Leak memory ...(TODO) \n");

	// 
	for (; it != end; ++it) {
		// 
		IMMObject *o = (*it);
		
		//PRINT_LOG(TYPE_WARNING, "Warning: Leak memory ...(TODO) \n");

		// 
		delete o;
	}

	// 
	liveObjects.clear();
}

END_TEG_NAMESPACE();
