#include "batchProcessor.h"
#include "HausdorffImageSimplify.h"
#include "HausdorffImageMatch.h"
#include <omp.h>
batchProcessor::batchProcessor(void)
{
	width = 512;
	height = 512;
}

batchProcessor::~batchProcessor(void)
{
}

vector<string> batchProcessor::getFileNamesFromLabelObj(vector<int>labelobjs)
{
	vector<string> imageNames;
	int numofeach = 60;
	if(labelobjs.size()!=0)
	{
		for(int ii=0;ii<labelobjs.size();ii++)
		{
			int i = labelobjs[ii];
			char objname[255];
			itoa(i,objname,10);

			for(int j=0;j<numofeach;j++)
			{
				int jid = j*360/numofeach;
				char jbuf[255];
				itoa(jid,jbuf,10);
				string name(objname);
				name.append(".");
				name.append(jbuf);
				name.append(".bmp");
				imageNames.push_back(name);
			}
		}
	}	
	return imageNames;
}
vector<vector<HausdorffNode>>  batchProcessor::batchLoadNodes(string path,vector<int>labelobj)
{
	HausdorffImageSimplify* simplifer = new HausdorffImageSimplify;
	vector<string> imageNames;
	if(labelobj.size()!=0)		
		imageNames = getFileNamesFromLabelObj(labelobj);
	else
		imageNames = getFileNames(path.c_str());
	vector<vector<HausdorffNode>> allImgNodes;
	for(int ii=0;ii<imageNames.size();ii++)	
	{
		string filename(path);
		filename.append("nodes/");
		filename.append(imageNames[ii].substr(0,imageNames[ii].size()-4));
		filename.append(".txt");
		vector<HausdorffNode> nodes = simplifer->loadNodeInfo(filename);
		allImgNodes.push_back(nodes);
	}	
	delete simplifer;

	return allImgNodes;
}
vector<vector<HausdorffNode>>  batchProcessor::imageSimplify(string path,int numseg,bool bmerge,bool saveinfo)
{
	HausdorffImageSimplify* simplifer = new HausdorffImageSimplify;
	vector<string> imageNames = getFileNames(path.c_str());
	
	vector<vector<HausdorffNode>> allImgNodes;
	for(int ii=0;ii<imageNames.size();ii++)	
	//int ii=1;
	{
		//cout<<"id is "<<ii<<endl;
		string filename(path);
		filename.append(imageNames[ii]);
		simplifer->run(filename,numseg,bmerge);
		if(saveinfo)
		{		
			simplifer->saveNodeInfo();	
			simplifer->saveSegmentImg();
		}
		allImgNodes.push_back(simplifer->getNodes());
	}	
	delete simplifer;
	
	return allImgNodes;
}










void batchProcessor::batchRetrieval(string testpath,string labelpath,vector<int> labelobjs)
{
	//omp_set_num_threads(3);
	vector<vector<HausdorffNode>> testImgRegons = batchLoadNodes(testpath);
	vector<vector<HausdorffNode>> labeledImgRegions = batchLoadNodes(labelpath,labelobjs);

	vector<string> labeledImg;
	if(labelobjs.size()==0)
		labeledImg = getFileNames(labelpath.c_str());
	else
		labeledImg = getFileNamesFromLabelObj(labelobjs);

	cout<<"finish loading"<<endl;
	vector<string> testedImg = getFileNames(testpath.c_str());


	HausdorffImageMatch *matcher = new HausdorffImageMatch;

	vector<pair<int,float>> matchparis;
	//#pragma omp parallel for
	for(int i=0;i<testImgRegons.size();i++)
	//int i=288;
	{
		float mincost = FLT_MAX;
		int mindex = -1;
		vector<pair<int,float>> imatchparis;
		cout<<testedImg[i]<<'\t'<<testImgRegons[0].size()<<endl;
		for(int j=0;j<labeledImgRegions.size();j++)
		//int j=243;
		//cout<<labeledImg[j]<<endl;
		{
			if(labeledImg[j]==testedImg[i])
				continue;
			float cost = 0;
			vector<pair<int,int>> pairs = matcher->run(testImgRegons[i],labeledImgRegions[j],cost);
			imatchparis.push_back(pair<int,float>(j,cost));
			cout<<cost<<endl;
			for(int ii=pairs.size()-1;ii>=0;ii--)			
				printf("%d --> %d\n",pairs[ii].first,pairs[ii].second);		

		}
		//return;

		sortPairwithIndex(imatchparis);

		string logname(testpath);
		logname.append("/matched/");
		if(!fileExists(logname))
			_mkdir(logname.c_str());
		logname.append(testedImg[i].substr(0,testedImg[i].size()-4));
		logname.append(".txt");
		ofstream outlog(logname.c_str());		
		int outpair = 20;
		if(imatchparis.size()<outpair)
			outpair = imatchparis.size();
		for(int ii=0;ii<outpair;ii++)
		{
			int exist = 0;
			for(int kk=0;kk<testedImg.size();kk++)
			{
				if(testedImg[kk]==labeledImg[imatchparis[ii].first])
				{
					exist=1;
					break;
				}
			}
			outlog<<labeledImg[imatchparis[ii].first].c_str()<<'\t'<<exist<<'\t'<<imatchparis[ii].second<<endl;		
		}
		outlog.close();

		matchparis.push_back(imatchparis[0]);

	}

	vector<int> pindex = sortPairwithIndex(matchparis);

	string logname(testpath);
	logname.append("/matched/");
	if(!fileExists(logname))
		_mkdir(logname.c_str());
	logname.append("matched.txt");

	ofstream outlog(logname.c_str());
	for(int ii=0;ii<matchparis.size();ii++)
	{
		int i = pindex[ii];
		outlog<<testedImg[i]<<" "<<"\t"<<labeledImg[matchparis[ii].first]<<"\t"<<matchparis[ii].second<<endl;
	}
	outlog.close();
	delete matcher;
}

vector<string> batchProcessor::readMatchedFile(string file)
{
	ifstream matchedin(file.c_str());

	vector<string>  matches;;
	string nodeinfo;
	

	while(!matchedin.eof()){

		//read data from file
		string testImg, labeledImg;
		std::getline(matchedin,nodeinfo);
		if(nodeinfo.size()<1)
			break;
		std::istringstream(nodeinfo,ios_base::in) >> labeledImg;
		char tmpsrc[255];
		char tmpdst[255];
		sscanf(nodeinfo.c_str(),"%[^\t\n] %s",tmpsrc,tmpdst);

		
		matches.push_back((tmpsrc));
	}
	matchedin.close();
	return matches;
}










