#include "bar2dat.h"

template <int N> void read_bar(string filename, Array<complex<double>,N> &res)
	{
	ifstream fin(filename.c_str());
	if(!fin)
		{
		cerr << "Read error: Unable to read " << filename << "!\n";
		exit(-1);
		}
	fin >> res;
	fin.close();
	}

template <int N> void save_double_bar_to_dat(Array<complex<double>,N> A, string outfilename, char im_real_part)
	{
	ofstream fout;

	int size = A.size();
	int dims = A.dimensions();
	complex<double>* data_ptr = A.data();
	string filename = outfilename + ".dat";
	string par_filename = filename + ".param";

	fout.open(filename.c_str());

	for(int i=0; i<size; i=i+1)
		{
		if(im_real_part == 'r')
			{
			fout << real(data_ptr[i]) << "\t";
			}
		else if (im_real_part == 'i')
			{
			fout << imag(data_ptr[i]) << "\t";
			}
		}
	fout.close();
	cout << "Stored: " << filename << "\n";

	fout.open(par_filename.c_str());
	for(int i=0; i<dims;i++)
		{
		fout << A.extent(i) << "\n";
		}
	fout.close();
	cout << "Stored: " << par_filename << "\n";
	}

template <int N> void save_bar_to_dat(Array<complex<double>,N> A, string outfilename, char isComplex)
	{
	char part = 'r';
	string filename;
	if(isComplex == 'y')
		{
		filename = outfilename + "_real";
		part = 'r';
		save_double_bar_to_dat(A,filename,part);

		filename = outfilename + "_imag";
		part = 'i';
		save_double_bar_to_dat(A,filename,part);
		}
	else if(isComplex == 'n')
		{
		filename = outfilename;
		part = 'r';
		save_double_bar_to_dat(A,filename,part);
		}
	else
		{
		cerr << "Input error: Last input should be y or n!\n";
		exit(-1);
		}
	}



int main(int argc, char** argv)
	{
	string infilename, outfilename, temp;
	int dims = 0;
	char isComplex = '0';
	if (argc == 4)
		{

		infilename = string(argv[1]);
		dims = atoi(argv[2]);
		if( (dims<=0) || (dims > 11))
			{
			cerr << "Input error: Second input should be between 1 and 11 (inclusive)!\n";
			exit(-1);
			}
		temp = string(argv[3]);
		isComplex = temp[0];
		if( (isComplex != 'y') && (isComplex != 'n'))
			{
			cerr << "Input error: Third input should be y or n indicating whether the matrix is complex or not!\n";
			exit(-1);
			}

		if(infilename.find_last_of('/'))
			{
			string indirectory = infilename.substr(0,infilename.find_last_of('/')+1);
			string only_filename = infilename.substr(infilename.find_last_of('/')+1);
			string outdirectory = indirectory + "data_files/";
			my_mkdir(outdirectory);
			outfilename = outdirectory+only_filename.substr(0,only_filename.length()-4);
			}
		else
			{
			string outdirectory = "data_files/";
			my_mkdir(outdirectory);
			outfilename = outdirectory+infilename.substr(0,infilename.length()-4);;
			}


		Array<complex<double>,1> res1;
		Array<complex<double>,2> res2;
		Array<complex<double>,3> res3;
		Array<complex<double>,4> res4;
		Array<complex<double>,5> res5;
		Array<complex<double>,6> res6;
		Array<complex<double>,7> res7;
		Array<complex<double>,8> res8;
		Array<complex<double>,9> res9;
		Array<complex<double>,10> res10;
		Array<complex<double>,11> res11;


		switch (dims)
			{
		case 1:
				{
				read_bar(infilename,res1);
				save_bar_to_dat(res1, outfilename, isComplex);
				break;
				}
		case 2:
				{
				read_bar(infilename,res2);
				save_bar_to_dat(res2, outfilename, isComplex);
				break;
				}
		case 3:
				{
				read_bar(infilename,res3);
				save_bar_to_dat(res3, outfilename, isComplex);
				break;
				}

			}

		}
	else
		{
		cout << "Format: bar2dat <filename.bar> <dimensions> <isComplex (y/n)>\n";
		}

	return (0);
	}


