package com.curiam.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.curiam.client.componentes.Utiles;
import com.curiam.client.datos.CaseBeanTPB;
import com.curiam.client.datos.ResultBeanTPB;
import com.curiam.client.llamada.GreetingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import es.upv.ibime.bmg.classificationengine.client.LocalClassificationEngineClient;
import es.upv.ibime.bmg.classificationengine.data.ClassificationData;
import es.upv.ibime.bmg.classificationengine.data.ClassificationID;
import es.upv.ibime.bmg.classificationengine.data.ClassificationInput;
import es.upv.ibime.bmg.classificationengine.data.ClassificationResult;
import es.upv.ibime.bmg.classificationengine.data.ClassifierResult;
  



/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")

/** Interaccion con el clasificador **/

public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	public ResultBeanTPB greetServer(CaseBeanTPB cb) {
		
		LocalClassificationEngineClient client = new LocalClassificationEngineClient();
		ClassificationInput input = new ClassificationInput("none", "none", cb.getCaseID(), new ClassificationID("id"));
		
		input.addClassifierName(cb.getCaseID());
		
		input.addData(new ClassificationData("Age", cb.getAge()));
		input.addData(new ClassificationData("Clinical_Presentation", cb.getClinical_presentation()));
		input.addData(new ClassificationData("Location", cb.getLocalization()));
		input.addData(new ClassificationData("Size", cb.getSize()));
		input.addData(new ClassificationData("Shape", cb.getShape()));
		input.addData(new ClassificationData("T1_Hyperintense_Tracts", cb.getT1_hyperitense_tracts()));
		input.addData(new ClassificationData("T1_Signal_Intensity", cb.getT1_signal_intensity()));
		input.addData(new ClassificationData("T2_Signal_Intensity", cb.getT2_signal_intensity()));
		input.addData(new ClassificationData("Margins", cb.getMargins()));
		input.addData(new ClassificationData("Homogeneity", cb.getHomogeneity()));
		input.addData(new ClassificationData("Edema", cb.getEdema()));
		input.addData(new ClassificationData("Multiplicity", cb.getMultiplicity()));
		input.addData(new ClassificationData("Target_Appearance", cb.getTarget_appearance()));
		input.addData(new ClassificationData("Dependence", cb.getDependence()));
		input.addData(new ClassificationData("Muscular_Atrophy", cb.getMulcular_atrophy()));
		input.addData(new ClassificationData("Calcification", cb.getCalcification()));
		input.addData(new ClassificationData("Vessels", cb.getVessels()));
		input.addData(new ClassificationData("Intratumoral_Hemorrhage", cb.getIntratumorral_hemorrhage()));
		input.addData(new ClassificationData("Fat", cb.getFat()));
		input.addData(new ClassificationData("Fibrosis", cb.getFibrosis()));
		input.addData(new ClassificationData("Fascial_Relationship", cb.getFascial_relationship()));
		input.addData(new ClassificationData("Bone_Alteration", cb.getBone_alteration()));
		input.addData(new ClassificationData("Lesion_Character", cb.getLesion_character()));

		
		
		
		ClassificationResult classificationResult = client.classify(input);
		ClassifierResult result = classificationResult.getClassificationResults().get(0);
		String resultXML = result.getXML();
		 
		//CLASSIFICATION RESULTS CAN BE OBTAINED FROM THE ClassifierResult CLASS
		 result.getProbabilities();
		 ArrayList<String> legends = new ArrayList<String>();
		 
		
		//THIS PARSES THE XML RESULT AND WRITES RESULTS IN ResultBean
		SAXBuilder builder = new SAXBuilder();
		Document resultDocument = null;
	    try {
	    	resultDocument = builder.build(new	StringReader(resultXML));
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Element probabilitiesElement = resultDocument.getRootElement().getChild("Answer").getChild("Probabilities").getChild("Probabilities").getChild("Matrix").getChild("row");
		Element labelsElement = resultDocument.getRootElement().getChild("Answer").getChild("Probabilities").getChild("Labels").getChild("Matrix").getChild("row");
		
		ResultBeanTPB resultBean = new ResultBeanTPB();
		
		double[] probabilities = new double[probabilitiesElement.getChildren("column").size()];
		for (int i = 0; i < probabilities.length; i++) {
			probabilities[i] =
				Double.parseDouble(((Element)probabilitiesElement.getChildren("column").get(i)).getText());
		}
		
		String[] labels = new String[labelsElement.getChildren("column").size()];
		for (int i = 0; i < probabilities.length; i++) {
			labels[i] =
				((Element)labelsElement.getChildren("column").get(i)).getText();
		}
		
		
		for (int i = 0; i < probabilities.length; i++) {
			resultBean.setProbabilities(probabilities[i]);
			resultBean.setLabels(labels[i]);
			resultBean.setLegends(result.getLegend().get(i).getClassID());
		}
		 
		return resultBean;
	}

	/** gestion de ficheros **/

	public Boolean eliminarFichero(String fichero) {
		File file = new File(fichero);
		if(file.isDirectory()){
			File[] files = file.listFiles();
			for(int i=0;i<files.length;i++)
				files[i].delete();
		}
		
		return file.delete();
	}
	
	public Boolean guardarEnFichero(String fichero, String datos) {
		try{
			
			FileWriter file = new FileWriter(fichero);
			BufferedWriter out = new BufferedWriter(file);
			out.write(datos);
			out.close();
			file.close();
		} catch (IOException e){

			return false;
		}
		
		return true;
	}

	public String leerFichero(String fichero) {
		String datos = "";
		
		try {
				
			FileReader file = new FileReader(fichero);
			BufferedReader in = new BufferedReader(file);
			String aux = in.readLine();
			while(aux != null){
				datos += aux;
				aux = in.readLine();
			}
			file.close();
			in.close();
			
		} catch (IOException e){
			return null;
		}
		
		return datos;
	}
	
	public Boolean ubicarfichero(String sourceFile, String destinationFile, String user) {
		
		try {
			
			File inFile = new File(sourceFile);
			File outFile = new File("config/"+user+"/"+destinationFile);
			outFile.createNewFile();
			
			FileInputStream in = new FileInputStream(inFile);
			FileOutputStream out = new FileOutputStream(outFile);
 
			int c;
			while( (c = in.read() ) != -1)
				out.write(c);
 
			in.close();
			out.close();
			inFile.delete();
			
		} catch(IOException e) {
			return false;
		}
		return true;
	}
 
	public Boolean crearDirectorio(String nombre){
		
		File dir = new File(nombre);
		if(!dir.exists())
			return dir.mkdir();
		
		return false;
	}
	
}