using System;
using MatrixLibrary;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace Graphs
{
	public class GraphDisplay
	{
		public GraphDisplay ()
		{
        }

		public  void ConsoleDisplay (Graph g)
		{

			Console.WriteLine ("Graphe : ");
			Console.WriteLine (" \tid : " + g.Id);
			Console.WriteLine (" \tname : " + g.Name);

			Console.WriteLine ("\nListe des noeuds : ");
			foreach (Node n in g.ListNodes) {

				if (n.Label == null)
					Console.WriteLine ("Etiquette null");
				else
					Console.WriteLine ("\t" + n.Id + " : " + n.Label.toString ());

			}

			Console.WriteLine ("Liste des edges : ");
			foreach (Edge e in g.ListEdges) {
				if (e.Label == null)
					Console.WriteLine ("Etiquette edge null");

				if (e.Label != null)
					Console.WriteLine ("\t" + e.Id + " de " + e.NodeSource.Id + " à " + e.NodeTarget.Id + " : " + e.Label.toString ());
                
			}


		}

		public  void MatrixDisplay (Matrix m)
		{
			//Affichage des numéros de colonnes
			Console.Write ("    ");
			for (int numColonne = 0; numColonne < m.NoCols; numColonne++) {
				Console.Write (numColonne);
			}
			Console.WriteLine ();
			//Affichage des lignes
			for (int i = 0; i < m.NoRows; i++) {
				Console.Write (i + " : ");

				for (int j = 0; j < m.NoCols; j++) {
					Console.Write (m [i, j]);
				}
				Console.WriteLine ();
			}
		}
	
		public void TouchDisplay (Graph g, string PathRessource)
		{
			IOGraph IOG = new IOGraph ();
			Console.WriteLine (PathRessource);
			IOG.WriteGFormat (g, PathRessource + "/touchgraph/tmptouch.g");
			string cmd = "java -classpath " + "\"" + PathRessource + "/touchgraph/colt.jar \"" + " -jar " + PathRessource + "/touchgraph/RomTouchGraph.jar " + PathRessource + "/touchgraph/tmptouch.g";
			Console.WriteLine (cmd);
			string exec = "java";
			string args = "-classpath " + "\"" + PathRessource + "/touchgraph/colt.jar \"" + " -jar " + PathRessource + "/touchgraph/RomTouchGraph.jar " + PathRessource + "/touchgraph/tmptouch.g";
			ExecuteCommandNoWait (exec, args);

		}

		public void ExportJPG (Graph g, string PathRessource, string FileNameJPG)
		{
			IOGraph IOG = new IOGraph ();
			IOG.WriteDotFormat (g, PathRessource + "/dot2jpg/tmp.dot");
			string exec = PathRessource + "/dot2jpg/dot.exe";
			string args = PathRessource + "/dot2jpg/tmp.dot -Tjpg -o" + FileNameJPG;
			string cmd = exec + " " + args;
			Console.WriteLine (cmd);
			ExecuteCommandWait (exec, args);
			//System.Diagnostics.Process.Start(exec,cmd);
		}

		public void ExportHTML (Graph g, string PathRessource, string FileNameHTML)
		{
	
			string filesansext = FileNameHTML;
			this.ExportJPG (g, PathRessource, filesansext + ".jpg");
			TextWriter tw;
			tw = new StreamWriter (FileNameHTML);
			tw.WriteLine ("<html>");
			tw.WriteLine ("<head>");
			tw.WriteLine ("<title>Graph JPEG</title>");
			tw.WriteLine ("</head>");
			tw.WriteLine ("<body>");
			tw.WriteLine ("<table border cellpadding=\"10\">");
			tw.WriteLine ("<tr>");
			tw.WriteLine ("<td bordercolor=\"blue\"><img src=\"" +System.IO.Path.GetFullPath(filesansext + ".jpg") + "\"> </td>");
			tw.WriteLine ("</tr>");

			tw.WriteLine ("</table>");		
			tw.WriteLine ("</body>");
			tw.WriteLine ("</html>");

			tw.Close ();
	
	
		}


		public void HTMLDisplay (Graph g, string PathRessource, string FileNameHTML)
		{
			ExportHTML ( g, PathRessource, FileNameHTML);
			//Process.Start(FileNameHTML);
		}

		public void ImageDisplay (Graph g, string PathRessource, string FileNameImage)
		{
			ExportJPG ( g, PathRessource, FileNameImage);
			//Process.Start(FileNameImage);
		}




		/// <summary>
/// Executes a shell command synchronously.
/// </summary>
/// <param name="command">string command</param>
/// <returns>string, as output of the command.</returns>
		private void ExecuteCommandNoWait (string exec, string args)
		{
			try {
				// create the ProcessStartInfo using "cmd" as the program to be run,
				// and "/c " as the parameters.
				// Incidentally, /c tells cmd that we want it to execute the command that follows,
				// and then exit.
				System.Diagnostics.ProcessStartInfo procStartInfo =
        new System.Diagnostics.ProcessStartInfo ("cmd", "/c " + exec + " " + args);

				// The following commands are needed to redirect the standard output.
				// This means that it will be redirected to the Process.StandardOutput StreamReader.
				procStartInfo.RedirectStandardOutput = false;
				procStartInfo.UseShellExecute = false;
				// Do not create the black window.
				procStartInfo.CreateNoWindow = false;

				procStartInfo.FileName = exec;
				procStartInfo.Arguments = args;
				// Now we create a process, assign its ProcessStartInfo and start it
				System.Diagnostics.Process proc = new System.Diagnostics.Process ();
				proc.StartInfo = procStartInfo;
				proc.Start ();
				// Get the output into a string
				//string result = proc.StandardOutput.ReadToEnd ();
				// Display the command output.
				//Console.WriteLine (result);
			} catch (Exception objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			}
		}




		/// <summary>
/// Executes a shell command synchronously.
/// </summary>
/// <param name="command">string command</param>
/// <returns>string, as output of the command.</returns>
		private void ExecuteCommandWait (string exec, string args)
		{
			try {
				// create the ProcessStartInfo using "cmd" as the program to be run,
				// and "/c " as the parameters.
				// Incidentally, /c tells cmd that we want it to execute the command that follows,
				// and then exit.
				System.Diagnostics.ProcessStartInfo procStartInfo =
        new System.Diagnostics.ProcessStartInfo ("cmd", "/c " + exec + " " + args);

				// The following commands are needed to redirect the standard output.
				// This means that it will be redirected to the Process.StandardOutput StreamReader.
				procStartInfo.RedirectStandardOutput = true;
				procStartInfo.UseShellExecute = false;
				// Do not create the black window.
				procStartInfo.CreateNoWindow = true;

				procStartInfo.FileName = exec;
				procStartInfo.Arguments = args;
				// Now we create a process, assign its ProcessStartInfo and start it
				System.Diagnostics.Process proc = new System.Diagnostics.Process ();
				proc.StartInfo = procStartInfo;
				proc.Start ();
				// Get the output into a string
				string result = proc.StandardOutput.ReadToEnd ();
				proc.WaitForExit ();
				// Display the command output.
				Console.WriteLine (result);
			} catch (Exception objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			}
		}


		/// <summary>
/// Executes a shell command synchronously.
/// </summary>
/// <param name="command">string command</param>
/// <returns>string, as output of the command.</returns>
		private void ExecuteCommandSync (object comm)
		{
			try {
				// create the ProcessStartInfo using "cmd" as the program to be run,
				// and "/c " as the parameters.
				// Incidentally, /c tells cmd that we want it to execute the command that follows,
				// and then exit.
				System.Diagnostics.ProcessStartInfo procStartInfo =
        new System.Diagnostics.ProcessStartInfo ("cmd", "/c " + comm);

				// The following commands are needed to redirect the standard output.
				// This means that it will be redirected to the Process.StandardOutput StreamReader.
				procStartInfo.RedirectStandardOutput = true;
				procStartInfo.UseShellExecute = false;
				// Do not create the black window.
				procStartInfo.CreateNoWindow = true;

				//procStartInfo.FileName = exec;
				//procStartInfo.Arguments = args;
				// Now we create a process, assign its ProcessStartInfo and start it
				System.Diagnostics.Process proc = new System.Diagnostics.Process ();
				proc.StartInfo = procStartInfo;
				proc.Start ();
				// Get the output into a string
				string result = proc.StandardOutput.ReadToEnd ();
				// Display the command output.
				Console.WriteLine (result);
			} catch (Exception objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			}
		}



/// <summary>
/// Execute the command Asynchronously.
/// </summary>
/// <param name="command">string command.</param>
		private void ExecuteCommandAsync (string command)
		{
			try {
				//Asynchronously start the Thread to process the Execute command request.
				Thread objThread = new Thread (new ParameterizedThreadStart (ExecuteCommandSync));
				//Make the thread as background thread.
				objThread.IsBackground = true;
				//Set the Priority of the thread.
				objThread.Priority = ThreadPriority.AboveNormal;
				//Start the thread.
				objThread.Start ();
				objThread.Join ();
				//while(objThread.IsAlive){
				//}
			} catch (ThreadStartException objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			} catch (ThreadAbortException objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			} catch (Exception objException) {
				// Log the exception
				Console.WriteLine (objException.ToString ());
			}
		}



	}
}