int CountResults(MData& testSet, int *predictions, int *&posSlideCnt, int *&negSlideCnt)
{
	int		result = 0;
	int		*slideIdx = testSet.GetSlideIndices();

	posSlideCnt = (int*)calloc(testSet.GetNumSlides(), sizeof(int));
	negSlideCnt = (int*)calloc(testSet.GetNumSlides(), sizeof(int));

	if( negSlideCnt && posSlideCnt ) {
		for(int i = 0; i < testSet.GetNumObjs(); i++) {
			if( predictions[i] == 1 ) {
				posSlideCnt[slideIdx[i]]++;
			} else {
				negSlideCnt[slideIdx[i]]++;
			}
		}
	}
	return result;
}
int CountTrainingObjs(MData& trainSet, MData& testSet, int *&posCount, int *&negCount)
{
	int result = 0,
		numTrainSlides = trainSet.GetNumSlides(),
		*slideIdx = trainSet.GetSlideIndices(),
		*labels = trainSet.GetLabels();

	posCount = (int*)calloc(numTrainSlides, sizeof(int));
	negCount = (int*)calloc(numTrainSlides, sizeof(int));

	for(int i = 0; i < trainSet.GetNumObjs(); i++) {
		if( labels[i] == 1 ) {
			posCount[slideIdx[i]]++;
		} else {
			negCount[slideIdx[i]]++;
		}
	}
	return result;
}
//  Apply the classifier to each slide in the test set. Save the counts of positive and negative
//	classes for each slide to a csv file.
//
int	ClassifySlides(MData& trainSet, MData& testSet, Classifier *classifier, string testFile,
					string outFileName)
{
	int		result = 0;
	int		*pred = NULL, *posSlideCnt = NULL, *negSlideCnt = NULL;
	char	**slideNames = testSet.GetSlideNames();
	ofstream 	outFile(outFileName.c_str());

	if( classifier == NULL ) {
		result = -10;
	}

	if( result == 0 ) {
		if( outFile.is_open() ) {

			outFile << "slides,";
			for(int i = 0; i < testSet.GetNumSlides() - 1; i++) {
				outFile << slideNames[i] << ",";
			}
			outFile << slideNames[testSet.GetNumSlides() - 1] << endl;

			pred = (int*)malloc(testSet.GetNumObjs() * sizeof(int));
			if( pred == NULL ) {
				cerr << "Unable to allocate results buffer" << endl;
				result = -11;
			}

		} else {
			cerr << "Unable to open " << outFileName << endl;
			result = -12;
		}
	}

	if( result == 0 ) {
		result = TrainClassifier(classifier, trainSet);
	}


	if( result == 0 ) {
		if( !classifier->ClassifyBatch(testSet.GetData(), testSet.GetNumObjs(), testSet.GetDims(), pred) ) {
			cerr << "Classification failed" << endl;
			result = -13;
		}
	}

	if( result == 0 ) {
		result = CountResults(testSet, pred, posSlideCnt, negSlideCnt);
	}

	if( result == 0 ) {
		outFile << "positive,";
		for( int i = 0; i < testSet.GetNumSlides() - 1; i++ ) {
			 outFile <<  posSlideCnt[i] << ",";
		}
		outFile <<  posSlideCnt[testSet.GetNumSlides() - 1] << endl;

		outFile << "negative,";
		for( int i = 0; i < testSet.GetNumSlides() - 1; i++ ) {
			outFile <<  negSlideCnt[i] << ",";
		}
		outFile <<  negSlideCnt[testSet.GetNumSlides() - 1] << endl;
	}

	if( outFile.is_open() ) {
		outFile.close();
	}

	if( posSlideCnt )
		free(posSlideCnt);
	if( negSlideCnt )
		free(negSlideCnt);
	return result;
}