#include "testApp.h"

static bool toggle = false;

//--------------------------------------------------------------
void testApp::setup(){	 
	// VARIOUS APP SETTINGS
	//set background to black
	ofBackground(30, 30, 30);	
	ofSetVerticalSync(true);	
	ofSetWindowTitle("card play");
	ofSetCircleResolution(50);
	
	useVideo  = true;
	threshold = 90;
	blob_min  = 30;
	blob_max  = 3000;
	setPct	  = false;
	videoPct  = 1.0;
	
	GUI.setTitle("cv settings - space to hide");   //<-- set the title of the gui 
	GUI.addToggle("use_video", &useVideo);
	GUI.addSlider("cv_threshold", &threshold, 0, 255);  
	GUI.addSlider("cv_blob_min", &blob_min, 0, 0.2 * 320 * 240); 
	GUI.addSlider("cv_blob_max", &blob_max, 0, 320 * 240);  

	GUI.setAutoSave(true);     // <-- enable auto saving 
	GUI.setFromXML("cv_settings.xml");  //<-- set from xml 
	GUI.setVerbose(true);      //<-- talk to me 
	
	GUI.setGuiPos(660, 90);
	
	//SETUP OUR VIDEO SOURCE
	if(!useVideo){
		videoCV.setupCamera(2, 640, 480);
	}else{
		videoCV.setupVideo("videos/CardsTestforIDsCut.mov");
		GUI.addMovieSlider("video slider", &videoCV.VP);
	}

	//set live time for stored cards to 2.5 seconds
	CT.setup(2500);
	CI.setup();
	CF.setup(videoCV.W, videoCV.H);
	
	GUI.toggleRender();
	
	cardMan.setup("card_bank.xml");	
	whichCard = 1;	
	

	// TODO fix this. 
	for (int i = 0; i < 52; i++){
		videoCV.passInImageToFindCardsIn(cardMan.cardImages[i]);
		videoCV.processFrame(threshold, true);
		vector <ofxCvBlob> goodBlobs = videoCV.findBlobs(blob_min, blob_max);
		numFound = goodBlobs.size();
		
		// find the card
		if( numFound > 0 ){
			cardsFound = CF.findCardsFromBlobs(goodBlobs);
		}
		
		// get some info out of it, and into the CM for card recognition...
		if (cardsFound.size() != 1){
			printf("there is a problem with card %i from the image loading operation \n", i);
		} else {
			//what do we do now??????
			//processCard
			printf("%i : ", i);
			cardMan.newCardBank[i] = cardsFound[0];
			CI.processCard(cardMan.newCardBank[i], cardMan.newCardBankImages[i], videoCV.GreyFrame, videoCV.ImageFrame);	// pass in the image frame...
			// TODO : where do I put this info 
			
		}
		//findCardFromImage(cardMan.newCardBank[i], threshold, blob_min, blob_max, cardMan.cardImages[i]);
	}
	 
	//std::exit(0);
}

