/*
  This file is part of the BJP package.

  BJP package 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.

  BJP package 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 Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with BJP package.  If not, see <http://www.gnu.org/licenses/>.
 */
package dataset;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import dataset.adtree.ADNode;
import dataset.feature.BinaryFeature;
import dataset.feature.Feature;
import dataset.feature.MixedFeature;


/**
 * Class used to manage files (data sets, cache files, etc)
 */
public class FileHandler {
	
	/**
	 * Writes an ADNode object in a binary mode in a file
	 */
	public static void writeADTree(File outputFile, ADNode adtree) {
		try {
			FileOutputStream fos = new FileOutputStream(outputFile);
			ObjectOutputStream oos = new ObjectOutputStream(fos);

			oos.writeObject(adtree);
			oos.flush();
			oos.close();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Reads an ADNode object in a binary mode from a file
	 * @param inputFile The file where to read the object
	 * @return The ADNode object readed
	 */
	public static ADNode readADTree(File inputFile) {
		ADNode adtree = null;

		try {
			FileInputStream fis = new FileInputStream(inputFile);

			ObjectInputStream ois = new ObjectInputStream(fis);

			adtree = (ADNode) ois.readObject();
			ois.close();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return adtree;
	}

	/**
	 * Reads a csv file from @param inputFile in the @param dataset
	 * @param inputFile The file which contains the data
	 * @param dataset The dataset object where to store the file content
	 * @throws IOException
	 */
	private static void readCSVDataset(File inputFile, Dataset dataset,
			int maxNumberOfExamples) throws IOException {
		// Open the file reader
		FileReader fileReader = new FileReader(inputFile);
		BufferedReader bufferedReader = new BufferedReader(fileReader);

		int numberOfVariables = 0;
		String line = null;



		while ((line = bufferedReader.readLine()) != null
				&& dataset.getNumberOfExamples() < maxNumberOfExamples) {
			String[] items = line.trim().split(",");

			numberOfVariables = items.length;
			Feature example = null;

			example = new BinaryFeature(numberOfVariables);

			for (int i = 0; i < numberOfVariables; i++) {
				example.addVal(i, Integer.parseInt(items[i]));
			}

			dataset.addExample(example);

		}

		bufferedReader.close();

		dataset.setNumberOfVariables(numberOfVariables);
	}
	
	private static void readCSVDataset(File inputFile, Dataset dataset) throws IOException {
		// Open the file reader
		FileReader fileReader = new FileReader(inputFile);
		BufferedReader bufferedReader = new BufferedReader(fileReader);
		
		int numberOfVariables = 0;
		String line = null;
		
		
		
		while ((line = bufferedReader.readLine()) != null ) {
			String[] items = line.trim().split(",");
			
			numberOfVariables = items.length;
			Feature example = null;
			
			example = new BinaryFeature(numberOfVariables);
			
			for (int i = 0; i < numberOfVariables; i++) {
				example.addVal(i, Integer.parseInt(items[i]));
			}
			
			dataset.addExample(example);
			
		}
		
		bufferedReader.close();
		
		dataset.setNumberOfVariables(numberOfVariables);
	}

	
	
	/**
	 * Reads a wdata file from @param inputFile in the @param dataset
	 * @param inputFile The file which contains the data
	 * @param dataset The dataset object where to store the file content
	 * @throws IOException
	 */
	private static void readWDataDataset(File inputFile, Dataset dataset) throws IOException {
		// Open the file reader
		FileReader fileReader = new FileReader(inputFile);
		BufferedReader bufferedReader = new BufferedReader(fileReader);

		int numberOfVariables = 0;
		String line = null;

		while ((line = bufferedReader.readLine()) != null) {
			String[] parts = line.trim().split("\\|");
			String[] items = parts[1].split(",");

			numberOfVariables = items.length;
			Feature example = new MixedFeature(numberOfVariables);
			for (int i = 0; i < numberOfVariables; i++)
				example.addVal(i, Integer.parseInt(items[i]));


			for (int i = 0; i < Integer.parseInt(parts[0]); i++)
				dataset.addExample(example);
		}

		bufferedReader.close();

		dataset.setNumberOfVariables(numberOfVariables);
	}

	/**
	 * Reads a file from @param inputFile in the @param dataset
	 * @param inputFile The file which contains the data
	 * @param maximumNumberOfFeatures A parameter to indicated the number of data points to be readed
	 * @param datasetType It can be csv format or wdata format
	 * @return
	 */
	public static Dataset
	readDataset(File inputFile,
		    int maximumNumberOfFeatures,
		    DatasetType datasetType) {

		Dataset dataset = new Dataset();
		

		try {
			switch(datasetType) {
			case WDATA:
				readWDataDataset(inputFile, dataset);
				break;
			case CSV:
				readCSVDataset(inputFile, dataset, maximumNumberOfFeatures);
				break;

			default:
				readCSVDataset(inputFile, dataset);
				break;
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		return dataset;
	}

}