using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.IO.Compression;
using System.Runtime.InteropServices;

namespace TheNovel
{
	[Serializable]
	class Chapter
	{
		[MarshalAs ( UnmanagedType.LPWStr )]
		string title;
		[MarshalAs ( UnmanagedType.LPWStr )]
		string text;

		public Chapter ( string _title )
		{
			title = _title; text = "";
		}

		public string Title { get { return title; } }
		public string Text { get { return text; } set { text = value; } }
	}

	[Serializable]
	class Novel : IEnumerable<Chapter>
	{
		[NonSerialized]
		static BinaryFormatter bf = new BinaryFormatter ();
		[MarshalAs ( UnmanagedType.LPWStr )]
		string title;
		[MarshalAs ( UnmanagedType.LPWStr )]
		string writer;
		DateTime created;
		List<Chapter> chapters;

		public string Title { get { return title; } }
		public string Writer { get { return writer; } }
		public DateTime Date { get { return created; } }

		public static bool Load ( Stream stream, out Novel novel )
		{
			try
			{
				using ( GZipStream strm = new GZipStream ( stream, CompressionMode.Decompress ) )
				{
					novel = bf.Deserialize ( stream ) as Novel;
					strm.Close ();
				}
			}
			catch
			{
				novel = null;
				return false;
			}

			return false;
		}

		public static bool Save ( Stream stream, Novel novel )
		{
			try
			{
				stream.SetLength ( 0 );
				using ( GZipStream strm = new GZipStream ( stream, CompressionMode.Compress ) )
				{
					bf.Serialize ( stream, novel );
					strm.Close ();
				}
			}
			catch
			{
				return false;
			}

			return true;
		}

		public Novel ( string _title, string _writer )
		{
			title = _title; writer = _writer;
			created = DateTime.Now;
			chapters = new List<Chapter> ();
		}

		public Chapter this [ int index ]
		{
			get { return chapters [ index ]; }
			set { chapters [ index ] = value; }
		}

		public int GetIndex ( Chapter chapter )
		{
			for ( int i = 0; i < chapters.Count; i++ )
				if ( chapters [ i ] == chapter )
					return i;
			return -1;
		}

		public int Count { get { return chapters.Count; } }

		public void AddChapter ( string title )
		{
			chapters.Add ( new Chapter ( title ) );
		}

		public void AddChapter ( Chapter c )
		{
			chapters.Add ( c );
		}

		public void RemoveChapter ( int i )
		{
			chapters.RemoveAt ( i );
		}

		public void RemoveChapter ( Chapter c )
		{
			chapters.Remove ( c );
		}

		public IEnumerator<Chapter> GetEnumerator ()
		{
			return chapters.GetEnumerator ();
		}

		IEnumerator IEnumerable.GetEnumerator ()
		{
			return chapters.GetEnumerator ();
		}
	}
}