// HandWrittenDigits.h

#ifndef __HANDWRITTENDIGITS_H__
#define __HANDWRITTENDIGITS_H__

#include <iostream>
#include <fstream>
#include<vector>
#include<map>

#include "GrayCode.h"

using namespace std;

typedef unsigned int uint;

class HandWrittenDigits
{
public:
	HandWrittenDigits();
	~HandWrittenDigits();

	void OpenTrainFiles();
	void ReadTrainHeaders();
	bool ReadTrainDigits(uint nSize, map< vector<uint>, vector<uint> >& m);
	void CloseTrainFiles();
	void GetTrainPixelsIndexClass(uint nSize, map< vector<uint>, vector<uint> >& m);

	void OpenTestFiles();
	void ReadTestHeaders();
	bool ReadTestDigits(uint nSize, map< vector<uint>, vector<uint> >& m);
	void CloseTestFiles();
	void GetTestPixelsIndexClass(uint nSize, map< vector<uint>, vector<uint> >& m);

	void AddTrainingSizeToTestIndex(uint nIndexPosition, uint nTrainingSize, map< vector<bool>, vector<uint> >& m);
	void AddTrainingSizeToTestIndex(uint nIndexPosition, uint nTrainingSize, map< vector<uint>, vector<uint> >& m);

	vector<bool> GrayInputs(uint nMin, vector<uint> v);
	map< vector<bool>, vector<uint> > GrayInputs(uint nMin, map< vector<uint>, vector<uint> > m);

	vector<bool> LinearGrayInputs(uint nMaxBase10, vector<uint> v);
	map< vector<bool>, vector<uint> > LinearGrayInputs(uint nMaxBase10, map< vector<uint>, vector<uint> > m);


	map< vector<bool>, vector<uint> > BinaryOutputIndex(uint nIndexPosition, uint nClassPosition, uint nIndex, map< vector<bool>, vector<uint> > m);
	map< vector<bool>, vector<uint> > BinaryOutput(uint nClass, map< vector<bool>, vector<uint> > m);
	map< vector<bool>, vector<uint> > BinaryOutput(uint nClassPosition, uint nClass, map< vector<bool>, vector<uint> > m);
	map< vector<bool>, vector<uint> > FocusClass(uint nClass, map< vector<bool>, vector<uint> > m);

	bool IncrementBitCounts(vector<bool> vGray, vector<uint>& vBitCounts);
	vector<uint> GetBitCounts(uint nBits, map<vector<bool>, vector<uint> > mGray);
	vector<uint> BitCountOrder(vector<uint> vBitCounts);
	//vector<uint> BitCountOrder(uint nBits, map<vector<bool>, vector<uint> > mGray);
	vector<uint> BitCountOrderBase2(uint nBits, map<vector<bool>, vector<uint> > mBase2);
	vector<uint> BitCountOrderGray(uint nBits, map<vector<bool>, vector<uint> > mGray);

	vector<bool> ReReOrder(vector<uint> vOrder, vector<bool> v);
	vector<bool> ReOrderGray(vector<uint> vOrder, vector<bool> vGray);
	vector<bool> ReOrderBase2(vector<uint> vOrder, vector<bool> vBase2);
	map<vector<bool>, vector<uint> > ReOrderBase2(vector<uint> vOrder, map<vector<bool>, vector<uint> > mBase2);
	map<vector<bool>, vector<uint> > ReOrderGray(vector<uint> vOrder, map<vector<bool>, vector<uint> > mGray);

	uint GetFirstOne(vector<bool> v);
	map<vector<bool>, vector<uint> > RemoveLeftZeros(uint& nFirstLeftOne, map<vector<bool>, vector<uint> > m);

	//map<vector<bool>, vector<uint> > GetBitOrderedClassFocusTrainSet(uint nClass, map< vector<uint>, vector<uint> > m);



private:

	uint m_nTotalPixels;

	bool m_bTrainFiles;
	bool m_bTestFiles;

	FILE* m_pTrainImages;
	FILE* m_pTrainLabels;

	FILE* m_pTestImages;
	FILE* m_pTestLabels;

	string m_sTrainImages;
	string m_sTrainLabels;

	string m_sTestLabels;
	string m_sTestImages;

};

#endif // __HANDWRITTENDIGITS_H__


