//
// 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.Collections;
using System.Threading;

namespace DelegatesAndEvents
{
	public enum ChangeType {Add, Subtract}

	public class ChangedEventArgs : EventArgs 
	{
		private ChangeType _type;
		private int _value;
		public ChangedEventArgs(ChangeType _type, int _value)
		{
			this._type = _type;
			this._value = _value;
		}
		public ChangeType Type
		{
			get
			{
				return _type;
			}
		}
		public int Value
		{
			get
			{
				return _value;
			}
		}
	}

	public class ChangedClass 
	{
		// Zdarzenie, które może być użyte do powiadomienia klientów o zmianie
		// elementów listy:
		public event EventHandler Changed;
		private int count;
		public ChangedClass()
		{
			count = 0;
		}
		// Wywołanie zdarzenia Changed przy każdej zmianie listy:
		protected void OnChanged(EventArgs e) 
		{
			if (Changed != null)
				Changed(this, e);
		}
		public void Add()
		{
			Interlocked.Increment(ref count);
			OnChanged(new ChangedEventArgs(ChangeType.Add, count));
		}
		public void Subtract()
		{
			Interlocked.Decrement(ref count);
			OnChanged(new ChangedEventArgs(ChangeType.Subtract, count));
		}
	}

	class Test 
	{
		private static void Changed(object sender, EventArgs e) 
		{
			Console.WriteLine("Wywołano Changed {0} {1}",
				              ((ChangedEventArgs)e).Value,
				              ((ChangedEventArgs)e).Type);
		}
		private static void Modified(object sender, EventArgs e) 
		{
			Console.WriteLine("Wywołano Modified {0} {1}",
				              ((ChangedEventArgs)e).Value,
				              ((ChangedEventArgs)e).Type);
		}
		// Test klasy EventHandler:
		public static void Main() 
		{
			// Utworzenie nowej listy:
			ChangedClass changed = new ChangedClass();
			changed.Changed += new EventHandler(Changed);
			changed.Changed += new EventHandler(Modified);
			changed.Add();
			changed.Add();
			changed.Changed -= new EventHandler(Modified);
			changed.Add();
			changed.Add();
			changed.Subtract();
			changed.Subtract();
			changed.Subtract();
		}
	}
}
