/*
    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 <iostream>
#include "matrices_all.h"
#include "comparator_all.h"
#include <boost/filesystem/path.hpp>

void helpMsg(char* av)
{
	std::cout<<"Program computing weight matrix for given similarity function and saving it to a file\n"
			<<"Runtime format: "<<av<<" base_matrix_path similarity_function out_matrix_path\n";
}

void GetIndicesToRemove(std::set<size_t> &indices, Matrices::FeatureVectorPtr features)
{
	for(size_t i = 0; i < features->size(); i++)
		if ( (*features)[i].GetNZ() == 0 )
			indices.insert( i );
}

int main(int ac, char** av)
{
	Matrices::init_logging();
	if( ac > 1 && (strcmp(av[1],"--help") == 0) )
	{
		helpMsg(av[0]);
		return 1;
	}
	if( ac!=4 )
	{
		helpMsg(av[0]);
		throw std::runtime_error("Invalid number of parameters!\n");
		return -1;
	}
	std::string str(av[1]);
	char last_char = str[ str.length() -1 ];
	if(last_char == '\\' || last_char == '/')
		str = str.substr(0, str.length() -1 );
	boost::filesystem::path smPath(str);
	smPath.normalize();
	Matrices::SuperMatrixPtr pMatrix = Matrices::IO::LoadSuperMatrix(smPath.branch_path().string(), smPath.filename().c_str(),true,true);
	try
	{
		smartcomparator::compare::CompareFunctionPtr pCmp =
			smartcomparator::compare::FunctionFactory::CreateFunction(av[2],pMatrix);
		std::cout<<"Transforming matrix...\n";
		pCmp->WeightMatrix();
		pMatrix = pCmp->GetMatrix();
	}
	catch (std::string a)
	{
		std::cout<<"Error: "<<a<<std::endl;
	}

	Matrices::update_features(pMatrix, false);

	std::set<size_t> excluded_rows;
	std::set<size_t> excluded_cols;


	GetIndicesToRemove(excluded_rows, pMatrix->GetRowFeatures());
	GetIndicesToRemove(excluded_cols, pMatrix->GetColumnFeatures());

	std::cout << "Exclude rows size: " << excluded_rows.size() << std::endl;
	std::cout << "Exclude  cols size: " << excluded_cols.size() << std::endl;

	pMatrix = Matrices::FilterSuperMatrix(pMatrix, excluded_rows, excluded_cols, true, true, true, false);

	str = std::string(av[3]);
	last_char = str[ str.length() -1 ];
	if(last_char == '\\' || last_char == '/')
		str = str.substr(0, str.length() -1 );
	boost::filesystem::path outPath(str);
	outPath.normalize();
	pMatrix->SetNewName(outPath.filename().c_str());
	Matrices::IO::WriteSuperMatrix(pMatrix,outPath.branch_path().string());


	return 0;
}
