/*
ImageDatabase
Represents a database of images and an associated
image description
*/

#ifdef _CH_
#pragma package <opencv>
#endif

#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#endif

#ifndef _IMAGE_DATABASE_H
#define _IMAGE_DATABASE_H

#include <vector>
#include "feature.h"

//************************** DEFINES/CONSTANTS *******************************
#define MAX_DATABASE_ENTRIES			(2000)
#define NUM_SUB_IMAGES					(10)
#define INTEGRAL_IMAGE_BINS				(16)
#define ORIENTATION_IMAGE_BINS			(64)
//#define DATABASE_IMAGE_WIDTH			(256)
//#define DATABASE_IMAGE_HEIGHT			(256)
#define eohbins 6

//************************** CLASS DEFINITION ********************************
class CImageDatabase
{
protected:
	int m_nEntries;
	int num_positives;
	int num_negatives;
	int num_features;
	int numSubs;
	int integralBins;
	//CHistogram *arrHistogram;
	IplImage *m_arrImage1[MAX_DATABASE_ENTRIES];

	IplImage *bins[INTEGRAL_IMAGE_BINS];
	IplImage *sels[INTEGRAL_IMAGE_BINS];
	IplImage *subs[NUM_SUB_IMAGES];
	IplImage *selsO[ORIENTATION_IMAGE_BINS];
	IplImage *binsO[ORIENTATION_IMAGE_BINS];
	char *m_arrstrImageName[MAX_DATABASE_ENTRIES];
	char *m_arrstrDescription[MAX_DATABASE_ENTRIES];

public:
	CImageDatabase();
	~CImageDatabase();
	double alpha1;
	int getMin1(int a, int b);
	int getMax1(int a, int b);
	int abs1(int a, int b);
	int getPosAndNeg();
	IplImage *EOHbins[MAX_DATABASE_ENTRIES][eohbins];	//integral images (6 for each image in pos and neg sets) therefore 6 X (n+p)
	int numEOHbins;		//number of EOHbins; we use 6-8;
	int violafeatures;	//number of basic viola features in training procedure
	int edgefeatures;	//number of basic edge features in training procedure
	int redfeatures;	//number of basic edge features in training procedure

	std::vector<IplImage*> positiveIntegrals;		//vector of positive integrals derived from *positives
	std::vector<IplImage*> negativeIntegrals;		//vector of negative integrals derived from *positives
	std::vector<IplImage*> redIntegrals;

	IplImage *positives[MAX_DATABASE_ENTRIES];		//array of positive images
	IplImage *negatives[MAX_DATABASE_ENTRIES];		//array of negative images

	bool load1(const char *pstrFilename);
	bool loadTraining(const char *pstrFilename, int pn);
	bool loadFeatures(const char *pstrFilename,const char *featdesc, const char *edgefeat,
	const char *redfeat, std::vector<feature*>& featureList);

	bool createIntegrals();
	bool createEOHIntegrals();
	bool createRedIntegrals();
	std::vector<IplImage*>& getPositiveIntegrals();
	std::vector<IplImage*>& getNegativeIntegrals();

	void destroy();
	void exit();
	void integralImage(IplImage *pImageToMatch, int index, int subcount);
	void subOrientation(IplImage *pImageToMatch, int index, int subcount);
	double avGrad(double *ar);

	int getNumberOfEntries();
	int getNumberOfSubs();
	IplImage *getImage1(int nImageIndex);			
	char *getImageName(int nImageIndex);
	char *getDescription(int nImageIndex);

	IplImage* CVIntegral(IplImage *pImageToMatch);
	IplImage* EOHIntegral(IplImage *pImageToMatch);

	IplImage* getEOHbin(int i, int j);

private:
	char *allocateString(int nSize);
	char *allocateString(const char *pString);
	void freeString(char *pString);
};

#endif

#ifdef _EiC
main(1,"ImageDatabase.cpp");
#endif