//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows.Forms;

using System.Threading;
using System.Reflection;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;

namespace CLRUnleashed.Remoting
{
	/// <summary>
	/// Podsumowanie dla TimeForm.
	/// </summary>
	public class TimeForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TextBox httpsoap;
		private System.Windows.Forms.TextBox httpbinary;
		private System.Windows.Forms.TextBox tcpsoap;
		private System.Windows.Forms.TextBox tcpbinary;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Button startButton;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.Label label8;

		private System.ComponentModel.IContainer components;

		public TimeForm()
		{
			//
			// Wymagane do obsługi Windows Form Designer
			//
			InitializeComponent();
			
		}

		/// <summary>
		/// Oczyszczenie używanych zasobów.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Metoda wymagana do obsługi Designera - nie należy modyfikować
		/// zawartości tej metody przy użyciu edytora kodu.
		/// </summary>
		private void InitializeComponent()
		{
			this.httpsoap = new System.Windows.Forms.TextBox();
			this.httpbinary = new System.Windows.Forms.TextBox();
			this.tcpsoap = new System.Windows.Forms.TextBox();
			this.tcpbinary = new System.Windows.Forms.TextBox();
			this.label1 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.startButton = new System.Windows.Forms.Button();
			this.label5 = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.label7 = new System.Windows.Forms.Label();
			this.label8 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// httpsoap
			// 
			this.httpsoap.BackColor = System.Drawing.Color.Black;
			this.httpsoap.Font = new System.Drawing.Font("Trebuchet MS", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.httpsoap.ForeColor = System.Drawing.Color.Lime;
			this.httpsoap.Location = new System.Drawing.Point(256, 15);
			this.httpsoap.Name = "httpsoap";
			this.httpsoap.Size = new System.Drawing.Size(128, 39);
			this.httpsoap.TabIndex = 0;
			this.httpsoap.Text = "";
			this.httpsoap.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
			// 
			// httpbinary
			// 
			this.httpbinary.BackColor = System.Drawing.Color.Black;
			this.httpbinary.Font = new System.Drawing.Font("Trebuchet MS", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.httpbinary.ForeColor = System.Drawing.Color.Lime;
			this.httpbinary.Location = new System.Drawing.Point(256, 68);
			this.httpbinary.Name = "httpbinary";
			this.httpbinary.Size = new System.Drawing.Size(128, 39);
			this.httpbinary.TabIndex = 1;
			this.httpbinary.Text = "";
			this.httpbinary.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
			// 
			// tcpsoap
			// 
			this.tcpsoap.BackColor = System.Drawing.Color.Black;
			this.tcpsoap.Font = new System.Drawing.Font("Trebuchet MS", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.tcpsoap.ForeColor = System.Drawing.Color.Lime;
			this.tcpsoap.Location = new System.Drawing.Point(256, 121);
			this.tcpsoap.Name = "tcpsoap";
			this.tcpsoap.Size = new System.Drawing.Size(128, 39);
			this.tcpsoap.TabIndex = 2;
			this.tcpsoap.Text = "";
			this.tcpsoap.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
			// 
			// tcpbinary
			// 
			this.tcpbinary.BackColor = System.Drawing.Color.Black;
			this.tcpbinary.Font = new System.Drawing.Font("Trebuchet MS", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.tcpbinary.ForeColor = System.Drawing.Color.Lime;
			this.tcpbinary.Location = new System.Drawing.Point(256, 174);
			this.tcpbinary.Name = "tcpbinary";
			this.tcpbinary.Size = new System.Drawing.Size(128, 39);
			this.tcpbinary.TabIndex = 3;
			this.tcpbinary.Text = "";
			this.tcpbinary.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
			// 
			// label1
			// 
			this.label1.Font = new System.Drawing.Font("Trebuchet MS", 22.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label1.Location = new System.Drawing.Point(7, 15);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(212, 38);
			this.label1.TabIndex = 4;
			this.label1.Text = "HTTP SOAP";
			// 
			// label2
			// 
			this.label2.Font = new System.Drawing.Font("Trebuchet MS", 22.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label2.Location = new System.Drawing.Point(7, 68);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(212, 38);
			this.label2.TabIndex = 5;
			this.label2.Text = "HTTP binarnie";
			// 
			// label3
			// 
			this.label3.Font = new System.Drawing.Font("Trebuchet MS", 22.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label3.Location = new System.Drawing.Point(7, 121);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(212, 38);
			this.label3.TabIndex = 6;
			this.label3.Text = "TCP SOAP";
			// 
			// label4
			// 
			this.label4.Font = new System.Drawing.Font("Trebuchet MS", 22.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label4.Location = new System.Drawing.Point(7, 174);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(212, 38);
			this.label4.TabIndex = 7;
			this.label4.Text = "TCP binarnie";
			// 
			// startButton
			// 
			this.startButton.Font = new System.Drawing.Font("Trebuchet MS", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.startButton.Location = new System.Drawing.Point(183, 242);
			this.startButton.Name = "startButton";
			this.startButton.Size = new System.Drawing.Size(109, 46);
			this.startButton.TabIndex = 8;
			this.startButton.Text = "Start";
			this.startButton.Click += new System.EventHandler(this.OnStart);
			// 
			// label5
			// 
			this.label5.Font = new System.Drawing.Font("Trebuchet MS", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label5.Location = new System.Drawing.Point(392, 24);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(136, 32);
			this.label5.TabIndex = 9;
			this.label5.Text = "wywołań/s";
			// 
			// label6
			// 
			this.label6.Font = new System.Drawing.Font("Trebuchet MS", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label6.Location = new System.Drawing.Point(392, 72);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(136, 32);
			this.label6.TabIndex = 10;
			this.label6.Text = "wywołań/s";
			// 
			// label7
			// 
			this.label7.Font = new System.Drawing.Font("Trebuchet MS", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label7.Location = new System.Drawing.Point(392, 128);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(136, 32);
			this.label7.TabIndex = 11;
			this.label7.Text = "wywołań/s";
			// 
			// label8
			// 
			this.label8.Font = new System.Drawing.Font("Trebuchet MS", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label8.Location = new System.Drawing.Point(392, 176);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(136, 32);
			this.label8.TabIndex = 12;
			this.label8.Text = "wywołań/s";
			// 
			// TimeForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(544, 310);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.label8,
																		  this.label7,
																		  this.label6,
																		  this.label5,
																		  this.startButton,
																		  this.label4,
																		  this.label3,
																		  this.label2,
																		  this.label1,
																		  this.tcpbinary,
																		  this.tcpsoap,
																		  this.httpbinary,
																		  this.httpsoap});
			this.Name = "TimeForm";
			this.Text = "Test zdalnego czasu";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// Główny punkt wejścia dla aplikacji.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new TimeForm());
		}

		private double Test(string configFile, int iterations)
		{
			// Wyszukanie pliku konfiguracji
			if(!File.Exists(configFile))
			{
				configFile = @"..\..\" + configFile;
				if(!File.Exists(configFile))
					return 0.0;
			}

			FileInfo fi = new FileInfo(configFile);
			configFile = fi.FullName;
			fi = null;

			// Ustawienie ApplicationBase na aktualny katalog

			AppDomainSetup info = new AppDomainSetup();

			string ab = System.Environment.CurrentDirectory;

			info.ApplicationBase = ab;

			// Utworzenie domeny aplikacji z pustym dowodem

			AppDomain dom = AppDomain.CreateDomain("RemotePerfTest", null, info);

			// Załadowanie podzespołu HelloWorld2 i utworzenie egzemplarza
			// typu HelloWorld
			BindingFlags flags = (BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance);
			ObjectHandle objh = dom.CreateInstance("PerfObject", "CLRUnleashed.Remoting.RemotingTest", false, flags, null, null, null, null, null);
			if (objh == null) 
			{
				Debug.WriteLine("Działanie CreateInstance nie powiodło się");
				return 0.0;
			}

			// Rozpakowanie obiektu
			Object obj = objh.Unwrap();

			// Rzutowanie do bieżącego typu
			RemotingTest h = (RemotingTest)obj;

			Debug.WriteLine(string.Format("W domenie aplikacji: {0} wątek {1}", Thread.GetDomain().FriendlyName, Thread.CurrentThread.GetHashCode()));
			// Wywołanie metody
			double testResult = 0.0;
			try
			{
				testResult = h.Test(configFile, iterations);
			}
			catch(Exception e)
			{
				Debug.WriteLine(e);
			}

			// Oczyszczenie poprzez usunięcie domeny aplikacji z pamięci
			AppDomain.Unload(dom);  

			return testResult;
		}

		private void HttpSoapTest()
		{
			double result = Test("Time.Http.Soap.config", 1000);
			httpsoap.Text = string.Format("{0:F2}", result);
			httpsoap.Refresh();
		}
		private void HttpBinaryTest()
		{
			double result = Test("Time.Http.Binary.config", 1000);
			httpbinary.Text = string.Format("{0:F2}", result);
			httpbinary.Refresh();
		}
		private void TcpSoapTest()
		{
			double result = Test("Time.Tcp.Soap.config", 1000);
			tcpsoap.Text = string.Format("{0:F2}", result);
			tcpsoap.Refresh();
		}
		private void TcpBinaryTest()
		{
			double result = Test("Time.Tcp.Binary.config", 1000);
			tcpbinary.Text = string.Format("{0:F2}", result);
			tcpbinary.Refresh();
		}
		private void OnStart(object sender, System.EventArgs e)
		{
			httpsoap.Text = "";
			httpsoap.Refresh();
			httpbinary.Text = "";
			httpbinary.Refresh();
			tcpsoap.Text = "";
			tcpsoap.Refresh();
			tcpbinary.Text = "";
			tcpbinary.Refresh();
			TcpBinaryTest();
			TcpSoapTest();
			HttpBinaryTest();
			HttpSoapTest();
		}
	}
}
