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

#pragma once
#include "../comparator_stdheaders.h"
#include "../filters/FilterFeature.h"
#include "../selectors/Selector.h"
#include "../selectors/RowRelativeSelector.h"
#include "../simfunctions/SimilarityFunction.h"
#include "../weights/WeightFeature.h"
#include "../transformations/GenericTransformer.h"

namespace smartcomparator
{
	namespace compare
	{

		class SMART_COMPARATOR_API CompareFunction
		{
		public:
			CompareFunction(Matrices::SuperMatrixPtr matrix,
							filters::FilterFeaturePtr filter = filters::FilterFeaturePtr(),
							selectors::SelectorPtr selector = selectors::SelectorPtr(),
							weights::WeightFeaturePtr weight = weights::WeightFeaturePtr(),
							simfunctions::SimilarityFunctionPtr simfun = simfunctions::SimilarityFunctionPtr(),
							selectors::RowRelativeSelectorPtr relativeSelector = selectors::RowRelativeSelectorPtr(),
							transformations::TransformationPtr transformation = transformations::TransformationPtr());
			virtual ~CompareFunction(void);

			virtual double Compare(size_t n1, size_t n2 );
			virtual double Compare(const std::string &w1, const std::string &w2);
			double ExternalCompare(size_t n1, Matrices::CompressedVectorPtr extVector);
			double ExternalCompare(std::string w1, Matrices::CompressedVectorPtr extVector);

			virtual double MinValue() const ;

			Matrices::SuperMatrixPtr  GetMatrix();

			bool IsTransformingMatrix() const;

			weights::WeightFeaturePtr GetWeightFeature();

			/**
			  * Returns true if cmp(a,b) = cmp(b,a); default is taken from similarity function used;
			  */
			virtual bool IsSymmetrical() const;
			void WeightMatrixCopy();
			void WeightMatrix();



		protected:
			double StandardCompare(size_t n1, size_t n2);
			double PreWeightCompare(size_t n1, size_t n2);
			void TransformRow(size_t row_index, Matrices::SuperMatrixPtr sourceMatrix = Matrices::SuperMatrixPtr());
			Matrices::SuperMatrixPtr m_pMatrix;
			filters::FilterFeaturePtr m_pFilter;
			selectors::SelectorPtr m_pSelector;
			weights::WeightFeaturePtr m_pWeight;
			simfunctions::SimilarityFunctionPtr m_pSimfun;
			selectors::RowRelativeSelectorPtr m_pRelativeSelector;
			transformations::TransformationPtr m_pTransform;
			bool m_bTransformed;

		};

		typedef boost::shared_ptr<CompareFunction> CompareFunctionPtr;
	}
}










