#include "cardTracker.h"

//-------------------------------------------
cardTracker::cardTracker(){
}

//-------------------------------------------
cardTracker::~cardTracker(){
	storedCards.clear();
}

//-------------------------------------------
void cardTracker::setup(int timeToLiveMs){
	storedCards.clear();
	
	numStoredCards	= 0;
	genID			= 0;
	lastTime		= 0;
	deathTime		= timeToLiveMs;
	
}

//-------------------------------------------
void cardTracker::resetCounter(){
	genID = 0;
	storedCards.clear();
}

//-------------------------------------------
void cardTracker::begin(){
	for(int j = 0; j < storedCards.size(); j++){
		storedCards[j].assigned = false;
	}
}

//-------------------------------------------
void cardTracker::end(){
	if(storedCards.size() <= 0)return;

	int timeMillis = ofGetElapsedTimeMillis();
	vector <int> eraseList;
	eraseList.clear();

	//we do it in reverse order so when we erase from the list it doesn't mess up the other indexes
	for(int j = storedCards.size()-1; j >= 0; j--){
		if( storedCards[j].assigned )storedCards[j].lastAliveTime = timeMillis;
		else if( timeMillis - storedCards[j].lastAliveTime > deathTime ){
			eraseList.push_back(j);
		}
	}
	
	//now kill the old stored cards
	for(int j = 0; j < eraseList.size(); j++){
		printf("deleting card %i \n", storedCards[j].id);
		storedCards.erase(storedCards.begin() + eraseList[j]);
	}
	
	numStoredCards = storedCards.size();
	if( numStoredCards == 0)resetCounter();
}

//------------------------------------------
int cardTracker::addCard(card & cardIn){
		cardIn.id				= genID;
		cardIn.birthTime		= ofGetElapsedTimeMillis();
		cardIn.lastAliveTime	= cardIn.birthTime;
		cardIn.assigned			= true;	
		cardIn.activity			= 20;
		storedCards.push_back(cardIn);	 			

		genID++;
		return cardIn.id;		
}		

//------------------------------------------
bool cardTracker::matchTrackedCard(card & cardIn, int maxDist, float activityThresh, float cacheRate){
		
		float shortestDistance 	= 99999999;
		int tmpID				= -1;
		int which 				= -1;
		bool found 				= false;
		float speed 			= 0.0;
		ofxVec2f dist;
		ofxVec2f movementVec;				
				
		for(int j = 0; j < storedCards.size(); j++){
			if( storedCards[j].assigned )continue;
				
			dist.set(cardIn.center.x - storedCards[j].center.x, cardIn.center.y - storedCards[j].center.y);
			float len = dist.length();
			
			if(len < maxDist && len < shortestDistance){
				movementVec = dist;
				shortestDistance = len;
				tmpID = storedCards[j].id;	
				found = true;
				which = j;	
				
				//this is 
				if( len > activityThresh ) speed = len;
			}
		}
								
		if(found){
			//if we have found our card 
			//then we fist update the cached card with the new stuff 
			//it needs then we copy the cached card to our current card
			
			//this says we found a card - so that it shouldn't be killed :)
			storedCards[which].assigned = true;		
			
			//we don't want to update the position if it has moved a tiny amount
			if( shortestDistance > 2){
				storedCards[which].movementVec	= movementVec;
				storedCards[which].prevPos		= storedCards[which].center;
				storedCards[which].center		= cardIn.center;
				for(int i = 0; i < 4; i++){
					storedCards[which].c[i] = cardIn.c[i];
				}
			}else{
				storedCards[which].movementVec = 0;
			}	
			
			storedCards[which].activity += speed;
			if(storedCards[which].activity < 0.001){
				storedCards[which].activity = 0.0;
			}
			else{
				//this should be contrable
				//and maybe based on frame rate
				storedCards[which].activity *= cacheRate;
			}
			
			//finally update our passed in card with the cached card
			cardIn = storedCards[which];	
				
			return true;
		}
		
		return false;
}		
