//
// 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.ComponentModel;
using System.Globalization;

namespace FrameworkLibraries
{
	[TypeConverter(typeof(ComplexConverter))]
	public class Complex
	{
		private double re;
		private double im;
		public Complex(double re, double im)
		{
			this.re = re;
			this.im = im;
		}
		public double Real
		{
			get
			{
				return re;
			}
			set
			{
				re = value;
			}
		}
		public double Imaginary
		{
			get
			{
				return im;
			}
			set
			{
				im = value;
			}
		}
	}
	public class ComplexConverter : TypeConverter
	{
		// Zastąpienie metody CanConvertFrom z TypeConverter.
		// Interfejs ITypeDescriptorContext zapewnia kontekst konwersji.
		// Ten interfejs jest zwykle używany w czasie projektowania
		// w celu zapewnienia informacji o kontenerze.
		public override bool CanConvertFrom(ITypeDescriptorContext context, 
			Type sourceType) 
		{
			if (sourceType == typeof(string)) 
			{
				return true;
			}
			return base.CanConvertFrom(context, sourceType);
		}
		// Zastąpienie metody ConvertFrom z TypeConverter.
		public override object ConvertFrom(ITypeDescriptorContext context, 
			CultureInfo culture, object value) 
		{
			if (value is string) 
			{
				string[] v = ((string)value).Split(new char[] {','});
				return new Complex(double.Parse(v[0]), double.Parse(v[1]));
			}
			return base.ConvertFrom(context, culture, value);
		}
		// Zastąpienie metody ConvertTo z TypeConverter.
		public override object ConvertTo(ITypeDescriptorContext context, 
			CultureInfo culture, object value, Type destinationType) 
		{  
			if (destinationType == typeof(string)) 
			{
				return ((Complex)value).Real + "," + ((Complex)value).Imaginary;
			}
			return base.ConvertTo(context, culture, value, destinationType);
		}
	}
	public class VersionMain 
	{
		static void Main(string [] args)
		{
			Complex c = (Complex)TypeDescriptor.GetConverter(typeof(Complex)).ConvertFromString("1.0,2.0");
			string ds = (string)TypeDescriptor.GetConverter(c).ConvertToString(c);
			Console.WriteLine("{0},{1} <-> {2}", c.Real, c.Imaginary, ds);
		}
	}
}