context: using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Text;
  using Server.ContextMenus;
  using Server.Gumps;
  using Server.Multis;
  using Server.Network;
  
  namespace Server.Items
  {
      public class BookPageInfo
      {
          private string[] m_Lines;
  
          public string[] Lines
          {
              get
              {
                  return this.m_Lines;
              }
              set
              {
                  this.m_Lines = value;
              }
          }
  
          public BookPageInfo()
          {
              this.m_Lines = new string[0];
          }
  
          public BookPageInfo(params string[] lines)
          {
              this.m_Lines = lines;
          }
  
          public BookPageInfo(GenericReader reader)
          {
              int length = reader.ReadInt();
  
              this.m_Lines = new string[length];
  
              for (int i = 0; i < this.m_Lines.Length; ++i)
                  this.m_Lines[i] = Utility.Intern(reader.ReadString());
          }
  
          public void Serialize(GenericWriter writer)
          {
              writer.Write(this.m_Lines.Length);
  
              for (int i = 0; i < this.m_Lines.Length; ++i)
                  writer.Write(this.m_Lines[i]);
          }
      }
  
      public class BaseBook : Item, ISecurable
      {
          private string m_Title;
          private string m_Author;
          private BookPageInfo[] m_Pages;
          private bool m_Writable;
          private SecureLevel m_SecureLevel;
  		
          [CommandProperty(AccessLevel.GameMaster)]
          public string Title
          {
              get
              {
                  return this.m_Title;
              }
              set
              {
                  this.m_Title = value;
                  this.InvalidateProperties();
              }
          }
  		
          [CommandProperty(AccessLevel.GameMaster)]
          public string Author
          {
              get
              {
                  return this.m_Author;
              }
              set
              {
                  this.m_Author = value;
                  this.InvalidateProperties();
              }
          }
  		
          [CommandProperty(AccessLevel.GameMaster)]
          public bool Writable
          {
              get
              {
                  return this.m_Writable;
              }
              set
              {
                  this.m_Writable = value;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int PagesCount
          {
              get
              {
                  return this.m_Pages.Length;
              }
          }
  
          public BookPageInfo[] Pages
          {
              get
              {
                  return this.m_Pages;
              }
          }
  
          public virtual double BookWeight { get { return 1.0; } }
  
          [Constructable]
          public BaseBook(int itemID)
              : this(itemID, 20, true)
          {
          }
  
          [Constructable]
          public BaseBook(int itemID, int pageCount, bool writable)
              : this(itemID, null, null, pageCount, writable)
          {
          }
  
          [Constructable]
          public BaseBook(int itemID, string title, string author, int pageCount, bool writable)
              : base(itemID)
          {
              this.m_Title = title;
              this.m_Author = author;
              this.m_Writable = writable;
  
              BookContent content = this.DefaultContent;
  
              if (content == null)
              {
                  this.m_Pages = new BookPageInfo[pageCount];
  
                  for (int i = 0; i < this.m_Pages.Length; ++i)
                      this.m_Pages[i] = new BookPageInfo();
              }
              else
              {
                  this.m_Pages = content.Copy();
              }
  
              Weight = BookWeight;
          }
  
          // Intended for defined books only
          public BaseBook(int itemID, bool writable)
              : base(itemID)
          {
              this.m_Writable = writable;
  
              BookContent content = this.DefaultContent;
  
              if (content == null)
              {
                  this.m_Pages = new BookPageInfo[0];
              }
              else
              {
                  this.m_Title = content.Title;
                  this.m_Author = content.Author;
                  this.m_Pages = content.Copy();
              }
          }
  
          public virtual BookContent DefaultContent
          {
              get
              {
                  return null;
              }
          }
  	
          public BaseBook(Serial serial)
              : base(serial)
          {
          }
  
          [Flags]
          private enum SaveFlags
          {
              None = 0x00,
              Title = 0x01,
              Author = 0x02,
              Writable = 0x04,
              Content = 0x08
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
              SetSecureLevelEntry.AddTo(from, this, list);
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              BookContent content = this.DefaultContent;
  
              SaveFlags flags = SaveFlags.None;
  
              if (this.m_Title != (content == null ? null : content.Title))
                  flags |= SaveFlags.Title;
  
              if (this.m_Author != (content == null ? null : content.Author))
                  flags |= SaveFlags.Author;
  
              if (this.m_Writable)
                  flags |= SaveFlags.Writable;
  
              if (content == null || !content.IsMatch(this.m_Pages))
                  flags |= SaveFlags.Content;
  
              writer.Write((int)4); // version
  
              writer.Write((int)this.m_SecureLevel);
  
              writer.Write((byte)flags);
  
              if ((flags & SaveFlags.Title) != 0)
                  writer.Write(this.m_Title);
  
              if ((flags & SaveFlags.Author) != 0)
                  writer.Write(this.m_Author);
  
              if ((flags & SaveFlags.Content) != 0)
              {
                  writer.WriteEncodedInt(this.m_Pages.Length);
  
                  for (int i = 0; i < this.m_Pages.Length; ++i)
                      this.m_Pages[i].Serialize(writer);
              }
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
  
              int version = reader.ReadInt();
  
              switch ( version )
              {
                  case 4:
                      {
                          this.m_SecureLevel = (SecureLevel)reader.ReadInt();
                          goto case 3;
                      }
                  case 3:
                  case 2:
                      {
                          BookContent content = this.DefaultContent;
  
                          SaveFlags flags = (SaveFlags)reader.ReadByte();
  
                          if ((flags & SaveFlags.Title) != 0)
                              this.m_Title = Utility.Intern(reader.ReadString());
                          else if (content != null)
                              this.m_Title = content.Title;
  
                          if ((flags & SaveFlags.Author) != 0)
                              this.m_Author = reader.ReadString();
                          else if (content != null)
                              this.m_Author = content.Author;
  
                          this.m_Writable = (flags & SaveFlags.Writable) != 0;
  
                          if ((flags & SaveFlags.Content) != 0)
                          {
                              this.m_Pages = new BookPageInfo[reader.ReadEncodedInt()];
  
  
gt:                             for (int i = 0; i < this.m_Pages.Length; ++i)