/**
 * 
 * Written by Márton Münz and Philip C Biggin
 * Copyright (c) University of Oxford, United Kingdom
 * Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
 * 
 * This source code file is part of JGromacs v1.0.
 * 
 * JGromacs v1.0 is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JGromacs v1.0. 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
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JGromacs v1.0. If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package jgromacs.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import jama.Matrix;

/**
 * This class contains static methods for IO of ArrayList and Matrix objects
 *
 */
public class IOMath {

	// Input
	
	/**
	 * Reads ArrayList from the given file
	 * @param filename file name
	 * @return file content as an ArrayList
	 * @throws IOException 
	 */
	public static ArrayList<Double> readArrayListFromFile(String filename) throws IOException{
		ArrayList<String> rows = readFromFileToVector(filename);
		ArrayList<Double> ret = new ArrayList<Double>();
		for (int i = 0; i < rows.size(); i++) {
			String row = (String)rows.get(i);
		    ret.add(Double.valueOf(row));
		}
		return ret;
	}
	
	/**
	 * Reads Matrix from the given file
	 * @param filename file name
	 * @return file content as a Matrix
	 * @throws IOException 
	 */
	public static Matrix readMatrixFromFile(String filename) throws IOException{
		ArrayList<String> rows = readFromFileToVector(filename);
		String firstrow = (String)rows.get(0);
		int dim = extractValues(firstrow).size();
		Matrix ret = new Matrix(rows.size(),dim);
		for (int i = 0; i < rows.size(); i++) {
			String row = (String)rows.get(i);
			ArrayList<String> elements = extractValues(row);
			for (int j = 0; j < elements.size(); j++) {
				ret.set(i, j, Double.valueOf((String)elements.get(j)));
			}
		}
		return ret;
	}
	
	// Output
	
	/**
	 * Writes a scalar to the given file
	 * @param scalar the scalar value
	 * @param filename file name
	 * @throws IOException 
	 */
	public static void writeScalarToFile(double scalar, String filename) throws IOException{
		File file = new File(filename);
		BufferedWriter output =  new BufferedWriter(new FileWriter(file));
		output.write(String.valueOf(scalar));
		output.close();
	}
	
	/**
	 * Writes an ArrayList to the given file
	 * @param list the ArrayList object
	 * @param filename file name
	 * @throws IOException 
	 */
	public static void writeArrayListToFile(ArrayList<Double> list, String filename) throws IOException{
		File file = new File(filename);
		BufferedWriter output =  new BufferedWriter(new FileWriter(file));
		for (int i = 0; i < list.size(); i++) {
			if (i>0) output.newLine();
			output.write(list.get(i).toString());
		}
		output.close();
	}
	
	/**
	 * Writes a Matrix to the given file
	 * @param M the Matrix object
	 * @param filename file name
	 * @throws IOException 
	 */
	public static void writeMatrixToFile(Matrix M, String filename) throws IOException{
			File file = new File(filename);
			BufferedWriter output =  new BufferedWriter(new FileWriter(file));
			for (int i = 0; i < M.getRowDimension(); i++) {
					if (i>0) output.newLine();
					for (int j = 0; j < M.getColumnDimension(); j++) {
							output.write(M.get(i, j)+"  ");
					}
			}
			output.close();
	}
	
	// Private methods	

	private static ArrayList<String> readFromFileToVector(String filename) throws IOException{
		ArrayList<String> ret = new ArrayList<String>();
		File file = new File(filename);
	    BufferedReader input =  new BufferedReader(new FileReader(file));
		String line = null; 
		while (( line = input.readLine()) != null) ret.add(line);
		input.close();
		return ret;
	}
	
	private static ArrayList<String> extractValues(String s){
		s=s.replaceAll("       ", " ");
		s=s.replaceAll("      ", " ");
		s=s.replaceAll("     ", " ");
		s=s.replaceAll("    ", " ");
		s=s.replaceAll("   ", " ");
		s=s.replaceAll("  ", " ");
		s=s.trim();
	
		ArrayList<String> elements = new ArrayList<String>();
		while(s.indexOf(" ")>0){
		String element = s.substring(0,s.indexOf(" "));
		s = s.substring(s.indexOf(" ")+1,s.length());
		elements.add(element);
		}
		elements.add(s);
	
		return elements;
	}
	
}
