/*
    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 "matrices_all.h"
#include "comparator_all.h"

#include "config.h"

std::vector<std::string> get_keywords(Matrices::CompressedVectorPtr pVector,
				  Matrices::FeatureVectorPtr pFeatures,
				  size_t k = 5);

int main(int ac, char **av)
{
	Matrices::init_logging();

	keywords::config cfg = keywords::config::parse_args(ac,av);

	Matrices::SuperMatrixPtr pMatrix = Matrices::IO::LoadSuperMatrix(cfg.mdir,cfg.mname, true, true);

	smartcomparator::compare::CompareFunctionPtr pCmp =
			smartcomparator::compare::FunctionFactory::CreateFunction(cfg.msr, pMatrix);

	pCmp->WeightMatrix();

	Matrices::FeatureVectorPtr pRowFeatures = pMatrix->GetRowFeatures();
	Matrices::FeatureVectorPtr pColumnFeatures = pMatrix->GetColumnFeatures();

	std::cout << "Keywords:" << std::endl;


	for(size_t row_no = 0; row_no < pMatrix->NumberOfRows(); ++row_no)
	{
		std::string rlabel = (*pRowFeatures)[row_no].GetLabel();
		Matrices::CompressedVectorPtr pVector = pMatrix->GetRow(row_no);
		std::vector<std::string> keywords = get_keywords(pVector, pColumnFeatures, cfg.k);

		std::cout << rlabel << ": ";
		std::copy(keywords.begin(), keywords.end(),
				  std::ostream_iterator<std::string>(std::cout, ", "));
		std::cout << std::endl;
	}

}


std::vector<std::string> get_keywords(Matrices::CompressedVectorPtr pVector,
				  Matrices::FeatureVectorPtr pFeatures, size_t k)
{
	std::map<size_t, double> *id2val = pVector->GetValues();

	std::multimap<double, size_t> val2id;

	for(std::map<size_t, double>::iterator iter = id2val->begin();
		iter != id2val->end(); ++iter)
		val2id.insert( std::make_pair(iter->second, iter->first));

	std::vector<std::string> keywords;
	for(std::multimap<double, size_t>::reverse_iterator riter = val2id.rbegin();
		riter != val2id.rend() && keywords.size() < k; ++riter)
	{
		keywords.push_back( (*pFeatures)[riter->second].GetLabel() );
	}

	return keywords;// not the best way to return vector of strings
}
