#pragma once

#define OF_ADDON_USING_OFXVECTORMATH
#define OF_ADDON_USING_OFXOPENCV

#include "ofMain.h"
#include "ofAddons.h"

#define CARD_CV_W 64
#define CARD_CV_H 80

//Not really using this at the moment
//but this is a basic representation of a card
class basicCard{
	public:
	void operator = (const basicCard &A){
		memcpy(this, &A, sizeof(basicCard));
	}

	//---------------------------------------------	
	basicCard(){
		reset();
	}

	//---------------------------------------------	
	void reset(){
		id			= -1;
		activity	= 20.0;
	
		pta	= ptb = ptc = ptd = 0;
		cached = false;
		
		angle = 0.0;
		
		for(int i = 0; i < 4; i++)c[i] = 0;
		
		center.x = 0;
		center.y = 0;
		center.z = 0;
	}

	//---------------------------------------------	
	void cache(){
		cached = true;
	}

	//---------------------------------------------	
	void uncache(){
		cached = false;
	}

	//---------------------------------------------
	void setPoints(ofxVec2f pt1, ofxVec2f pt2, ofxVec2f pt3, ofxVec2f pt4){
		c[0] = pt1;
		c[1] = pt2;
		c[2] = pt3;
		c[3] = pt4;
		
		ptsSet = true;
	}	
		
	//corner points
	ofxVec2f c[4];					//the points describing the four corners
	int pta;						//refers to the index of c[4] - once the points are found
	int ptb;						//pta -> ptd should be 0, 1, 2, 3
	int ptc;
	int ptd;
	bool ptsSet;					//have pts been set for this card
	
	//caching and blob tracking
	int id;							//the id of the card for blob tracking
	float activity;					//how much the card/blob is moving
	bool cached;					//are we are cached card?

	//other
	ofxVec2f center;				//the center of the card
	float angle;					//angle of card	
		
};


//this card can have more properties
//images for drawing / comparing etc
class card : public basicCard{

	public:
	//---------------------------------------------
	void operator = (const card &A){
       memcpy(this, &A, sizeof(card));
    }	
	
	//---------------------------------------------	
	void operator = (const basicCard &A){
		for(int i = 0; i < 4; i++)c[i] = A.c[i];
		pta			= A.pta;
		ptb			= A.ptb;
		ptc			= A.ptc;
		ptd			= A.ptd;
		ptsSet		= A.ptsSet;
		cached		= A.cached;
		id			= A.id;
		activity	= A.activity;
		center		= A.center;
		angle		= A.angle;
	}	

	//---------------------------------------------
	card(){
		reset();		
	}

	//---------------------------------------------
	int getSuit(){
		return suit;
	}

	//---------------------------------------------
	int getCard(){
		cardNumber = 1 + (whichCard-1) % 13;
		return cardNumber;
	}
	
	//------------------------------------------------------------------------------------------
	void drawAnalysisResults(int x, int y){
		
		// TODO: make this drawing much better, less hard constants, etc
		
		glPushMatrix();
		glTranslatef(x,y,0);
		
		ofSetColor(20, 20, 160, 190);
		ofRect(-8, -12 +60, 56, 23);
		ofSetColor(0x00FF00);	
		ofDrawBitmapString("pct edge white " + ofToString(pctEdgeDetectionWhite, 4),  - 4,  + 2 + 60);
		
		ofSetColor(20, 20, 160, 190);
		ofRect(-8, -12+90, 56, 23);
		ofSetColor(0x00FF00);	
		ofDrawBitmapString( bFaceCard == true ? "face card" : "number card" ,  - 4,  + 2 + 90);
		
		ofSetColor(20, 20, 160, 190);
		ofRect(-8, -12+105, 56, 23);
		ofSetColor(0x00FF00);	
		ofDrawBitmapString( bRedSuit == true ? "red" : "black" ,  - 4,  + 2 + 105);
		//ofDrawBitmapString( bRedSuit == true ? "red" : "black" ,  - 4,  + 2 + 105);
		
		//ofSetColor(avgColor.x, avgColor.y, avgColor.y);
		//ofRect(0,120,100,100);
		
		glPopMatrix();
		
	}
	
	
	//---------------------------------------------
	void reset(){
		basicCard::reset();
		
		pixelRatio	= 0.0;
		whichCard	= -1;
		suit		= -1;
		cardNumber	= -1;
		hu			= 0.0;
		
		assigned		= false;
		lastAliveTime	= 0;	
		birthTime		= 0;			
		speed			= 0;				
		prevPos			= 0;			
		movementVec		= 0;			
		
		boundingRect.x = 0;
		boundingRect.y = 0;
		boundingRect.width = 0;
		boundingRect.height = 0;
		
		pctWhitePixels = 0;
	}

	//-------------------
	//-------------------
	
	//identification
	int		whichCard;				//which card is this? 0-52
	int		suit;					//which suit? 0-3
	int		cardNumber;				//which card 1-13
	bool	bFaceCard;				//is a face card?
	bool	bRedSuit;				//is red?
	
	//tracking stuff
	bool		assigned;			//whether or not the card has been matched
	long		lastAliveTime;		//when was the last time this card was seen
	long		birthTime;			//when was it born
	float		speed;				//how fast is it moving
	ofxPoint2f	prevPos;			//previous position
	ofxVec2f	movementVec;		//direction it is moving
	
	//pixel stuff
	float		pixelRatio;					//not sure
	float		pctWhitePixels;				//ratio of white to non white pixels
	ofPoint		avgColor;					//avg color of card?
	float		pctEdgeDetectionWhite;		// pct of EDGE pixels that are white, great for face card detection.
	
	//moments
	CvMoments Moments;				//all the moments
	CvHuMoments HuMoments;			//just the hu moments
	int whichCardHu[3];				//not sure
	float diffHu[3];				//not sure
	float hu;						//simple hu comparison
	
	//other
	float	diff;					//not sure
	ofRectangle boundingRect;		//bounding box of card
				
};


class cardImageSet{
	
	public: 
	
	cardImageSet(){
		cardImage.allocate(CARD_CV_W, CARD_CV_H, OF_IMAGE_GRAYSCALE);
		cardImage.allocate(CARD_CV_W, CARD_CV_H, OF_IMAGE_GRAYSCALE);
		cardImage.allocate(CARD_CV_W, CARD_CV_H, OF_IMAGE_GRAYSCALE);
		cardImage.allocate(CARD_CV_W, CARD_CV_H, OF_IMAGE_GRAYSCALE);
	}
	
	
	// I got some images in here too ! 

	ofImage cardImage;
	ofImage cardImageFlipped;
	ofImage thresholdedImage;
	ofImage thresholdedImageFlipped;
	
	
};



