//
// 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.Diagnostics;
using System.Collections;
using System.Text;
using System.Web.Mail;

namespace TraceSwitchTest
{
	/// <summary>
	/// Podsumowanie dla TraceSwitchMain.
	/// </summary>
	// W zależności od konfiguracji wyniki są zapisywane w:
	// trace.log
	// dzienniku zdarzeń
	// strumieniu wyjściowym debug
	// 
	class TraceSwitchMain
	{
		[Conditional("DEBUG")]
		static void WriteDebugOutput()
		{
			Console.WriteLine("To są informacje o debugowaniu");
		}

		public class CustomTraceListener : TraceListener
		{
			private Queue messageList;
			private StringBuilder message;
			private string mailTo;

			public CustomTraceListener(string to)
			{
				messageList = Queue.Synchronized(new Queue());
				mailTo = to;
			}
			public override void Close()
			{
				// Odbiornik został zamknięty
				Flush();

				MailMessage mailMessage = new MailMessage();
				mailMessage.To = mailTo;
				mailMessage.Subject = "Wydruk śledzenia";
				mailMessage.BodyFormat = MailFormat.Text;

				while ( messageList.Count > 0 )
					mailMessage.Body += messageList.Dequeue() + "\r\n";

				mailMessage.Body += "\r\n";
				SmtpMail.Send(mailMessage);
			}
			public override void Flush()
			{
				// Odbiornik został oczyszczony
				if(message != null)
				{
					messageList.Enqueue(message);
					message = null;
				}
			}
			public override void Write(object o)
			{
				// Utworzenie wiadomości
				if(message == null)
					message = new StringBuilder();
				message.Append(o.ToString());
			}
			public override void Write(string s)
			{
				// Utworzenie wiadomości
				if(message == null)
					message = new StringBuilder();
				message.Append(s);
			}
			public override void Write(object o, string category)
			{
				// Utworzenie wiadomości
				if(message == null)
					message = new StringBuilder();
				message.Append(category + ": " + o.ToString());
			}
			public override void Write(string s, string category)
			{
				// Utworzenie wiadomości
				if(message == null)
					message = new StringBuilder();
				message.Append(category + ": " + s);
			}
			public override void WriteLine(object o)
			{
				Flush();
				// Zapisanie wiersza wiadomości
				messageList.Enqueue(o.ToString());
			}
			public override void WriteLine(string s)
			{
				Flush();
				// Zapisanie wiersza wiadomości
				messageList.Enqueue(s);
			}
			public override void WriteLine(object o, string s)
			{
				Flush();
				// Zapisanie wiersza wiadomości
				messageList.Enqueue(o.ToString() + s);
			}
			public override void WriteLine(string s, string category)
			{
				Flush();
				// Zapisanie wiersza wiadomości
				messageList.Enqueue(category + ": " + s);
			}
		}

		// Dostępne wartości dla nowego przełącznika.
		public enum CustomTracingSwitchLevel 
		{
			Off = 0,
			ShowStopper = 1,
			Critical = 2,
			Severe = 3,
			Annoying = 4,
			Success = 5
		}

		public class CustomTracingSwitch : Switch 
		{
			public CustomTracingSwitch(string displayName, string description) : base(displayName, description)
			{
			}
 			public bool ShowStopper
			{
				get
				{
					return SwitchSetting >= (int)CustomTracingSwitchLevel.ShowStopper;
				}
			}
			public bool Critical
			{
				get
				{
					return SwitchSetting >= (int)CustomTracingSwitchLevel.Critical;
				}
			}
			public bool Severe
			{
				get
				{
					return SwitchSetting >= (int)CustomTracingSwitchLevel.Severe;
				}
			}
			public bool Annoying
			{
				get
				{
					return SwitchSetting >= (int)CustomTracingSwitchLevel.Annoying;
				}
			}
			public bool Success
			{
				get
				{
					return SwitchSetting >= (int)CustomTracingSwitchLevel.Success;
				}
			}
		}

 	    static void Main(string[] args)
		{
			CustomTraceListener ctl = new CustomTraceListener("imie.nazwisko@mojafirma.com");
			Trace.Listeners.Add(ctl);

			TraceSwitch ts1 = new TraceSwitch("MySwitch", "Mój przełącznik debugowania");
			TraceSwitch ts2 = new TraceSwitch("YourSwitch", "Twój przełącznik debugowania");

			Trace.WriteLineIf(ts1.Level == TraceLevel.Info, "Moje wyniki");
			Trace.WriteLineIf(ts1.TraceError, "Mój komunikat o błędzie");
			Trace.WriteLineIf(ts1.TraceWarning, "Moje ostrzeżenie");
			Trace.WriteLineIf(ts1.TraceInfo, "Moje informacje");

			Trace.WriteLineIf(ts2.Level == TraceLevel.Error, "Twoje wyniki");
			Trace.WriteLineIf(ts2.TraceError, "Twój komunikat o błędzie", "Kategoria");

			CustomTracingSwitch cs = new CustomTracingSwitch("CustomSwitch", "Własny przełącznik debugowania");
			Trace.WriteLineIf(cs.Annoying, "Własny komunikat o błędzie", "Własna kategoria");

			WriteDebugOutput();
			// Trace.Flush();
			Trace.Close();
		}
	}
}
