package Model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Random;

import weka.classifiers.Evaluation;
import weka.classifiers.trees.J48;
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;

public class Classification {
	static J48 j48;
	private static Evaluation eval;
	public static J48 constructModel (String filename) {

		DataSource source;
		j48 = null;
		try {
			source = new DataSource("apprentissagebest.arff");
			Instances data = source.getDataSet();
			// setting class attribute if the data format does not provide this information
			// For example, the XRFF format saves the class attribute information as well
			if (data.classIndex() == -1)
				data.setClassIndex(data.numAttributes() - 1);
			// classifier
			j48 = new J48();
			j48.setOptions(weka.core.Utils.splitOptions("-C 0.25 -M 2"));
			j48.buildClassifier(data);
			// train and make predictions
			eval = new Evaluation(data);
			eval.crossValidateModel(j48, data, 10, new Random(1));
			System.out.println(j48.toString());
			
			System.out.println(eval.toSummaryString("\nResults\n======\n", false));

			// Get the confusion matrix
			System.out.println(eval.toMatrixString());
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return j48;
	}
	
	public static double[] takeDecision (String filename){
		double[] clsLabels = null;
		try {
			J48 j48 = constructModel(filename);

			// load unlabeled data
			Instances unlabeled = new Instances(new BufferedReader(new FileReader("identification.arff")));

			// set class attribute
			unlabeled.setClassIndex(unlabeled.numAttributes() - 1);

			// create copy
			Instances labeled = new Instances(unlabeled);

			// label instances
			clsLabels = new double[unlabeled.numInstances()];
			for (int i = 0; i < unlabeled.numInstances(); i++) {
				double clsLabel = j48.classifyInstance(unlabeled.instance(i));
				clsLabels[i] = clsLabel;
				labeled.instance(i).setClassValue(clsLabel);
			}
			
			// save labeled data
			BufferedWriter writer = new BufferedWriter(new FileWriter("decision.arff"));
			writer.write(labeled.toString());
			writer.newLine();
			writer.flush();
			writer.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return clsLabels;
	}
	
	public static String getDecisionTree(){
		return j48.toString();
	}
	public static String getResults(){
		return eval.toSummaryString("\nResults\n======\n", false);
	}
	public static String getMatrix() throws Exception{
		return eval.toMatrixString();
	}
}
