/*
    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"

void helpMsg(char* av)
{
	std::cout<<"Program multiplying 2 matrices in CRS format\n"
			<<"Runtime format: "<<av<<" matrix_1 matrix_2 out_matrix\n";
}

int main(int ac, char** av)
{
	Matrices::init_logging();
	if(ac>0 && (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;
	}
	Matrices::CRSMatrixPtr matrix1 = Matrices::IO::ReadCRSFromSingleFile(std::string(av[1]),"matrix1");
	Matrices::CRSMatrixPtr matrix2 = Matrices::IO::ReadCRSFromSingleFile(std::string(av[2]),"matrix2");
	if(matrix1->NumberOfColumns() != matrix2->NumberOfRows())
		throw std::runtime_error("Cannot multiply matrices, wrong dimensions!\n");

	Matrices::CRSMatrixPtr outputMatrix(new Matrices::CRSMatrix("multiplied_matrix",matrix1->NumberOfRows(),matrix2->NumberOfColumns()));

	std::cout<<"Multiplying matrices...\n";
	int rowCounter=0;
	for(size_t row=0;row<outputMatrix->NumberOfRows();row++,rowCounter++)
	{
		for(size_t col=0;col<outputMatrix->NumberOfColumns();col++)
		{
			double sum=0;
			for(size_t iterator=0;iterator<matrix1->NumberOfColumns();iterator++)
				sum+=matrix1->GetCell(row,iterator)*matrix2->GetCell(iterator,col);
			outputMatrix->SetCell(sum,row,col);
			std::cout<<"Current: "<<row<<" x "<<col<<std::endl;
		}
		if(rowCounter==1000)
		{
			rowCounter=0;
			std::cout<<"Multiplying matrices...row "<<row<<" / "<<outputMatrix->NumberOfRows();
		}
	}
	Matrices::IO::WriteToSingleFile(outputMatrix,av[3]);


}
