/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#include "domaincomparator.h"
#include "FunctionFactory.h"

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("SuperMatrix.comparator.compare.domaincomparator"));

namespace smartcomparator
{
	namespace compare
	{
		bool DomainComparator::IsSymmetrical() const
		{
			return false;
		}
		DomainComparator::DomainComparator(Matrices::SuperMatrixPtr m, std::string domainFile, std::string label_file, std::string compareFunction) :CompareFunction(m)
		{
			loadDomains(domainFile,label_file,m);
			comparePtr = FunctionFactory::CreateFunction(compareFunction,m);
		}
		double DomainComparator::Compare(size_t n1, size_t n2 )
		{
			if(n1>=domains.size() || n2>=domains.size())
				return -1;
			if(domains[n1].find(n2)==domains[n1].end())
				return 0;
			else return comparePtr->Compare(n1,n2);
		}

		void DomainComparator::loadDomains(std::string domainFilename, std::string labelFileName, Matrices::SuperMatrixPtr m)
		{
			LOG4CXX_INFO(logger,"Loading domains' labels...");
			std::ifstream labelFile(labelFileName.c_str());
			if(!labelFile)
				throw std::runtime_error("Cannot load label file for domains!");
			std::map<std::string,size_t> matLab2ind;
			Matrices::FeatureVectorPtr rowFeatures= m->GetRowFeatures();
			for(size_t i=0;i<rowFeatures->size();i++)
				matLab2ind[(*rowFeatures)[i].GetLabel()]=i;
			std::map<size_t, size_t> domLab2matLab;
			std::string line;
			int counter=0;
			while(std::getline(labelFile,line))
			{
				std::map<std::string,size_t>::iterator find = matLab2ind.find(line);
				if(find==matLab2ind.end())
					throw std::runtime_error("Labels mismatch between domain and base matrix!");

				domLab2matLab[counter]=(find->second);//.second;
				counter++;
			}

			LOG4CXX_INFO(logger,"Loading domains...");
			std::ifstream domainFile(domainFilename.c_str());
			if(!domainFile)
				throw std::runtime_error("Cannot open file with domains!");

			for(size_t i=0;i<domLab2matLab.size();i++)
				domains.push_back(std::set<size_t>());
			//Header
			std::getline(domainFile,line);
			counter=0;
			while(std::getline(domainFile,line))
			{


				std::vector<std::string> domain;
				boost::trim(line);
				boost::split(domain, line, boost::is_any_of(" ") );
				for(size_t j=0;j<domain.size();j++)
					domains[domLab2matLab[counter]].insert(domLab2matLab[atoi(domain[j].c_str())]);
				counter++;

			}
		}

	}
}
