/*
    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 "zscores.h"
#include "Options.h"

using namespace Matrices;
using namespace clustering::zscores;

std::vector<int> ReadClutoFile(const std::string & filename)
{
	std::ifstream in_stream(filename.c_str());
	if(!in_stream)
		throw std::runtime_error("Error reading from file " + filename);

	std::vector<int> cluster_ids;
	std::string line;
	size_t row = 0;

	while (getline(in_stream, line, '\n'))
	{
		try
		{
			int space = line.find(" ");
			if (space > -1)
				line = line.substr(0, space);
			int cluster = boost::lexical_cast<int>(line);

			cluster_ids.push_back(cluster);
		}
		catch (boost::bad_lexical_cast)
		{
			throw std::runtime_error("Error in cluto file, line number: " + (row+1));
		}
		row++;
	}
	return cluster_ids;
}

void SaveResults(std::string filename, std::vector<int> & cluster_ids, ZScores & zscores)
{
	std::ofstream out_stream(filename.c_str());
	if(!out_stream)
		throw std::runtime_error("Error writing to file " + filename);

	for (size_t i = 0; i < cluster_ids.size(); ++i)
		out_stream << cluster_ids[i] << " " << zscores.GetInternalZScore(i) << " " << zscores.GetExternalZScore(i) << std::endl;
	out_stream.close();
}

int main(int argc, char **argv)
{
	Options opt(argc, argv);

	Params params = opt.GetParams();

	SuperMatrixPtr matrix = Matrices::IO::LoadSuperMatrix(params.matrix_dir, params.matrix_name, false, true);
	CompareFunctionPtr cmp_fun = FunctionFactory::CreateFunction(params.sim_function, matrix);

	std::vector<int> cluster_ids = ReadClutoFile(params.input_file);

	ZScores z(cluster_ids, cmp_fun);

	SaveResults(params.output_file, cluster_ids, z);

	return 0;
}
