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

#include "TimeManagement.h"

#include "../../Scene Parser/SceneFile.h"
#include "../../Scene Parser/DataTypes/DataInt.h"

BEGIN_TEG_NAMESPACE();

/*
// Constructor
TimeManagement::TimeManagement() {

}

// Destructor
TimeManagement::~TimeManagement() {

}

// Method to update the time
void TimeManagement::update() {
	// Obtain the actual time
	const clock_t tmp = clock();
	
	last = current;
	current = tmp;


	// 
	const int nTimers  = static_cast<int> (timers.size());
	for (int i = 0; i < nTimers; ++i) {
		if (!timers[i].isRunning) continue;

		// Execute the final task
		// Stop the timer
		// TODO: el tiempo final deberia ser en base a a cuando inicio
		//       el time y no la aplicacion
		if (tmp >= timers[i].end && timers[i].end > 0) {
			timers[i].isRunning = false;
			timers[i].funcEnd->call();
		}

		// Check if pass an interval to do the task
		// Update the last time obtained
		// Execute the task
		if ((tmp - timers[i].last) > timers[i].interval) {
			timers[i].last = tmp;
			timers[i].funcInterval->call();
		}
	}
}
*/

//// Prueba
/*
DataTime::DataTime(const std::vector<SmartPointer<DATA> >& params)
	: DATA(DATA_TIME) {
	// 
	const SmartPointer<Data<int>> interval_ = castToInt(params[0]);
	const SmartPointer<Data<int>> duration_ = castToInt(params[1]);
	
	last = clock();
	interval = interval_->value;
	end = duration_->value;
	if(end != -1) end += last;
	isRunning = true;

	// Por ahora voy asumir que las funciones que se llaman son sin parametros
	funcInterval = castToDataCallFunction(params[2]);
	funcEnd = castToDataCallFunction(params[3]);
}

DataTime::~DataTime() {
	funcInterval = NULL;
	funcEnd = NULL;
}
*/

// Constructor
TimeManagement::TimeManagement() {

}

// Destructor
TimeManagement::~TimeManagement() {

}

// Method to update the time
void TimeManagement::update() {
	// Obtain the actual time
	const clock_t tmp = clock();
	
	last = current;
	current = tmp;

	// 
	const int nTimers  = static_cast<int> (timers.size());
	for (int i = 0; i < nTimers; ++i) {
		if (!timers[i]->isRunning) continue;

		// Execute the final task
		// Stop the timer
		// TODO: el tiempo final deberia ser en base a a cuando inicio
		//       el time y no la aplicacion
		//if (timers[i]->end != -1 && tmp >= timers[i]->end && timers[i]->end > 0) {
		//if (timers[i]->end != -1 && tmp >= timers[i]->end) {
		if (timers[i]->end != -1 && tmp >= timers[i]->end + timers[i]->begin) {
			timers[i]->isRunning = false;
			//timers[i]->funcEnd->call();
			timers[i]->funcEnd->resolve(std::map<std::string, SmartPointer<IData>>());
		}

		// Check if pass an interval to do the task
		// Update the last time obtained
		// Execute the task
		if ((tmp - timers[i]->last) > timers[i]->interval) {
			timers[i]->last = tmp;
			//timers[i].funcInterval->call();
			timers[i]->funcInterval->resolve(std::map<std::string, SmartPointer<IData>>());
		}
	}

	// TODO: borrar los timers que ya terminaron...
	if (tmp - lastCallGarbageCollector > garbageCollectorInterval) {
	  lastCallGarbageCollector = tmp;
	  COLLECT_GARBAGE();
	}
}

// ..
void TimeManagement::release() {
	timers.clear();
}

// Method to stop all the tiemers.
void TimeManagement::stopAllTimers(void) {
	const int nTimers = static_cast<int> (timers.size());
	for (int i = 0; i < nTimers; ++i) timers[i]->stop();
}

// Method to pause all the timers.
void TimeManagement::pauseAllTimers(void) {
	const int nTimers = static_cast<int> (timers.size());
	for (int i = 0; i < nTimers; ++i) timers[i]->pause();
}

// Method to start allt the timers.
void TimeManagement::startAllTimers(void) {
	const int nTimers = static_cast<int> (timers.size());
	for (int i = 0; i < nTimers; ++i) timers[i]->start();
}

END_TEG_NAMESPACE();
