#include "DataMemoryManagement.h"
#include "../Base/LogManagement.h"

BEGIN_TEG_NAMESPACE();

// DataMemoryManagement constructor.
DataMemoryManagement::DataMemoryManagement() {
#ifdef _DEBUG
  numNewf = numNewi = numNewb = 0;
#endif 
}

// DataMemoryManagement destructor.
DataMemoryManagement::~DataMemoryManagement() { }

// Method to initialize the array with the precreated values
void DataMemoryManagement::init(void) { }

// Metho to free 
void DataMemoryManagement::release(void) {
  buffer.clear();

#ifdef _DEBUG
  PRINT_LOG(TYPE_EVENT, "Number of new float(%d), int(%d), bool(%d)", numNewf, numNewi, numNewb);
#endif 
}

int DataMemoryManagement::getNextFreePosition(const int& type) const {
  const int nBuffer = static_cast<int> (buffer.size());
  for (int i = 0; i < nBuffer; ++i)
    if (buffer[i]->type == type && buffer[i]->getRefCount() == 1)
      return i;
  return -1;
}

// Method to get DataFloat memory.
SmartPointer<DataFloat> DataMemoryManagement::newDataFloat(const float& t)  {
  const int nextFree = getNextFreePosition(IData::DATA_FLOAT);
  if (nextFree != -1) {
    SmartPointer<DataFloat> tmp = castToFloat(buffer[nextFree]);
	tmp->value = t;
	return tmp;
  }

#ifdef _DEBUG
  numNewf++;
#endif 

  const int nBuffer = static_cast<int> (buffer.size());
  const SmartPointer<DataFloat> tmp = new DataFloat(t);
  if (nBuffer < MAX_DATA_ARRAY_SIZE) buffer.push_back(castToDATA(tmp));
  return tmp;
}

// Method to get DataInt memory.
SmartPointer<DataInt> DataMemoryManagement::newDataInt(const int& t)  {
  const int nextFree = getNextFreePosition(IData::DATA_INT);
  if (nextFree != -1) {
    SmartPointer<DataInt> tmp = castToInt(buffer[nextFree]);
	tmp->value = t;
	return tmp;
  }

#ifdef _DEBUG
  numNewi++;
#endif 

  const int nBuffer = static_cast<int> (buffer.size());
  const SmartPointer<DataInt> tmp = new DataInt(t);
  if (nBuffer < MAX_DATA_ARRAY_SIZE) buffer.push_back(castToDATA(tmp));
  return tmp;
}

// Method to get DataInt memory.
SmartPointer<DataBool> DataMemoryManagement::newDataBool(const bool& t)  {
  const int nextFree = getNextFreePosition(IData::DATA_BOOL);
  if (nextFree != -1) {
    SmartPointer<DataBool> tmp = castToBool(buffer[nextFree]);
	tmp->value = t;
	return tmp;
  }

#ifdef _DEBUG
  numNewb++;
#endif 

  const int nBuffer = static_cast<int> (buffer.size());
  const SmartPointer<DataBool> tmp = new DataBool(t);
  if (nBuffer < MAX_DATA_ARRAY_SIZE) buffer.push_back(castToDATA(tmp));
  return tmp;
}

END_TEG_NAMESPACE();
