using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection;
using System.IO;


using CategoryTheory;

namespace DiagramUI
{
    [Serializable()]
    public class MultiLibraryObject : CategoryObjectWrapper, ISerializable
    {
        List<byte[]> bytes = new List<byte[]>();
        List<string> names = new List<string>();
        string name;
        /// <summary>
        /// The properties
        /// </summary>
        protected object properties;

        Assembly ass;




        public MultiLibraryObject()
        {
        }


        public MultiLibraryObject(SerializationInfo info, StreamingContext context)
        {
            bytes = info.GetValue("Bytes", typeof(List<byte[]>)) as List<byte[]>;
            name = info.GetValue("Name", typeof(string)) as string;
            names = info.GetValue("Names", typeof(List<string>)) as List<string>;
            try
            {
                properties = info.GetValue("Properties", typeof(object));
            }
            catch (Exception)
            {
            }
            init();
        }


        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Bytes", bytes, typeof(List<byte[]>));
            info.AddValue("Name", name, typeof(string));
            info.AddValue("Names", names, typeof(List<string>));
            if (theObject != null)
            {
                if (theObject is IPropertiesEditor)
                {
                    IPropertiesEditor pe = theObject as IPropertiesEditor;
                    object prop = pe.Properties;
                    info.AddValue("Properties", prop);
                }
            }

        }

        #endregion


        #region Specific Members

        public void Add(string filename)
        {
            Stream stream = File.OpenRead(filename);
            byte[] b = new byte[stream.Length];
            stream.Read(b, 0, b.Length);
            stream.Close();
            ass = Assembly.Load(b);
            bytes.Add(b);
            names.Add(filename);
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                theObject = Factory[name];
            }
        }

        public string[] Libraries
        {
            get
            {
                if (names.Count == 0)
                {
                    return null;
                }
                string[] s = new string[names.Count];
                for (int i = 0; i < s.Length; i++)
                {
                    s[i] = names[i] + "";
                }
                return s;
            }
        }

        public IObjectFactory Factory
        {
            get
            {
                if (ass == null)
                {
                    return null;
                }
                return LibraryObjectWrpapper.GetFactory(ass);
            }
        }

        protected void init()
        {
            foreach (byte[] b in bytes)
            {
                ass = Assembly.Load(b);
            }
            IObjectFactory factory = Factory;
            theObject = factory[name];
            if (theObject is IPropertiesEditor)
            {
                if (properties != null)
                {
                    IPropertiesEditor pe = theObject as IPropertiesEditor;
                    pe.Properties = properties;
                }
            }
        }



        #endregion
    }
}
