/*
    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 "../comparator_stdheaders.h"
#include "BoundaryScaledWeight.h"

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("SuperMatrix.comparator.weights.BoundaryScaledWeight"));

namespace smartcomparator
{
	namespace weights
	{
                BoundaryScaledWeight::BoundaryScaledWeight(Matrices::SuperMatrixPtr pMatrix, WeightFeaturePtr pBaseWeight, double AdjP, double AmISubj, double Coord, double NGen)
			: WeightFeature(pMatrix),
                        AdjP_weight(AdjP), AmISubj_weight(AmISubj),
                        Coord_weight(Coord), NGen_weight(NGen), m_pBaseWeight(pBaseWeight)

		{
                        //std::cout<<"This class is incomplete, for unit testing only!"<<std::endl;
                        std::map<size_t, std::string > boundaries = pMatrix->Boundaries();

			int lastColumnIndex=0;
                        Matrices::FeatureVectorPtr rowFeatures = pMatrix->GetRowFeatures();
                        Matrices::FeatureVectorPtr baseColFeatures = pMatrix->GetColumnFeatures();


                        for(std::map<size_t, std::string >::iterator iterBound=boundaries.begin();iterBound!=boundaries.end();++iterBound)
                        {
				if ((*iterBound).second == "substAdjP_utf")
				{
					AdjP_index = std::pair<size_t,size_t>(lastColumnIndex,(*iterBound).first-1);
				}
				if ((*iterBound).second == "substAmISubj")
				{
					AmISubj_index = std::pair<size_t,size_t>(lastColumnIndex,(*iterBound).first-1);
				}
				if ((*iterBound).second == "substCoord")
				{
					Coord_index = std::pair<size_t,size_t>(lastColumnIndex,(*iterBound).first-1);
				}
				if ((*iterBound).second == "substNGen")
				{
					NGen_index = std::pair<size_t,size_t>(lastColumnIndex,(*iterBound).first-1);
				}
				lastColumnIndex = (*iterBound).first-1;
                        }

		}

		BoundaryScaledWeight::~BoundaryScaledWeight()
		{
			// does nothing
		}

		void BoundaryScaledWeight::Weight(size_t rowindex, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices)
		{
			m_pBaseWeight->Weight(rowindex, v, filteredIndices);
			DoScaling(rowindex, v, filteredIndices);
		}

		void BoundaryScaledWeight::DoScaling(size_t rowindex, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices)
		{
			double value;
			for(std::set<size_t>::iterator iter = filteredIndices.begin(); iter != filteredIndices.end(); ++iter)
			{
                                value = (*v)[*iter] * getWeight(*iter);
				v->SetElement(*iter, value);
			}

		}
		double BoundaryScaledWeight::getWeight(const size_t& colno)
		{
			if (colno >= AdjP_index.first && colno < AdjP_index.second)
				return AdjP_weight;
			if (colno >= AmISubj_index.first && colno < AmISubj_index.second)
				return AmISubj_weight;
			if (colno >= Coord_index.first && colno < Coord_index.second)
				return Coord_weight;
			if (colno >= NGen_index.first && colno <= NGen_index.second)
				return NGen_weight;
			LOG4CXX_WARN(logger,"Warning: column " << colno <<" out of all defined boundaries!");
			LOG4CXX_INFO(logger,"Boundaries are: " << AdjP_index.first <<" " << AdjP_index.second<<" "<<
						 AmISubj_index.first<<" "<<AmISubj_index.second<<" "<<
						 Coord_index.first<<" "<<Coord_index.second<<" "<<
						 NGen_index.first<<" "<<NGen_index.second);
			return 0;
		}
	}
}
