//
// 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;

namespace CLRUnleashed
{
	public class PointEventArgs : EventArgs
	{
		private Point point;
		public PointEventArgs(int x, int y)
		{
			point = new Point(x, y);
		}
		public Point Point
		{
			get
			{
				return point;
			}
			set
			{
				point = value;
			}
		}
	}

	public struct Point
	{
		// Zdarzenie używane przez klienta w celu powiadomienia
		// o zmianie elementów listy:
		public event EventHandler Changed;
		private int _x;
		private int _y;
		// Wywołanie zdarzenia Changed event; używane przy każdej zmianie punktu:
		private void OnChanged(PointEventArgs e) 
		{
			if (Changed != null)
				Changed(this, e);
		}
		public Point(int x, int y)
		{
			_x = x;
			_y = y;
			Changed = null;
		}
		public int X
		{
			get
			{
				return _x;
			}
			set
			{
				_x = value;
				PointEventArgs e = new PointEventArgs(_x, _y);
				OnChanged(e);
			}
		}
		public int Y
		{
			get
			{
				return _y;
			}
			set
			{
				_y = value;
				PointEventArgs e = new PointEventArgs(_x, _y);
				OnChanged(e);
			}
		}
		public Point Coordinate
		{
			get
			{
				return this;
			}
			set
			{
				_x = value._x;
				_y = value._y;
				PointEventArgs e = new PointEventArgs(_x, _y);
				OnChanged(e);
			}
		}
	}

	/// <summary>
	/// Podsumowanie dla ValuePoint.
	/// </summary>
	class ValuePoint
	{
		private static void Changed(object sender, EventArgs e) 
		{
			PointEventArgs pe = (PointEventArgs)e;
			Console.WriteLine("Punkt zmienił się. ({0}, {1})", pe.Point.X, pe.Point.Y);
		}
		/// <summary>
		/// Główny punkt wejścia dla aplikacji.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			Point p = new Point();
			Console.WriteLine("Punkt {0}", p.GetType().BaseType);
			p.Changed += new EventHandler(Changed);
			p.Coordinate = new Point(1, 2);
		}
	}
}
