// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

namespace Microsoft.Data.Entity.Design.Model.Designer
{
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Xml.Linq;
    using Microsoft.Data.Entity.Design.Model.Entity;

    internal class AssociationConnector : Connector
    {
        internal static readonly string ElementName = "AssociationConnector";
        internal static readonly string AttributeAssociation = "Association";

        private SingleItemBinding<Association> _associationBinding;

        internal AssociationConnector(EFElement parent, XElement element)
            : base(parent, element)
        {
        }

        /// <summary>
        ///     A bindable reference to the Association for this connector
        /// </summary>
        internal SingleItemBinding<Association> Association
        {
            get
            {
                if (_associationBinding == null)
                {
                    _associationBinding = new SingleItemBinding<Association>(
                        this,
                        AttributeAssociation,
                        EFNormalizableItemDefaults.DefaultNameNormalizerForDesigner);
                }
                return _associationBinding;
            }
        }

        #region overrides

        // we unfortunately get a warning from the compiler when we use the "base" keyword in "iterator" types generated by using the
        // "yield return" keyword.  By adding this method, I was able to get around this.  Unfortunately, I wasn't able to figure out
        // a way to implement this once and have derived classes share the implementation (since the "base" keyword is resolved at 
        // compile-time and not at runtime.
        private IEnumerable<EFObject> BaseChildren
        {
            get { return base.Children; }
        }

        internal override IEnumerable<EFObject> Children
        {
            get
            {
                foreach (var efobj in BaseChildren)
                {
                    yield return efobj;
                }

                yield return _associationBinding;
            }
        }

#if DEBUG
        internal override ICollection<string> MyAttributeNames()
        {
            var s = base.MyAttributeNames();
            s.Add(AttributeAssociation);
            return s;
        }
#endif

        protected override void PreParse()
        {
            Debug.Assert(State != EFElementState.Parsed, "this object should not already be in the parsed state");

            ClearEFObject(_associationBinding);
            _associationBinding = null;

            base.PreParse();
            ;
        }

        protected override void DoResolve(EFArtifactSet artifactSet)
        {
            Association.Rebind();
            if (Association.Status == BindingStatus.Known)
            {
                State = EFElementState.Resolved;
            }
        }

        internal override EFObject ModelItem
        {
            get
            {
                if (Association.Status == BindingStatus.Known)
                {
                    return Association.SafeTarget;
                }
                return null;
            }
        }

        #endregion
    }
}
