/*
    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.
*/

#ifndef SMARTCOMPARATOR_FUNCTIONFACTORY_H
#define SMARTCOMPARATOR_FUNCTIONFACTORY_H
#include "../comparator_stdheaders.h"
#include "../comparator_all.h"
#include "../../matrices/SuperMatrixSplitter.h"

namespace smartcomparator
{
	namespace compare
	{
		typedef std::map<std::string, std::string> STR2STR;

		class FunctionFactory
		{
			public:
				static CompareFunctionPtr SMART_COMPARATOR_API CreateFunction(const std::string &str,
						Matrices::SuperMatrixPtr pMatrix);
				static weights::RankBuilderPtr CreateRankBuilder(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix,
																 size_t &args_count);
				static weights::RankBuilderPtr CreateRankBuilder(const std::string &args, Matrices::SuperMatrixPtr pMatrix, size_t &args_count);
				static std::string CreateRankBuilderString(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix, size_t &args_count);
				static std::string CreateRankBuilderString(const std::string &args, Matrices::SuperMatrixPtr pMatrix, size_t &args_count);
			private:

				//Comparator based on domain
				static CompareFunctionPtr CreateDomainComparator(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				// FileSimFunction
				static CompareFunctionPtr CreateFileSimFunction(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				// RFF
				static CompareFunctionPtr CreateRFF(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				// RWFs:
				static CompareFunctionPtr CreateRWFZScore(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFLinFiltered(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFLin(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFPMI(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFLogLikelihood(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFEvertsMI(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFChi2(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateMCFRWFLin(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);

				static CompareFunctionPtr CreateSHD(const std::string &args, Matrices::SuperMatrixPtr pMatrix);

				// PMI
				static CompareFunctionPtr CreatePMI(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreatePMIQuantified(STR2STR &name2val, Matrices::SuperMatrixPtr pMatrix);
				// Lins
				static CompareFunctionPtr CreateMILin(STR2STR & name2val,const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateMILinCosine(STR2STR & name2val, const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreatePlainSimpleLin(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				// CRM
				static CompareFunctionPtr CreateCRMDMI(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				// simple
				static CompareFunctionPtr CreateCosine(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateEuclidian(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateMinkowski(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateJaccard(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateDice(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateLogEnt(const std::string &args, Matrices::SuperMatrixPtr pMatrix);
				//other
				static CompareFunctionPtr CreateRWFNoWeight(STR2STR & name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateQuantifiedCos(STR2STR & name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateQuantifiedLin(STR2STR & name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateTfIdf(Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFLinEnsemble(STR2STR & name2val, Matrices::SuperMatrixPtr pMatrix);
				static CompareFunctionPtr CreateRWFLinScaled(STR2STR & name2val, Matrices::SuperMatrixPtr pMatrix);


				static void PrepareArgs(const std::string &args, STR2STR & name2val);

				/**
				  * Gets minimal values for RowFrequencyFilter, i.e., minimal values for row:
				  * - "row_mintf" - term frequency
				  * - "row_minTF" - global term frequency
				  * - "row_minnz" - number of non zero cells in a row
				  * All the values are set to 0.
				  */
				static void GetRowFreqFilter(STR2STR &name2val, size_t &row_mintf, size_t &row_minTF, size_t &row_minnz,
											 size_t &args_count);

				static bool GetNoise(STR2STR &name2val, double &noise);
				static bool GetTScoreTreshold(STR2STR &name2val, double &treshold);
				static bool GetTreshold(STR2STR &name2val, double &treshold);
				static bool GetMinCDFP(STR2STR &name2val, double &min_cdf_p);
				static bool GetRz(STR2STR &name2val, double &min_cdf_p);
                                static bool GetPNorm(STR2STR &name2val, double &p_norm);
				static bool GetColMintf(STR2STR &name2val, size_t &min_tf);
				static bool GetRankSize(STR2STR &name2val, size_t &rank_size);
				static bool GetDiscount(STR2STR &name2val, bool &discount);
				static bool GetUniformRank(STR2STR &name2val, bool &uniform_rank);
				static bool GetUseNoiseFilter(STR2STR &name2val, bool &noise_filter);
				static bool GetUseTScoreSelector(STR2STR &name2val, bool &tsc_sel);

				static void GetRowFreqFilter(STR2STR &name2val, std::string &row_mintf, std::string &row_minTF, std::string &row_minnz,
											 size_t &args_count);

				static bool GetNoise(STR2STR &name2val, std::string &noise);
				static bool GetTScoreTreshold(STR2STR &name2val, std::string &treshold);
				static bool GetTreshold(STR2STR &name2val, std::string &treshold);
				static bool GetMinCDFP(STR2STR &name2val, std::string &min_cdf_p);
				static bool GetRz(STR2STR &name2val, std::string &min_cdf_p);
				static bool GetPNorm(STR2STR &name2val, std::string &p_norm);
				static bool GetColMintf(STR2STR &name2val, std::string &min_tf);
				static bool GetRankSize(STR2STR &name2val, std::string &rank_size);
				static bool GetDiscount(STR2STR &name2val, std::string &discount);
				static bool GetUniformRank(STR2STR &name2val, std::string &uniform_rank);
				static bool GetUseNoiseFilter(STR2STR &name2val, std::string &noise_filter);
				static bool GetUseTScoreSelector(STR2STR &name2val, std::string &tsc_sel);

		};
	}//compare
}//smartcomparator

#endif //SMARTCOMPARATOR_FUNCTIONFACTORY_H
