//
// 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.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.IO;
 
namespace VehicleSerialization
{
	public class VehicleBuilder
	{
		public Vehicle Vehicle(string licenseNumber) 
		{
			if (licenseNumber == "0") 
			{
				Vehicle v = new Car();
				v.licenseNumber = licenseNumber;
				v.make = DateTime.Now;
				return v;
			}
			else if (licenseNumber == "1") 
			{
				Vehicle v = new Bike();
				v.licenseNumber = licenseNumber;
				v.make = DateTime.Now;
				return v;
			}
			else 
			{
				return null;
			}
		}
	}

	// Brak poniższego wiersza powoduje zgłoszenie wyjątku
	// Unhandled Exception: System.Exception: There was an error generating the XML document. --->
	// System.Exception: The type VehicleSerialization.Car was not expected.
	// Należy użyć atrybutu XmlInclude lub SoapInclude do zdefiniowania typów, które nie są statyczne.
	[XmlInclude(typeof(Car)), XmlInclude(typeof(Bike))]
	public abstract class Vehicle 
	{
		public string licenseNumber;
		public DateTime make;
	}
 
	public class Car : Vehicle 
	{
	}
 
	public class Bike : Vehicle 
	{
	}

	public class VehicleSerializationTest
	{
		public static int Main(string[] args)
		{
			VehicleBuilder vb = new VehicleBuilder();
			Vehicle [] va = new Vehicle[2];
			va[0] = vb.Vehicle("0");
			va[1] = vb.Vehicle("1");
			// Utworzenie egzemplarza klasy Soap Serializer;
			// wybór typu obiektu do szeregowania.
			XmlSerializer serializer = 
				new XmlSerializer(typeof(Vehicle[]));
			StreamWriter streamWriter = new StreamWriter("out.xml");
			serializer.Serialize(streamWriter, va);
			streamWriter.Close();

			StreamReader streamReader = new StreamReader("out.xml");
			va = (Vehicle [])serializer.Deserialize(streamReader);
			streamReader.Close();

			Console.WriteLine("Pierwszy element to: {0}", va[0]);
			Console.WriteLine("Drugi element to: {0}", va[1]);

			return 0;
		}
	}
}