#include "testApp.h"


//--------------------------------------------------------------
void testApp::setup(){


	#ifdef _USE_LIVE_VIDEO
        vidGrabber.setVerbose(true);
        vidGrabber.initGrabber(320,240);
	#else
        vidPlayer.loadMovie("fingers.mov");
        vidPlayer.play();
	#endif
        
    colorImg.allocate(320,240);
	grayImage.allocate(320,240);
	grayBg.allocate(320,240);
	grayDiff.allocate(320,240);
	
	bLearnBakground = true;
	threshold = 30;
	nDilations = 0;
	
	objAImg.allocate(320,240);
	objAIntersection.allocate(320,240);
	objBImg.allocate(320,240);
	objBIntersection.allocate(320,240);
	
	pctAIntersected = 0;
	pctBIntersected = 0;
	
	
}

//--------------------------------------------------------------
void testApp::update(){
	
	ofBackground(255,255,255);
    
	
	
	// lets draw some objects to test into the images:
	
	ofxCvBlob tempBlob;
	tempBlob.pts.push_back(ofPoint(40,40));
	tempBlob.pts.push_back(ofPoint(90,40));
	tempBlob.pts.push_back(ofPoint(90,180));
	tempBlob.pts.push_back(ofPoint(40,180));
	tempBlob.nPts = tempBlob.pts.size();
	objAImg.set(0);
	objAImg.drawBlobIntoMe(tempBlob, 255);

	
	// make a moving circle for B, 
	
	tempBlob.pts.clear();
	for (int i = 0; i < 20; i++){
		
		float radius = 20;
		float centerx = 160 + 40 * sin(ofGetElapsedTimef());
		float centery = 120;
		float x = centerx + radius * cos((float)i/19.0f * (TWO_PI));
		float y = centery + radius * sin((float)i/19.0f * (TWO_PI));
		tempBlob.pts.push_back(ofPoint(x,y));
	}
	tempBlob.nPts = tempBlob.pts.size();
	objBImg.set(0);
	objBImg.drawBlobIntoMe(tempBlob, 255);

    bool bNewFrame = false;
	
	#ifdef _USE_LIVE_VIDEO
       vidGrabber.grabFrame();
	   bNewFrame = vidGrabber.isFrameNew();
    #else
        vidPlayer.idleMovie();
        bNewFrame = vidPlayer.isFrameNew();
	#endif
	
	if (bNewFrame){
		
		#ifdef _USE_LIVE_VIDEO
            colorImg.setFromPixels(vidGrabber.getPixels(), 320,240);
	    #else
            colorImg.setFromPixels(vidPlayer.getPixels(), 320,240);
        #endif
		
        grayImage = colorImg;
		if (bLearnBakground == true){
			grayBg = grayImage;		// the = sign copys the pixels from grayImage into grayBg (operator overloading)
			bLearnBakground = false;
		}
		
		// take the abs value of the difference between background and incoming and then threshold:
		grayDiff.absDiff(grayBg, grayImage);
		grayDiff.threshold(threshold);
		for (int i = 0; i < nDilations; i++){
			grayDiff.erode();
		}
		
		// calc pcts: 
		objAIntersection = objAImg;
		objAIntersection &= grayDiff;		
		objBIntersection = objBImg;
		objBIntersection &= grayDiff;
		
		// this should be checked against 0 white pixels in the obj image...
		pctAIntersected =	(float)objAIntersection.countNonZeroInRegion(0, 0, 320, 240) / 
							(float)objAImg.countNonZeroInRegion(0, 0, 320, 240);
		
		pctBIntersected =	(float)objBIntersection.countNonZeroInRegion(0, 0, 320, 240) / 
							(float)objBImg.countNonZeroInRegion(0, 0, 320, 240);
		
	
		// find contours which are between the size of 20 pixels and 1/3 the w*h pixels.
		// also, find holes is set to true so we will get interior contours as well....
		contourFinder.findContours(grayDiff, 20, (340*240)/3, 10, true);	// find holes
	}

	//printf("%f \n", ofGetFrameRate());
}

//--------------------------------------------------------------
void testApp::draw(){

	// draw the incoming, the grayscale, the bg and the thresholded difference
	ofSetColor(0xffffff);
	grayImage.draw(20,20);
	grayDiff.draw(360,20);
	ofSetColor(0xff0000);
	objAImg.draw(20,280);
	ofSetColor(0x00ff00);
	objBImg.draw(360, 280);
	ofSetColor(0xff0000);
	objAIntersection.draw(20,540);
	ofSetColor(0x00ff00);
	objBIntersection.draw(360,540);
	
	ofSetColor(0, 0, 0);
	ofRect(720,180,300,60);
	ofSetColor(0xff0000);
	ofDrawBitmapString("pct of obj a : " + ofToString(pctAIntersected), 740, 200);
	ofSetColor(0x00ff00);
	ofDrawBitmapString("pct of obj b : " + ofToString(pctBIntersected), 740, 220);
	
}


//--------------------------------------------------------------
void testApp::keyPressed  (int key){ 
	
	switch (key){
		case ' ':
			bLearnBakground = true;
			break;
		case '+':
			threshold ++;
			if (threshold > 255) threshold = 255;
			break;
		case '-':
			threshold --;
			if (threshold < 0) threshold = 0;
			break;
		case 'd':
			nDilations++;
			break;
		case 'D':
			nDilations--;
			if (nDilations < 0) nDilations = 0;
			break;
	}
}

//--------------------------------------------------------------
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(){

}
