/*
  * The contents of this file are subject to the Mozilla Public
  * License Version 1.1 (the "License"); you may not use this
  * file except in compliance with the License. You may obtain
  * a copy of the License at http://www.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an
  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  * or implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  *
  * The Original Code is .NET RASP toolkit.
  *
  * The Initial Developer of the Original Code is Accenture and Avanade.
  * Portions created by Accenture and Avanade are Copyright (C) 2009
  * Danish National IT and Telecom Agency (http://www.itst.dk). 
  * All Rights Reserved.
  *
  * Contributor(s):
  *   Gert Sylvest, Avanade
  *   Jesper Jensen, Avanade
  *   Ramzi Fadel, Avanade
  *   Patrik Johansson, Accenture
  *   Dennis Søgaard, Accenture
  *   Christian Pedersen, Accenture
  *   Martin Bentzen, Accenture
  *   Mikkel Hippe Brun, ITST
  *   Finn Hartmann Jordal, ITST
  *   Christian Lanng, ITST
  *
  */
using System;
using System.Collections.Generic;

namespace dk.gov.oiosi.xml.xpath.discriminator {
    /// <summary>
    /// A collection of XPath discriminator configruations
    /// </summary>
    public class XpathDiscriminatorConfigCollection : IEnumerable<XPathDiscriminatorConfig>, IEquatable<XpathDiscriminatorConfigCollection> {
        private List<XPathDiscriminatorConfig> _xpathDiscriminatorConfigs;
        
        /// <summary>
        /// Defatult constructor that initializes the collection.
        /// </summary>
        public XpathDiscriminatorConfigCollection() {
            _xpathDiscriminatorConfigs = new List<XPathDiscriminatorConfig>();
        }

        /// <summary>
        /// Gets and sets the configurations of the collection
        /// </summary>
        /// <remarks>
        /// This is used by the XML serialization, used the add and remove
        /// functions instead.
        /// </remarks>
        public XPathDiscriminatorConfig[] XPathDiscriminatorConfigs {
            get { return _xpathDiscriminatorConfigs.ToArray(); }
            set { _xpathDiscriminatorConfigs = new List<XPathDiscriminatorConfig>(value); }
        }

        /// <summary>
        /// Adds an XPath discriminator configuration to the collection.
        /// </summary>
        /// <param name="xpathDiscriminatorConfig"></param>
        public void Add(XPathDiscriminatorConfig xpathDiscriminatorConfig) {
            _xpathDiscriminatorConfigs.Add(xpathDiscriminatorConfig);
        }

        /// <summary>
        /// Removes an XPath discriminator configuration from the 
        /// collection.
        /// </summary>
        /// <param name="xpathDiscriminatorConfig"></param>
        /// <returns></returns>
        public bool Remove(XPathDiscriminatorConfig xpathDiscriminatorConfig) {
            return _xpathDiscriminatorConfigs.Remove(xpathDiscriminatorConfig);
        }

        #region IEnumerable<XPathDiscriminatorConfig> Members

        /// <summary>
        /// Gets an IEnumerator to traverse the collection
        /// </summary>
        /// <returns></returns>
        public IEnumerator<XPathDiscriminatorConfig> GetEnumerator() {
            return _xpathDiscriminatorConfigs.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Gets an IEnumerator to traverse the collection
        /// </summary>
        /// <returns></returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return _xpathDiscriminatorConfigs.GetEnumerator();
        }

        #endregion

        #region IEquatable<XpathDiscriminatorConfigCollection> Members

        /// <summary>
        /// Returns whether the collection is equal with another collection.
        /// This is done by value comparering and not reference.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(XpathDiscriminatorConfigCollection other) {
            int thisCount = _xpathDiscriminatorConfigs.Count;
            int otherCount = other._xpathDiscriminatorConfigs.Count;
            if (thisCount != otherCount) return false;
            Comparison<XPathDiscriminatorConfig> comparer =
                delegate(XPathDiscriminatorConfig x, XPathDiscriminatorConfig y) {
                    if (x.XPathExpression != y.XPathExpression)
                        return x.XPathExpression.CompareTo(y.XPathExpression);
                    return x.XPathExpectedResult.CompareTo(y.XPathExpectedResult);
                };
            _xpathDiscriminatorConfigs.Sort(comparer);
            other._xpathDiscriminatorConfigs.Sort(comparer);
            for(int i = 0; i<thisCount; i++) {
                int compare = comparer(_xpathDiscriminatorConfigs[i], other._xpathDiscriminatorConfigs[i]);
                if (compare != 0) return false;
            }
            return true;
        }

        #endregion
    }
}
