import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.graphstream.graph.Graph;
import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.stream.file.FileSourceEdge;

public class TP2 {

	public static void main(String[] args) {
		Graph graphe = new SingleGraph("Graphe");

		FileSourceEdge fs = new FileSourceEdge();

		fs.addSink(graphe);

		try {
			fs.readAll("data/com-dblp.ungraph.txt");
		} catch (IOException e) {
			System.out.println("Fichier non trouvé");
		} finally {
			fs.removeSink(graphe);
		}

		System.out.println("Question n°2");

		System.out.println("Nombre de noeuds : " + graphe.getNodeCount());
		System.out.println("Nombre d'arrêtes : " + graphe.getEdgeCount());
		System.out.println("Degré moyen : " + Toolkit.averageDegree(graphe));
		System.out.println("Coefficient de clustering moyen : " + Toolkit.averageClusteringCoefficient(graphe));
		System.out.println("Coefficient de clustering pour un réseau aléatoire de même taille et du même degré moyen: "+
				Toolkit.averageDegree(graphe)/graphe.getNodeCount());

		System.out.println("\nQuestion n°3");

		System.out.println("Le réseau est connexe : " + Toolkit.isConnected(graphe));
		System.out.println("Un réseau aléatoire de la même taille et degré moyen sera-t-il connexe ? " +
							(Toolkit.averageDegree(graphe) > Math.log(graphe.getNodeCount())));
		System.out.println("À partir de quel degré moyen un réseau aléatoire avec cette taille devient connexe ? " +
				Math.log(graphe.getNodeCount()));



		// distribution des degrés
		double[] degree = normaliser(graphe);
		TP2.creerFichier(degree);

		// graphe Linéaire
		TP2.creerGrapheLineaire();

		// graphe Log Log
		TP2.creerGrapheLogLog();

		// graphe distribution poisson
		TP2.creerGraphePoisson();


	}

	public static double[] normaliser(Graph g)
	{
		int[] dd = Toolkit.degreeDistribution(g);
		double[] degree = new double[dd.length];
		for (int k = 0; k < dd.length; k++) {
			if (dd[k] != 0) {
				degree[k] = (double)dd[k] / g.getNodeCount();
			}
		}
		return degree;
	}

	public static void creerFichier(double[] tabResultat)
	{
		try {
			File f = new File("./data/Resultat.dat");
			FileWriter writer = new FileWriter(f);
			for (int i = 1; i < tabResultat.length; i++)
				writer.write(i + " " + tabResultat[i] + "\n");

			writer.close();

		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public static void creerGrapheLineaire()
	{
		File dossier = new File("./gnuplot");
		if(!dossier.exists())
			dossier.mkdir();
		dossier = new File("./graphes");
		if(!dossier.exists())
			dossier.mkdir();

		try {
			File f = new File("./gnuplot/Lineaire.gnuplot");
			FileWriter writer = new FileWriter(f);
			writer.write(
					"set terminal png\n" +
							"set title \"Distribution des degrés\"\n" +
							"set xlabel 'k'\n" +
							"set ylabel 'p(k)'\n" +
							"set output './graphes/Lineaire.png'\n" +
							"plot './data/Resultat.dat' title 'Distribution des degrés' with linesp lt 2 pt 2 lc 2"
			);
			writer.close();
		} catch (Exception e) {
			System.out.println(e);
		}

		try {
			Runtime commandPrompt = Runtime.getRuntime();
			commandPrompt.exec("gnuplot ./gnuplot/Lineaire.gnuplot");
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public static void creerGrapheLogLog()
	{
		File dossier = new File("./gnuplot");
		if(!dossier.exists())
			dossier.mkdir();
		dossier = new File("./graphes");
		if(!dossier.exists())
			dossier.mkdir();
		try {
			File f = new File("./gnuplot/Log.gnuplot");
			FileWriter writer = new FileWriter(f);
			writer.write(
					"set terminal png\n" +
							"set title \"Distribution des degrés\"\n" +
							"set xlabel 'k'\n" +
							"set ylabel 'p(k)'\n" +
							"set output './graphes/LogLog.png'\n" +
							"set logscale xy\n" +
							"set yrange [1e-6:1]\n" +
							"plot './data/Resultat.dat' title 'Distribution des degrés' with linesp lt 2 pt 2 lc 2"
			);
			writer.close();
		} catch (Exception e) {
			System.out.println(e);
		}

		try {
			Runtime commandPrompt = Runtime.getRuntime();
			commandPrompt.exec("gnuplot ./gnuplot/Log.gnuplot");
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public static void creerGraphePoisson()
	{
		File dossier = new File("./gnuplot");
		if(!dossier.exists())
			dossier.mkdir();
		dossier = new File("./graphes");
		if(!dossier.exists())
			dossier.mkdir();

		try {
			File f = new File("./gnuplot/Poisson.gnuplot");
			FileWriter writer = new FileWriter(f);
			writer.write(
			"set terminal png\n" +
				"set title \"Distribution des degrés\"\n" +
				"set xlabel 'k'\n" +
				"set ylabel 'p(k)'\n" +
				"set output './graphes/distribution_Poisson.png'\n" +
				"set logscale xy\n" +
				"set yrange [1e-6:1]\n" +
				"# Poisson\n" +
				"lambda = 6.62208890914917\n" +
				"poisson(k) = lambda ** k * exp(-lambda) / gamma(k + 1)\n" +
				"\n" +
				"# on va fitter une fonction linéaire en log-log\n" +
				"\n" +
				"f(x) = lc - gamma * x\n" +
				"fit f(x) './data/Resultat.dat' using (log($1)):(log($2)) via lc, gamma\n" +
				"c = exp(lc)\n" +
				"power(k) = c * k ** (-gamma)\n" +
				"plot './data/Resultat.dat' title 'DBLP', \\\n" +
				"poisson(x) title 'Loi de poisson', \\\n" +
				"power(x) title 'Loi de puissance'\n"
			);
			writer.close();
		} catch (Exception e) {
			System.out.println(e);
		}

		try {
			Runtime commandPrompt = Runtime.getRuntime();
			commandPrompt.exec("gnuplot ./gnuplot/Poisson.gnuplot");
		} catch (Exception e) {
			System.out.println(e);
		}
	}
}