using System;

namespace InterfaceDemo
{
	interface IStorable
	{
		void Read();
		void Write(object obj);
		int Status { get; set; }
	}

	interface ICompressible
	{
		void Compress();
		void Decompress();
	}

	public class Note : IStorable
	{
		private int status = 0; // IStorable
		private string myString;

		public Note(string theString)
		{
			myString = theString;
		}

		public override string ToString()
		{
			return myString;
		}

		#region IStorable

		public void Read()
		{
			Console.WriteLine(
			"Implementacja metody Read interfejsu IStorable");
		}

		public void Write(object o)
		{
			Console.WriteLine(
			"Implementacja metody Write interfejsu IStorable");
		}

		public int Status
		{
			get { return status; }
			set { status = value; }
		}

		#endregion // IStorable

	}

	public class Document : Note, ICompressible
	{
		private int documentID;
		public int ID
		{
			get { return this.documentID; }
		}

		public Document(string docString, int documentID)
			:
		base(docString)
		{
			this.documentID = documentID;
		}

		#region ICompressible

		public void Compress()
		{
			Console.WriteLine("Pakowanie...");
		}
		public void Decompress()
		{
			Console.WriteLine("Rozpakowywanie...");
		}
		#endregion // ICompressible

	} // Koniec Document 

	class Tester
	{
		public void Run()
		{
			string testString = "Łańcuch znaków ";
			Note[] myNoteArray = new Note[3];

			for (int i = 0; i < 3; i++)
			{
				string docText = testString + i.ToString();
				if (i % 2 == 0)
				{
					Document myDocument = new Document(docText, (i + 5) * 10);
					myNoteArray[i] = myDocument;
				}
				else
				{
					Note myNote = new Note(docText);
					myNoteArray[i] = myNote;
				}
			}

			foreach (Note theNote in myNoteArray)
			{
				Console.WriteLine("\nTestowanie {0} przy użyciu IS", theNote);

				theNote.Read(); // Wszystkie obiekty klasy Note udostępniają tę metodę
				if (theNote is ICompressible)
				{
					ICompressible myCompressible = theNote as ICompressible;
					myCompressible.Compress();
				}
				else
				{
					Console.WriteLine("Tego zapisywalnego obiektu nie można pakować.");
				}

				if (theNote is Document)
				{
					Document myDoc = theNote as Document;

					// Eleganckie rzutowanie
					myDoc = theNote as Document;
					Console.WriteLine("ID dokumentu to {0}", myDoc.ID);

					// Staromodne rzutowanie!
					Console.WriteLine("ID dokumentu to {0}",
					((Document)theNote).ID);
				}
			}

			foreach (Note theNote in myNoteArray)
			{
				Console.WriteLine("\nTestowanie {0} przy użyciu AS", theNote);
				ICompressible myCompressible = theNote as ICompressible;
				if (myCompressible != null)
				{
					myCompressible.Compress();
				}
				else
				{
					Console.WriteLine("Tego zapisywalnego obiektu nie można pakować.");
				} // Koniec else

				Document theDoc = theNote as Document;
				if (theDoc != null)
				{
					Console.WriteLine("ID dokumentu to {0}",
					((Document)theNote).ID);
				}
				else
				{
					Console.WriteLine("To nie jest dokument.");
				}
			}
		}

		static void Main()
		{
			Tester t = new Tester();
			t.Run();
		}
	} // Koniec Tester
} // Koniec InterfaceDemo
