/*
    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 <fstream>
#include <string>
#include <cstring>
#include <stdexcept>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/detail/classification.hpp>
#include <boost/lexical_cast.hpp>
#include <vector>
#include <set>
#include <map>

void helpMsg(char* av)
{
	std::cout<<"Program creating a ranking matrix from a given similarity matrix\n"
			<<"Runtime format: "<<av<<" matrix_to_rank output_matrix\n";
}

bool comparePairs(std::pair<size_t, double> t1, std::pair<size_t, double> t2)
{
	return t2.second < t1.second;
}

int main(int argc,char** argv)
{
	if(argc == 1 || argc>0 && (strcmp(argv[1],"--help")==0))
	{
		helpMsg(argv[0]);
		return 1;
	}
	if(argc!=3)
	{
		helpMsg(argv[0]);
		throw std::runtime_error("Invalid number of parameters!\n");
		return -1;
	}
	std::string lineBuffer;
	std::vector<std::string> tokens;
	size_t words = 0;

	std::ifstream inFile;
	std::ofstream outFile;

	inFile.open(argv[1]);
	outFile.open(argv[2]);

	if (!inFile.good())
	{
		throw std::runtime_error("Error opening input file\n");
		return -1;
	}
	if (!outFile.good())
	{
		throw std::runtime_error("Error opening input file\n");
		return -1;
	}

	std::getline(inFile, lineBuffer);
	// >> lineBuffer;
	boost::trim(lineBuffer);
	boost::split(tokens, lineBuffer, boost::is_any_of(" "));
	/*std::cout<<"LINE: " <<lineBuffer<<"\n";
    std::cout<<"TOKENS: "<<"\n";
    for (int i=0; i<tokens.size(); i++)
    {
	std::cout<<tokens[i]<<"\n";
    }*/
	assert(tokens.size() > 2);
	words = boost::lexical_cast<size_t>(tokens[0]);
	outFile << words << " " << words << " " << tokens[2] << std::endl;
	bool (*comparePtr) (std::pair<size_t, double>,std::pair<size_t, double>) = comparePairs;
	std::set<
			std::pair<size_t, double>,
			bool(*) (std::pair<size_t, double>, std::pair<size_t, double>)
			> pairs (comparePtr);

	std::set<
			std::pair<size_t, double>,
			bool(*) (std::pair<size_t, double>, std::pair<size_t, double>)
			>::iterator pairsIter;

	std::map<size_t, size_t> id2pos;

	size_t pos;
	double val;
	std::cout << "\n";
	for (size_t i=0; i<words; i++)
	{
		std::cout << "\rProcessing line " << i << " of " << words << std::flush;
		tokens.clear();
		// >> lineBuffer;
		std::getline(inFile,lineBuffer);
		boost::split(tokens, lineBuffer, boost::is_any_of(" "));
		pairs.clear();
		id2pos.clear();
		for (size_t j=0; j<tokens.size() && tokens[j]!=""; j+=2)
		{
			//std::cout<<"j="<<j<<"\n";
			//std::cout<<"CASTING $"<<tokens[j]<<"$\n";
			//std::cout<<"CASTING $"<<tokens[j+1]<<"$\n";
			pos = boost::lexical_cast<size_t>(tokens[j]);
			val = boost::lexical_cast<double>(tokens[j+1]);
			pairs.insert(std::pair<size_t, double> (pos,val));
		}
		pos = words;
		for (pairsIter = pairs.begin(); pairsIter != pairs.end(); pairsIter++)
		{
			id2pos[pairsIter->first] = pos;
			pos--;
		}
		for (size_t j=0; j<words; j++)
		{
			if(id2pos.find(j) != id2pos.end())
			{
				outFile << j << " " << id2pos[j] << " ";
			}
		}
		outFile << "\n";
	}
	std::cout << "\n";
}
