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


using CategoryTheory;

namespace Motion6D
{
    [Serializable()]
    public class RelativeMeasurementsLink : ISerializable, ICategoryArrow, IRemovableObject
    {

        #region Fields

        private object obj;

        ICategoryObject source;

        ICategoryObject target;

        #endregion


        #region Ctor

        public RelativeMeasurementsLink()
        {
        }

        private RelativeMeasurementsLink(SerializationInfo info, StreamingContext context)
        {
        }

        #endregion

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {

        }

        #endregion

        #region ICategoryArrow Members

        ICategoryObject ICategoryArrow.Source
        {
            get
            {
                return source;
            }
            set
            {
                if (!(value is IPosition) & !(value is RelativeMeasurements))
                {
                    throw new Exception("Illegal type");
                }
                source = value;
            }
        }

        ICategoryObject ICategoryArrow.Target
        {
            get
            {
                return target;
            }
            set
            {
                if (value is RelativeMeasurements)
                {
                    if (measurements != null)
                    {
                        throw new Exception("Measurements already exists");
                    }
                    target = value;
                    measurements.Source = source as IPosition;
                    return;
                }
                if (!(value is IPosition))
                {
                    throw new Exception("Illegal type");
                }
                target = value;
                measurements.Target = target as IPosition;
            }
        }

        bool ICategoryArrow.IsMonomorphism
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        bool ICategoryArrow.IsEpimorphism
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        bool ICategoryArrow.IsIsomorphism
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        ICategoryArrow ICategoryArrow.Compose(ICategory category, ICategoryArrow next)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IAssociatedObject Members

        object IAssociatedObject.Object
        {
            get
            {
                return obj;
            }
            set
            {
                obj = value;
            }
        }

        #endregion

        #region IRemovableObject Members

        void IRemovableObject.RemoveObject()
        {
            if (measurements == source)
            {
                measurements.Target = null;
                return;
            }
            if (measurements != null)
            {
                measurements.Source = null;
            }
        }

        #endregion

        #region Specific Members

        RelativeMeasurements measurements
        {
            get
            {
                if (source != null)
                {
                    if (source is RelativeMeasurements)
                    {
                        return source as RelativeMeasurements;
                    }
                }
                if (target != null)
                {
                    if (target is RelativeMeasurements)
                    {
                        return target as RelativeMeasurements;
                    }
                }
                return null;
            }
        }

        #endregion
    }
}
