using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml;
using CategoryTheory;
using MathGraph;
using DiagramUI.Labels;
using DiagramUI.Interfaces;
namespace DiagramUI
{
/// <summary>
/// Base conttainer of objects
/// </summary>
public abstract class ObjectContainerBase : CategoryObject, ISerializable, IObjectContainer, IPostSetArrow
{
#region Fields
/// <summary>
/// Byte information
/// </summary>
protected byte[] bytes;
/// <summary>
/// Interface
/// </summary>
protected Hashtable inter = new Hashtable();
/// <summary>
/// Type
/// </summary>
private string type;
/// <summary>
/// Serialization binders
/// </summary>
static private SerializationBinder[] binders;
/// <summary>
/// Child desktop
/// </summary>
protected PureDesktopPeer desktop = new PureDesktopPeer();
/// <summary>
/// The "is loaded" sign
/// </summary>
protected bool isLoaded = false;
/// <summary>
/// The "is post loaded" sign
/// </summary>
protected bool isPostLoaded = false;
#endregion
#region Constructors
/// <summary>
/// Main constructor
/// </summary>
/// <param name="desktop">The parent desktop</param>
protected ObjectContainerBase(PureDesktopPeer desktop)
{
this.desktop = desktop;
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
public ObjectContainerBase(SerializationInfo info, StreamingContext context)
{
bytes = info.GetValue("Bytes", typeof(byte[])) as byte[];
inter = info.GetValue("Interface", typeof(Hashtable)) as Hashtable;
type = info.GetValue("Type", typeof(string)) as string;
}
#endregion
#region ISerializable Members
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
MemoryStream stream = new MemoryStream();
SaveDesktop(stream);
bytes = stream.GetBuffer();
info.AddValue("Bytes", bytes);
info.AddValue("Interface", inter);
info.AddValue("Type", type);
}
#endregion
#region Abstract Members
/// <summary>
/// Saves desktop
/// </summary>
/// <param name="stream">Stream to save</param>
protected abstract void SaveDesktop(Stream stream);
/// <summary>
/// Loads desktop
/// </summary>
/// <param name="bytes">Soure bytes</param>
/// <returns>Thrue in success and false otherwise</returns>
protected abstract bool LoadDesktop(byte[] bytes);
#endregion
#region IPostSetArrow Members
/// <summary>
/// The post set arrow operation
/// </summary>
public void PostSetArrow()
{
}
#endregion
#region IObjectCollection Members
string[] IObjectCollection.Names
{
get { return desktop.GetNames(); }
}
object IObjectCollection.this[string name]
{
get
{
return desktop.GetObject(name);
}
}
#endregion
#region IComponentCollection Members
ICollection<object> IComponentCollection.AllComponents
{
get { return desktop.AllComponents; }
}
#endregion
#region Specific Members
/// <summary>
/// Sets parents of objects
/// </summary>
/// <param name="desktop">The desktop</param>
public void SetParents(IDesktop desktop)
{
ICollection<IObjectLabel> objs = desktop.Objects;
INamedComponent comp = null;
foreach (IObjectLabel ol in objs)
{
if (ol.Object == this)
{
comp = ol;
break;
}
}
ICollection<object> objects = this.desktop.Components;
foreach (INamedComponent nc in objects)
{
if (nc is IObjectLabel)
{
IObjectLabel l = nc as IObjectLabel;
if (l.Object is IObjectContainer)
{
IObjectContainer oc = l.Object as IObjectContainer;
PureDesktopPeer.SetParents(oc.Desktop);
}
}
nc.Parent = comp;
}
}
/// <summary>
/// Loads itself
/// </summary>
/// <returns>True in success</returns>
public bool Load()
{
if (isLoaded)
{
return false;
}
isLoaded = true;
desktop.HasParent = true;
bool b = LoadDesktop(bytes);
foreach (INamedComponent nc in desktop.Components)
{
if (nc.Parent == null)
{
nc.Parent = Object as INamedComponent;
}
nc.Desktop = desktop;
}
desktop.setParent(this);
return b;
}
/// <summary>
/// The post load operation
/// </summary>
public virtual bool PostLoad()
{
if (!isLoaded)
{
return false;
}
if (isPostLoaded)
{
return true;
}
isPostLoaded = true;
bytes = null;
GC.Collect();
return desktop.PostLoad();
}
/// <summary>
/// Gets relative name of component
/// </summary>
/// <param name="comp">The component</param>
/// <returns>The relative name</returns>
public string GetName(INamedComponent comp)
{
return comp.GetName(desktop);
}
/// <summary>
/// All child objects
/// </summary>
public ICollection<object> AllObjects
{
get
{
return PureDesktopPeer.GetAllObjects(desktop);
}
}
/// <summary>
/// Adds a component
/// </summary>
/// <param name="c">The component to add</param>
/// <param name="x">The x - coordinate</param>
/// <param name="y">The y - coordinate</param>
/// <param name="comment">The comment</param>
public void Add(INamedComponent c, int x, int y, string comment)
{
string name = c.GetName(desktop);
inter[name] = new object[]{x, y, comment};
}
/// <summary>
/// Serialization binders
/// </summary>
public static SerializationBinder[] Binders
{
set
{
binders = value;
}
}
/// <summary>
/// The type
/// </summary>
public string Type
{
get
{
return type;
}
set
{
type = value;
}
}
/// <summary>
/// Access to child by name
/// </summary>
/// <param name="name">The name</param>
/// <returns>The child</returns>
public INamedComponent this[string name]
{
get
{
return desktop[name];
}
}
/// <summary>
/// The interface
/// </summary>
public Hashtable Interface
{
get
{
return inter;
}
}
/// <summary>
/// Loads desktop
/// </summary>
/// <returns>Desktop</returns>
public IDesktop LoadDesktop()
{
desktop.Load(bytes);
return desktop;
}
/// <summary>
/// The desktop
/// </summary>
public IDesktop Desktop
{
get
{
return desktop;
}
}
/// <summary>
/// Post Load desktop
/// </summary>
/// <returns>True in success</returns>
protected bool DesktopPostLoad()
{
return desktop.PostLoad();
}
#endregion
}
}