/***************************************************************************
 *                           WithPostSynaptic.cpp                          *
 *                           -------------------                           *
 * copyright            : (C) 2013 by Francisco Naveros                    *
 * email                : fnaveros@ugr.es                                  *
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "../../include/learning_rules/BufferedActivityTimes.h"
#include <iostream>
using namespace std;



BufferedActivityTimes::BufferedActivityTimes(int newSize):size(newSize){
	indexData = new int[newSize * 4]();
	times = (double**) new double*[newSize];
	for (int i = 0; i < newSize; i++){
		indexData[i * 4] = 2;
		times[i] = new double[2]();
	}
}

BufferedActivityTimes::~BufferedActivityTimes(){
	for (int i = 0; i < size; i++){
		delete times[i];
	}
	delete times;
	delete indexData;

}

void BufferedActivityTimes::InsertElement(int index, double time, double thresholdTime){
	//check if the old times are under the threshold time.
	if (indexData[index * 4 + 1] > 0){
		int i = indexData[index * 4 + 2];//first position
		int counter = 0;
		while (i != indexData[index * 4 + 3]){
			if (times[index][i] > thresholdTime){
				counter++;
				i++;
				if (i == indexData[index * 4]){
					i = 0;
				}
			}
			else{
				indexData[index * 4 + 3] = i;
				indexData[index * 4 + 1] = counter;
				break;
			}
		}
	}

	//if the vector is full, we double its size.
	if (indexData[index * 4 + 0] == (indexData[index * 4 + 1] + 1)){
		double * aux = times[index];
		times[index] = new double[indexData[index * 4 + 0] * 2];

		int i = indexData[index * 4 + 2];//first position
		int counter = 0;
		while (i != indexData[index * 4 + 3]){
			times[index][counter] = aux[i];
			counter++;
			i++;
			if (i == indexData[index * 4]){
				i = 0;
			}
		}
		indexData[index * 4 + 0] *= 2;
		indexData[index * 4 + 2] = 0;
		indexData[index * 4 + 3] = counter;
		delete aux;		
	}

	//insert the new element
	indexData[index * 4 + 1]++;
	if (indexData[index * 4 + 2] == 0){
		indexData[index * 4 + 2] = indexData[index * 4];
	}
	indexData[index * 4 + 2]--;
	times[index][indexData[index * 4 + 2]] = time;
}


void BufferedActivityTimes::GetTimeElements(int index, double thresholdTime, double * outputTimes){
	//check if the old times are under the threshold time.
	if (indexData[index * 4 + 1] > 0){
		int i = indexData[index * 4 + 2];//first position
		int counter = 0;
		while (i != indexData[index * 4 + 3]){
			if (times[index][i] > thresholdTime){
				outputTimes[counter] = times[index][i];
				counter++;
				i++;
				if (i == indexData[index * 4]){
					i = 0;
				}
			}
			else{
				indexData[index * 4 + 3] = i;
				indexData[index * 4 + 1] = counter;
				break;
			}
		}
	}
}

