/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää and Jaakko Viertola
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.6 $
 *********************************************************************/

#include "SampleUtils.h"

#include <Util.h>

using namespace util::io;
using namespace util;
using namespace std;

namespace prapi
{
	List<Sample<int,ImageSampleIdentifier,int> > SampleUtils::readIdsSampleSet(string sampleSet,List<string>& classes,List<string>& features)
		throw (IOException&)
	{
		ifstream idsSampleSet(sampleSet.c_str());
		if(!idsSampleSet)
			throw IOException("SampleUtils::readIdsSampleSet(string): Can not open file "+sampleSet+".");
	
		// make tmp buffer
		char* tmp = new char[4096];
		string temp;
	
		// first read the first line and deside which kind of sample set is to be read.
		idsSampleSet.getline(tmp,4096);
		string header(tmp);
		//read while the header ends
		while(idsSampleSet.getline(tmp,4096,'\n') && idsSampleSet != NULL)
			{
				temp=tmp;
				if(temp == "TIP_HEADER_DESC_END") break;
			}
	
		// then read the next 3 uninportant lines and the 4:th which is important.
		for(int i=0;i<4;i++)idsSampleSet.getline(tmp,4096,'\n');
		temp=tmp;
		int featureNames = Util::parseInt(temp);

		//then read the feature names
		for(int i=0;i<featureNames;i++)
			{
				idsSampleSet.getline(tmp,4096,'\n');
				temp=tmp;
				features += temp;
			}
		
		// then read the the number of classes
		idsSampleSet.getline(tmp,4096,'\n');
		temp=tmp;
		int numberOfClasses = Util::parseInt(temp);

		//then read the classes
		for(int i=0;i<numberOfClasses;i++)
			{
				idsSampleSet.getline(tmp,4096,'\n');
				temp=tmp;
				classes += temp;
			}
			
		if(header == "TIP_DSAMPLE_SET")
			{
				//then read the nex unidentified info
				idsSampleSet.getline(tmp,4096,'\n');
				temp=tmp;
				int number = Util::parseInt(temp);
				for (int i=0;i<number;i++)idsSampleSet.getline(tmp,4096,'\n');

				// then read four un importan lines and the fifth is important.
				for(int i=0;i<3;i++)idsSampleSet.getline(tmp,4096,'\n');
				temp=tmp;
				
				int numberOfFeatures = Util::parseInt(temp);
				// then read the 9 unimportant lines and the important one.
				for(int i=0;i<10;i++)idsSampleSet.getline(tmp,4096,'\n');
				temp=tmp;
				int numberOfSamples = Util::parseInt(temp);
			
				// make the sample set
				List<Sample<int,ImageSampleIdentifier,int> > sampleSet(numberOfSamples);
			
				//then read the sample data and make the samples.
				string line;
				while(idsSampleSet >> line && idsSampleSet != NULL)
					{
						string name(line);
						List<int> coordinates(4);
						// read the coordinates
						for(int i=0;i<4;i++){idsSampleSet >> line;coordinates += Util::parseInt(line);}
						//read the class info
						idsSampleSet >> line;
						int trueClass=classes.indexOf(line);
						idsSampleSet >> line; // read the second
						idsSampleSet >> line; // and thirth class names
					
						//then read the features.
						List<int> features(numberOfFeatures);
						for(int i=0;i<numberOfFeatures;i++){idsSampleSet >> line;features += Util::parseInt(line);}
					
						//ok now make the Sample
						Sample<int,ImageSampleIdentifier,int> sample(features,trueClass);
					
						//make the identifier
						ImageSampleIdentifier identity(name,coordinates[0],coordinates[1],
																					 coordinates[2]-coordinates[0]+1,coordinates[3]-coordinates[1]+1);
					
						//then set the identifier
						sample.setIdentifier(identity);
					
						sampleSet += sample;
					}
			
				return sampleSet;
			}
	
		else if(header == "TIP_SAMPLE_SET")
			{
				// make the sample set
				List<Sample<int,ImageSampleIdentifier,int> > sampleSet;

				//then read the sample data and make the samples.
				string line;
				while(idsSampleSet >> line && idsSampleSet != NULL)
					{
						string name(line);
						List<int> coordinates(4);
						// read the coordinates
						for(int i=0;i<4;i++){idsSampleSet >> line;coordinates += Util::parseInt(line);}
						//read the class info
						idsSampleSet >> line;
						int trueClass=classes.indexOf(line);
						idsSampleSet >> line; // read the second
						idsSampleSet >> line; // and thirth class names
					
						//then read the features.
						List<int> features(featureNames);
						for(int i=0;i<featureNames;i++){idsSampleSet >> line;features += Util::parseInt(line);}
					
						//ok now make the Sample
						Sample<int,ImageSampleIdentifier,int> sample(features,trueClass);
					
						//make the identifier
						ImageSampleIdentifier identity(name,coordinates[0],coordinates[1],
																					 coordinates[2]-coordinates[0]+1,coordinates[3]-coordinates[1]+1);
					
						//then set the identifier
						sample.setIdentifier(identity);
						//cerr << "coordinates="<<coordinates[0]<<":"<<coordinates[1]<<":"<<coordinates[2]<<":"<<coordinates[3]<<":"<<endl;

						sampleSet += sample;
					}
			
				return sampleSet;
			}
		else throw IOException("SampleUtils::readIdsSampleSet(string): Unsuportes TIP file format.");
	}
}