//--------------------------------------------------------------
void testApp::update(){
	
		
	if(!useVideo)videoCV.useVideo();	
	else videoCV.useCamera();
	
	//clear the current card vector
	cardsFound.clear();	
	
	//basic processing of the frame
	videoCV.processFrame(threshold);

	//find blobs and trims out obviously bad blobs
	vector <ofxCvBlob> goodBlobs = videoCV.findBlobs(blob_min, blob_max);
	numFound = goodBlobs.size();

	if( numFound > 0 ){
		cardsFound = CF.findCardsFromBlobs(goodBlobs);
		int numCardsFound = cardsFound.size();
		
		//okay here is where we check our blobs to see if they are pre-exisiting 
		//or if they are brand spanking new
		
		if( numCardsFound > 0){

			/* NOTE: the ideal scenario is this 
				
				1. 1st check static cards - cards that match previous cards by a very small value
				2. then check moving cards - cards that are from previous frames but have moved a larger value
				3. then add all remaining cards 
				
				right now we are only doing 1. and 3.
				but 1. is set to accept quite a large tolerance 
				which means that a less close matching card could steel the history of a card that gets checked after
			*/
			
			//begin tracking
			CT.begin();
			for(int i = 0; i < numCardsFound; i++){
		
				//try and match against existing stored cards
				bool cardMatched =  CT.matchTrackedCard(cardsFound[i], 30);	
				
				//check to see if the card deserves to be cached
				//this only applies to matched cards
				bool cardCached = false;
				if( cardMatched ){
					if( cardsFound[i].activity > 0.8)cardsFound[i].uncache();
					else if( cardsFound[i].activity < 0.7)cardsFound[i].cache();
					cardCached = cardsFound[i].cached;
				}
				
				//if the card is brand new or the card is moving too much to be cached
				//then do the computer vision and identification
				if( !cardMatched || !cardCached ){
					
					// zach - I use here a temporary card image set 
					// it'd be good to put this somewhere else, but this will at least mean we have something
					// for recognition. 
					// later this would be good in cardManager, in a fixed preallocated size, etc..
					
					CI.processCard(cardsFound[i], cardImage, videoCV.GreyFrame, videoCV.VideoFrame);
					//cardMan.identifyCardSimple(cardsFound[i], 1);
					cardMan.identifyCardViaPixels(cardsFound[i], cardImage);
				}
				
				//for cards that have not been seen before
				//lets tell our card tracker about them :)
				if(! cardMatched ) CT.addCard(cardsFound[i]);
				
			}
			//end tracking - cards that haven't been seen for a while get killed
			CT.end();
		}
	}
		
}

//--------------------------------------------------------------
void testApp::draw(){
	
	ofSetColor(0x000000);
	ofRect(640,240,320,240);
	
	ofSetColor(0xFFFFFF);	
	videoCV.draw(0,0);
	
	//ghetto hack - passing in the current cards
	cardMan.draw(cardsFound, 0, 0);

	ofSetColor(0xFFFFFF);
	CI.cardAnal.cardImg.draw(videoCV.W, 0);
	CI.cardAnal.thresholdedFrame.draw(videoCV.W + CARD_CV_W, 0);

	ofSetColor(0xFFFFFF);
	string info = "framerate: ";
	info += ofToString(ofGetFrameRate()) + "\n";
	info += "numFound: "+ofToString(numFound) + "\n";
	info += "whichCard: "+ofToString(whichCard) + "\n";
	info += "cardTracker storing "+ofToString( CT.numStoredCards )+" cards";
	
	ofDrawBitmapString(info, 10, 15);
	
	
	
	/*ofSetColor(255, 255, 255);
	for (int i = 0; i < 52; i++){
		if (ofGetFrameNum() % 10 < 5)  cardMan.newCardBankImages[i].thresholdedImage.draw((i%13)*64,(i/13)*80);
		else cardMan.newCardBankImages[i].thresholdedImageFlipped.draw((i%13)*64,(i/13)*80);
	}
	
	for (int i = 0; i < 52; i++){
		int x1 = (i%13)*64;
		int y1 = (i/13)*80;
		int x2 = x1 + CARD_CV_W;
		int y2 = y1 + CARD_CV_H;
		
		if (mouseX > x1 && mouseX < x2){
			if (mouseY > y1 && mouseY < y2){
				cardMan.newCardBank[i].drawAnalysisResults(x1 + 30, y1 + 30);
			}
		}
	}
	*/
	
	// sorry just testing my temporary imageSet out :)
	//CI.cardAnal.cornerAsColorTex.draw(mouseX+20, mouseY+20, 64*4,80*4);
}


//--------------------------------------------------------------
void testApp::keyPressed  (int key){ 
	
	if(key == 's'){
		GUI.saveToXML("cv_settings.xml");   
	}else if(key == 'r'){
		GUI.setFromXML("cv_settings.xml"); 
	}
	
	if(key == ' '){
		GUI.toggleRender();
	}
	
	 else if(key == 'c'){
		videoCV.openCameraSettings();
	 }
}

//--------------------------------------------------------------
void testApp::keyReleased (int key){
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){		
}

//---------------------------------------------------------------
void testApp::mouseDragged( int x, int y, int button){
}

//---------------------------------------------------------------
void testApp::mousePressed( int x, int y, int button ){
}

//---------------------------------------------------------------
void testApp::mouseReleased(){
}


//--------------------------------------------------------------
void testApp::loadSettings(){
}

//--------------------------------------------------------------
void testApp::saveSettings(){
}
